Fossil SCM

Update the built-in SQLite to the latest trunk, just so we can stay on the bleeding edge.

drh 2024-09-02 22:20 trunk
Commit ff931032bd23cd4c116b96063d7d707283c3f7514a44eb5143c43652717f20fa
3 files changed +414 -109 +84 -50 +18 -7
+414 -109
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -262,10 +262,11 @@
262262
/* Deselect most features from the console I/O package for Fiddle. */
263263
# define SQLITE_CIO_NO_REDIRECT
264264
# define SQLITE_CIO_NO_CLASSIFY
265265
# define SQLITE_CIO_NO_TRANSLATE
266266
# define SQLITE_CIO_NO_SETMODE
267
+# define SQLITE_CIO_NO_FLUSH
267268
#endif
268269
/************************* Begin ../ext/consio/console_io.h ******************/
269270
/*
270271
** 2023 November 1
271272
**
@@ -442,16 +443,23 @@
442443
#ifdef CONSIO_EPUTB
443444
SQLITE_INTERNAL_LINKAGE int
444445
ePutbUtf8(const char *cBuf, int nAccept);
445446
#endif
446447
448
+/*
449
+** Flush the given output stream. Return non-zero for success, else 0.
450
+*/
451
+#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
452
+SQLITE_INTERNAL_LINKAGE int
453
+fFlushBuffer(FILE *pfOut);
454
+#endif
455
+
447456
/*
448457
** Collect input like fgets(...) with special provisions for input
449
-** from the console on platforms that require same. Defers to the
450
-** C library fgets() when input is not from the console. Newline
451
-** translation may be done as set by set{Binary,Text}Mode(). As a
452
-** convenience, pfIn==NULL is treated as stdin.
458
+** from the console on such platforms as require same. Newline
459
+** translation may be done as set by set{Binary,Text}Mode().
460
+** As a convenience, pfIn==NULL is treated as stdin.
453461
*/
454462
SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
455463
/* Like fGetsUtf8 except stream is always the designated input. */
456464
/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */
457465
@@ -1144,10 +1152,90 @@
11441152
# if CIO_WIN_WC_XLATE
11451153
}
11461154
# endif
11471155
}
11481156
1157
+/*
1158
+** Flush the given output stream. Return non-zero for success, else 0.
1159
+*/
1160
+#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
1161
+SQLITE_INTERNAL_LINKAGE int
1162
+fFlushBuffer(FILE *pfOut){
1163
+# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
1164
+ return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
1165
+# else
1166
+ return fflush(pfOut);
1167
+# endif
1168
+}
1169
+#endif
1170
+
1171
+#if CIO_WIN_WC_XLATE \
1172
+ && !defined(SHELL_OMIT_FIO_DUPE) \
1173
+ && defined(SQLITE_USE_ONLY_WIN32)
1174
+static struct FileAltIds {
1175
+ int fd;
1176
+ HANDLE fh;
1177
+} altIdsOfFile(FILE *pf){
1178
+ struct FileAltIds rv = { _fileno(pf) };
1179
+ union { intptr_t osfh; HANDLE fh; } fid = {
1180
+ (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
1181
+ };
1182
+ rv.fh = fid.fh;
1183
+ return rv;
1184
+}
1185
+
1186
+SQLITE_INTERNAL_LINKAGE size_t
1187
+cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
1188
+ size_t rv = 0;
1189
+ struct FileAltIds fai = altIdsOfFile(pf);
1190
+ int fmode = _setmode(fai.fd, _O_BINARY);
1191
+ _setmode(fai.fd, fmode);
1192
+ while( rv < ocnt ){
1193
+ size_t nbo = osz;
1194
+ while( nbo > 0 ){
1195
+ DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
1196
+ BOOL wrc = TRUE;
1197
+ BOOL genCR = (fmode & _O_TEXT)!=0;
1198
+ if( genCR ){
1199
+ const char *pnl = (const char*)memchr(buf, '\n', nbo);
1200
+ if( pnl ) nbo = pnl - (const char*)buf;
1201
+ else genCR = 0;
1202
+ }
1203
+ if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
1204
+ if( genCR && wrc ){
1205
+ wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
1206
+ ++dwno; /* Skip over the LF */
1207
+ }
1208
+ if( !wrc ) return rv;
1209
+ buf = (const char*)buf + dwno;
1210
+ nbo += dwno;
1211
+ }
1212
+ ++rv;
1213
+ }
1214
+ return rv;
1215
+}
1216
+
1217
+SQLITE_INTERNAL_LINKAGE char *
1218
+cfGets(char *cBuf, int n, FILE *pf){
1219
+ int nci = 0;
1220
+ struct FileAltIds fai = altIdsOfFile(pf);
1221
+ int fmode = _setmode(fai.fd, _O_BINARY);
1222
+ BOOL eatCR = (fmode & _O_TEXT)!=0;
1223
+ _setmode(fai.fd, fmode);
1224
+ while( nci < n-1 ){
1225
+ DWORD nr;
1226
+ if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
1227
+ if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
1228
+ }
1229
+ if( nci < n ) cBuf[nci] = 0;
1230
+ return (nci>0)? cBuf : 0;
1231
+}
1232
+# else
1233
+# define cfWrite(b,os,no,f) fwrite(b,os,no,f)
1234
+# define cfGets(b,n,f) fgets(b,n,f)
1235
+# endif
1236
+
11491237
# ifdef CONSIO_EPUTB
11501238
SQLITE_INTERNAL_LINKAGE int
11511239
ePutbUtf8(const char *cBuf, int nAccept){
11521240
FILE *pfErr;
11531241
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1155,11 +1243,11 @@
11551243
# if CIO_WIN_WC_XLATE
11561244
if( pstReachesConsole(ppst) ){
11571245
return conZstrEmit(ppst, cBuf, nAccept);
11581246
}else {
11591247
# endif
1160
- return (int)fwrite(cBuf, 1, nAccept, pfErr);
1248
+ return (int)cfWrite(cBuf, 1, nAccept, pfErr);
11611249
# if CIO_WIN_WC_XLATE
11621250
}
11631251
# endif
11641252
}
11651253
# endif /* defined(CONSIO_EPUTB) */
@@ -1221,11 +1309,11 @@
12211309
return cBuf;
12221310
}else return 0;
12231311
# endif
12241312
}else{
12251313
# endif
1226
- return fgets(cBuf, ncMax, pfIn);
1314
+ return cfGets(cBuf, ncMax, pfIn);
12271315
# if CIO_WIN_WC_XLATE
12281316
}
12291317
# endif
12301318
}
12311319
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
@@ -1265,15 +1353,16 @@
12651353
# define oputz(z) oPutsUtf8(z)
12661354
# define oputf oPrintfUtf8
12671355
# define eputz(z) ePutsUtf8(z)
12681356
# define eputf ePrintfUtf8
12691357
# define oputb(buf,na) oPutbUtf8(buf,na)
1358
+# define fflush(s) fFlushBuffer(s);
12701359
12711360
#else
12721361
/* For Fiddle, all console handling and emit redirection is omitted. */
12731362
/* These next 3 macros are for emitting formatted output. When complaints
1274
- * from the WASM build are issued for non-formatted output, (when a mere
1363
+ * from the WASM build are issued for non-formatted output, when a mere
12751364
* string literal is to be emitted, the ?putz(z) forms should be used.
12761365
* (This permits compile-time checking of format string / argument mismatch.)
12771366
*/
12781367
# define oputf(fmt, ...) printf(fmt,__VA_ARGS__)
12791368
# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__)
@@ -1281,10 +1370,11 @@
12811370
/* These next 3 macros are for emitting simple string literals. */
12821371
# define oputz(z) fputs(z,stdout)
12831372
# define eputz(z) fputs(z,stderr)
12841373
# define sputz(fp,z) fputs(z,fp)
12851374
# define oputb(buf,na) fwrite(buf,1,na,stdout)
1375
+# undef fflush
12861376
#endif
12871377
12881378
/* True if the timer is enabled */
12891379
static int enableTimer = 0;
12901380
@@ -4689,11 +4779,11 @@
46894779
** May you share freely, never taking more than you give.
46904780
**
46914781
******************************************************************************
46924782
**
46934783
** This file contains code to implement the percentile(Y,P) SQL function
4694
-** as described below:
4784
+** and similar as described below:
46954785
**
46964786
** (1) The percentile(Y,P) function is an aggregate function taking
46974787
** exactly two arguments.
46984788
**
46994789
** (2) If the P argument to percentile(Y,P) is not the same for every
@@ -4738,48 +4828,173 @@
47384828
** file that compiles into a shared-library or DLL that can be loaded
47394829
** into SQLite using the sqlite3_load_extension() interface.
47404830
**
47414831
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
47424832
**
4743
-** (14) A separate percentile_cond(Y,X) function is the equivalent of
4744
-** percentile(Y,X*100.0).
4833
+** (14) A separate percentile_cont(Y,P) function is equivalent to
4834
+** percentile(Y,P/100.0). In other words, the fraction value in
4835
+** the second argument is in the range of 0 to 1 instead of 0 to 100.
4836
+**
4837
+** (15) A separate percentile_disc(Y,P) function is like
4838
+** percentile_cont(Y,P) except that instead of returning the weighted
4839
+** average of the nearest two input values, it returns the next lower
4840
+** value. So the percentile_disc(Y,P) will always return a value
4841
+** that was one of the inputs.
4842
+**
4843
+** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and
4844
+** percentile_disc(Y,P) can be used as window functions.
4845
+**
4846
+** Differences from standard SQL:
4847
+**
4848
+** * The percentile_cont(X,P) function is equivalent to the following in
4849
+** standard SQL:
4850
+**
4851
+** (percentile_cont(P) WITHIN GROUP (ORDER BY X))
4852
+**
4853
+** The SQLite syntax is much more compact. The standard SQL syntax
4854
+** is also supported if SQLite is compiled with the
4855
+** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option.
4856
+**
4857
+** * No median(X) function exists in the SQL standard. App developers
4858
+** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)".
4859
+**
4860
+** * No percentile(Y,P) function exists in the SQL standard. Instead of
4861
+** percential(Y,P), developers must write this:
4862
+** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that
4863
+** the fraction parameter to percentile() goes from 0 to 100 whereas
4864
+** the fraction parameter in SQL standard percentile_cont() goes from
4865
+** 0 to 1.
4866
+**
4867
+** Implementation notes as of 2024-08-31:
4868
+**
4869
+** * The regular aggregate-function versions of these routines work
4870
+** by accumulating all values in an array of doubles, then sorting
4871
+** that array using quicksort before computing the answer. Thus
4872
+** the runtime is O(NlogN) where N is the number of rows of input.
4873
+**
4874
+** * For the window-function versions of these routines, the array of
4875
+** inputs is sorted as soon as the first value is computed. Thereafter,
4876
+** the array is kept in sorted order using an insert-sort. This
4877
+** results in O(N*K) performance where K is the size of the window.
4878
+** One can imagine alternative implementations that give O(N*logN*logK)
4879
+** performance, but they require more complex logic and data structures.
4880
+** The developers have elected to keep the asymptotically slower
4881
+** algorithm for now, for simplicity, under the theory that window
4882
+** functions are seldom used and when they are, the window size K is
4883
+** often small. The developers might revisit that decision later,
4884
+** should the need arise.
47454885
*/
4746
-/* #include "sqlite3ext.h" */
4747
-SQLITE_EXTENSION_INIT1
4886
+#if defined(SQLITE3_H)
4887
+ /* no-op */
4888
+#elif defined(SQLITE_STATIC_PERCENTILE)
4889
+/* # include "sqlite3.h" */
4890
+#else
4891
+/* # include "sqlite3ext.h" */
4892
+ SQLITE_EXTENSION_INIT1
4893
+#endif
47484894
#include <assert.h>
47494895
#include <string.h>
47504896
#include <stdlib.h>
47514897
4752
-/* The following object is the session context for a single percentile()
4753
-** function. We have to remember all input Y values until the very end.
4898
+/* The following object is the group context for a single percentile()
4899
+** aggregate. Remember all input Y values until the very end.
47544900
** Those values are accumulated in the Percentile.a[] array.
47554901
*/
47564902
typedef struct Percentile Percentile;
47574903
struct Percentile {
47584904
unsigned nAlloc; /* Number of slots allocated for a[] */
47594905
unsigned nUsed; /* Number of slots actually used in a[] */
4760
- double rPct; /* 1.0 more than the value for P */
4906
+ char bSorted; /* True if a[] is already in sorted order */
4907
+ char bKeepSorted; /* True if advantageous to keep a[] sorted */
4908
+ char bPctValid; /* True if rPct is valid */
4909
+ double rPct; /* Fraction. 0.0 to 1.0 */
47614910
double *a; /* Array of Y values */
47624911
};
4912
+
4913
+/* Details of each function in the percentile family */
4914
+typedef struct PercentileFunc PercentileFunc;
4915
+struct PercentileFunc {
4916
+ const char *zName; /* Function name */
4917
+ char nArg; /* Number of arguments */
4918
+ char mxFrac; /* Maximum value of the "fraction" input */
4919
+ char bDiscrete; /* True for percentile_disc() */
4920
+};
4921
+static const PercentileFunc aPercentFunc[] = {
4922
+ { "median", 1, 1, 0 },
4923
+ { "percentile", 2, 100, 0 },
4924
+ { "percentile_cont", 2, 1, 0 },
4925
+ { "percentile_disc", 2, 1, 1 },
4926
+};
47634927
47644928
/*
47654929
** Return TRUE if the input floating-point number is an infinity.
47664930
*/
4767
-static int isInfinity(double r){
4931
+static int percentIsInfinity(double r){
47684932
sqlite3_uint64 u;
47694933
assert( sizeof(u)==sizeof(r) );
47704934
memcpy(&u, &r, sizeof(u));
47714935
return ((u>>52)&0x7ff)==0x7ff;
47724936
}
47734937
47744938
/*
4775
-** Return TRUE if two doubles differ by 0.001 or less
4939
+** Return TRUE if two doubles differ by 0.001 or less.
47764940
*/
4777
-static int sameValue(double a, double b){
4941
+static int percentSameValue(double a, double b){
47784942
a -= b;
47794943
return a>=-0.001 && a<=0.001;
47804944
}
4945
+
4946
+/*
4947
+** Search p (which must have p->bSorted) looking for an entry with
4948
+** value y. Return the index of that entry.
4949
+**
4950
+** If bExact is true, return -1 if the entry is not found.
4951
+**
4952
+** If bExact is false, return the index at which a new entry with
4953
+** value y should be insert in order to keep the values in sorted
4954
+** order. The smallest return value in this case will be 0, and
4955
+** the largest return value will be p->nUsed.
4956
+*/
4957
+static int percentBinarySearch(Percentile *p, double y, int bExact){
4958
+ int iFirst = 0; /* First element of search range */
4959
+ int iLast = p->nUsed - 1; /* Last element of search range */
4960
+ while( iLast>=iFirst ){
4961
+ int iMid = (iFirst+iLast)/2;
4962
+ double x = p->a[iMid];
4963
+ if( x<y ){
4964
+ iFirst = iMid + 1;
4965
+ }else if( x>y ){
4966
+ iLast = iMid - 1;
4967
+ }else{
4968
+ return iMid;
4969
+ }
4970
+ }
4971
+ if( bExact ) return -1;
4972
+ return iFirst;
4973
+}
4974
+
4975
+/*
4976
+** Generate an error for a percentile function.
4977
+**
4978
+** The error format string must have exactly one occurrance of "%%s()"
4979
+** (with two '%' characters). That substring will be replaced by the name
4980
+** of the function.
4981
+*/
4982
+static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
4983
+ PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
4984
+ char *zMsg1;
4985
+ char *zMsg2;
4986
+ va_list ap;
4987
+
4988
+ va_start(ap, zFormat);
4989
+ zMsg1 = sqlite3_vmprintf(zFormat, ap);
4990
+ va_end(ap);
4991
+ zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0;
4992
+ sqlite3_result_error(pCtx, zMsg2, -1);
4993
+ sqlite3_free(zMsg1);
4994
+ sqlite3_free(zMsg2);
4995
+}
47814996
47824997
/*
47834998
** The "step" function for percentile(Y,P) is called once for each
47844999
** input row.
47855000
*/
@@ -4790,45 +5005,38 @@
47905005
double y;
47915006
assert( argc==2 || argc==1 );
47925007
47935008
if( argc==1 ){
47945009
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
4795
- rPct = 50.0;
4796
- }else if( sqlite3_user_data(pCtx)==0 ){
4797
- /* Requirement 3: P must be a number between 0 and 100 */
4798
- eType = sqlite3_value_numeric_type(argv[1]);
4799
- rPct = sqlite3_value_double(argv[1]);
4800
- if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
4801
- || rPct<0.0 || rPct>100.0 ){
4802
- sqlite3_result_error(pCtx, "2nd argument to percentile() is not "
4803
- "a number between 0.0 and 100.0", -1);
4804
- return;
4805
- }
4806
- }else{
4807
- /* Requirement 3: P must be a number between 0 and 1 */
4808
- eType = sqlite3_value_numeric_type(argv[1]);
4809
- rPct = sqlite3_value_double(argv[1]);
4810
- if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
4811
- || rPct<0.0 || rPct>1.0 ){
4812
- sqlite3_result_error(pCtx, "2nd argument to percentile_cont() is not "
4813
- "a number between 0.0 and 1.0", -1);
4814
- return;
4815
- }
4816
- rPct *= 100.0;
5010
+ rPct = 0.5;
5011
+ }else{
5012
+ /* Requirement 3: P must be a number between 0 and 100 */
5013
+ PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
5014
+ eType = sqlite3_value_numeric_type(argv[1]);
5015
+ rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac;
5016
+ if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
5017
+ || rPct<0.0 || rPct>1.0
5018
+ ){
5019
+ percentError(pCtx, "the fraction argument to %%s()"
5020
+ " is not between 0.0 and %.1f",
5021
+ (double)pFunc->mxFrac);
5022
+ return;
5023
+ }
48175024
}
48185025
48195026
/* Allocate the session context. */
48205027
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
48215028
if( p==0 ) return;
48225029
48235030
/* Remember the P value. Throw an error if the P value is different
48245031
** from any prior row, per Requirement (2). */
4825
- if( p->rPct==0.0 ){
4826
- p->rPct = rPct+1.0;
4827
- }else if( !sameValue(p->rPct,rPct+1.0) ){
4828
- sqlite3_result_error(pCtx, "2nd argument to percentile() is not the "
4829
- "same for all input rows", -1);
5032
+ if( !p->bPctValid ){
5033
+ p->rPct = rPct;
5034
+ p->bPctValid = 1;
5035
+ }else if( !percentSameValue(p->rPct,rPct) ){
5036
+ percentError(pCtx, "the fraction argument to %%s()"
5037
+ " is not the same for all input rows");
48305038
return;
48315039
}
48325040
48335041
/* Ignore rows for which Y is NULL */
48345042
eType = sqlite3_value_type(argv[0]);
@@ -4835,19 +5043,18 @@
48355043
if( eType==SQLITE_NULL ) return;
48365044
48375045
/* If not NULL, then Y must be numeric. Otherwise throw an error.
48385046
** Requirement 4 */
48395047
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
4840
- sqlite3_result_error(pCtx, "1st argument to percentile() is not "
4841
- "numeric", -1);
5048
+ percentError(pCtx, "input to %%s() is not numeric");
48425049
return;
48435050
}
48445051
48455052
/* Throw an error if the Y value is infinity or NaN */
48465053
y = sqlite3_value_double(argv[0]);
4847
- if( isInfinity(y) ){
4848
- sqlite3_result_error(pCtx, "Inf input to percentile()", -1);
5054
+ if( percentIsInfinity(y) ){
5055
+ percentError(pCtx, "Inf input to %%s()");
48495056
return;
48505057
}
48515058
48525059
/* Allocate and store the Y */
48535060
if( p->nUsed>=p->nAlloc ){
@@ -4860,112 +5067,209 @@
48605067
return;
48615068
}
48625069
p->nAlloc = n;
48635070
p->a = a;
48645071
}
4865
- p->a[p->nUsed++] = y;
5072
+ if( p->nUsed==0 ){
5073
+ p->a[p->nUsed++] = y;
5074
+ p->bSorted = 1;
5075
+ }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
5076
+ p->a[p->nUsed++] = y;
5077
+ }else if( p->bKeepSorted ){
5078
+ int i;
5079
+ i = percentBinarySearch(p, y, 0);
5080
+ if( i<p->nUsed ){
5081
+ memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
5082
+ }
5083
+ p->a[i] = y;
5084
+ p->nUsed++;
5085
+ }else{
5086
+ p->a[p->nUsed++] = y;
5087
+ p->bSorted = 0;
5088
+ }
48665089
}
48675090
5091
+/*
5092
+** Interchange two doubles.
5093
+*/
5094
+#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
5095
+
48685096
/*
48695097
** Sort an array of doubles.
5098
+**
5099
+** Algorithm: quicksort
5100
+**
5101
+** This is implemented separately rather than using the qsort() routine
5102
+** from the standard library because:
5103
+**
5104
+** (1) To avoid a dependency on qsort()
5105
+** (2) To avoid the function call to the comparison routine for each
5106
+** comparison.
48705107
*/
4871
-static void sortDoubles(double *a, int n){
4872
- int iLt; /* Entries with index less than iLt are less than rPivot */
4873
- int iGt; /* Entries with index iGt or more are greater than rPivot */
5108
+static void percentSort(double *a, unsigned int n){
5109
+ int iLt; /* Entries before a[iLt] are less than rPivot */
5110
+ int iGt; /* Entries at or after a[iGt] are greater than rPivot */
48745111
int i; /* Loop counter */
48755112
double rPivot; /* The pivot value */
4876
- double rTmp; /* Temporary used to swap two values */
4877
-
4878
- if( n<2 ) return;
4879
- if( n>5 ){
4880
- rPivot = (a[0] + a[n/2] + a[n-1])/3.0;
4881
- }else{
4882
- rPivot = a[n/2];
4883
- }
4884
- iLt = i = 0;
4885
- iGt = n;
4886
- while( i<iGt ){
5113
+
5114
+ assert( n>=2 );
5115
+ if( a[0]>a[n-1] ){
5116
+ SWAP_DOUBLE(a[0],a[n-1])
5117
+ }
5118
+ if( n==2 ) return;
5119
+ iGt = n-1;
5120
+ i = n/2;
5121
+ if( a[0]>a[i] ){
5122
+ SWAP_DOUBLE(a[0],a[i])
5123
+ }else if( a[i]>a[iGt] ){
5124
+ SWAP_DOUBLE(a[i],a[iGt])
5125
+ }
5126
+ if( n==3 ) return;
5127
+ rPivot = a[i];
5128
+ iLt = i = 1;
5129
+ do{
48875130
if( a[i]<rPivot ){
4888
- if( i>iLt ){
4889
- rTmp = a[i];
4890
- a[i] = a[iLt];
4891
- a[iLt] = rTmp;
4892
- }
5131
+ if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
48935132
iLt++;
48945133
i++;
48955134
}else if( a[i]>rPivot ){
48965135
do{
48975136
iGt--;
48985137
}while( iGt>i && a[iGt]>rPivot );
4899
- rTmp = a[i];
4900
- a[i] = a[iGt];
4901
- a[iGt] = rTmp;
5138
+ SWAP_DOUBLE(a[i],a[iGt])
49025139
}else{
49035140
i++;
49045141
}
4905
- }
4906
- if( iLt>=2 ) sortDoubles(a, iLt);
4907
- if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt);
4908
-
5142
+ }while( i<iGt );
5143
+ if( iLt>=2 ) percentSort(a, iLt);
5144
+ if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
5145
+
49095146
/* Uncomment for testing */
49105147
#if 0
49115148
for(i=0; i<n-1; i++){
49125149
assert( a[i]<=a[i+1] );
49135150
}
49145151
#endif
49155152
}
5153
+
49165154
49175155
/*
4918
-** Called to compute the final output of percentile() and to clean
4919
-** up all allocated memory.
5156
+** The "inverse" function for percentile(Y,P) is called to remove a
5157
+** row that was previously inserted by "step".
49205158
*/
4921
-static void percentFinal(sqlite3_context *pCtx){
5159
+static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
5160
+ Percentile *p;
5161
+ int eType;
5162
+ double y;
5163
+ int i;
5164
+ assert( argc==2 || argc==1 );
5165
+
5166
+ /* Allocate the session context. */
5167
+ p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
5168
+ assert( p!=0 );
5169
+
5170
+ /* Ignore rows for which Y is NULL */
5171
+ eType = sqlite3_value_type(argv[0]);
5172
+ if( eType==SQLITE_NULL ) return;
5173
+
5174
+ /* If not NULL, then Y must be numeric. Otherwise throw an error.
5175
+ ** Requirement 4 */
5176
+ if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
5177
+ return;
5178
+ }
5179
+
5180
+ /* Ignore the Y value if it is infinity or NaN */
5181
+ y = sqlite3_value_double(argv[0]);
5182
+ if( percentIsInfinity(y) ){
5183
+ return;
5184
+ }
5185
+ if( p->bSorted==0 ){
5186
+ assert( p->nUsed>1 );
5187
+ percentSort(p->a, p->nUsed);
5188
+ p->bSorted = 1;
5189
+ }
5190
+ p->bKeepSorted = 1;
5191
+
5192
+ /* Find and remove the row */
5193
+ i = percentBinarySearch(p, y, 1);
5194
+ if( i>=0 ){
5195
+ p->nUsed--;
5196
+ if( i<p->nUsed ){
5197
+ memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
5198
+ }
5199
+ }
5200
+}
5201
+
5202
+/*
5203
+** Compute the final output of percentile(). Clean up all allocated
5204
+** memory if and only if bIsFinal is true.
5205
+*/
5206
+static void percentCompute(sqlite3_context *pCtx, int bIsFinal){
49225207
Percentile *p;
5208
+ PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
49235209
unsigned i1, i2;
49245210
double v1, v2;
49255211
double ix, vx;
49265212
p = (Percentile*)sqlite3_aggregate_context(pCtx, 0);
49275213
if( p==0 ) return;
49285214
if( p->a==0 ) return;
49295215
if( p->nUsed ){
4930
- sortDoubles(p->a, p->nUsed);
4931
- ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
5216
+ if( p->bSorted==0 ){
5217
+ assert( p->nUsed>1 );
5218
+ percentSort(p->a, p->nUsed);
5219
+ p->bSorted = 1;
5220
+ }
5221
+ ix = p->rPct*(p->nUsed-1);
49325222
i1 = (unsigned)ix;
4933
- i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
4934
- v1 = p->a[i1];
4935
- v2 = p->a[i2];
4936
- vx = v1 + (v2-v1)*(ix-i1);
5223
+ if( pFunc->bDiscrete ){
5224
+ vx = p->a[i1];
5225
+ }else{
5226
+ i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
5227
+ v1 = p->a[i1];
5228
+ v2 = p->a[i2];
5229
+ vx = v1 + (v2-v1)*(ix-i1);
5230
+ }
49375231
sqlite3_result_double(pCtx, vx);
49385232
}
4939
- sqlite3_free(p->a);
4940
- memset(p, 0, sizeof(*p));
5233
+ if( bIsFinal ){
5234
+ sqlite3_free(p->a);
5235
+ memset(p, 0, sizeof(*p));
5236
+ }else{
5237
+ p->bKeepSorted = 1;
5238
+ }
5239
+}
5240
+static void percentFinal(sqlite3_context *pCtx){
5241
+ percentCompute(pCtx, 1);
5242
+}
5243
+static void percentValue(sqlite3_context *pCtx){
5244
+ percentCompute(pCtx, 0);
49415245
}
49425246
4943
-
4944
-#ifdef _WIN32
5247
+#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE)
49455248
49465249
#endif
49475250
int sqlite3_percentile_init(
49485251
sqlite3 *db,
49495252
char **pzErrMsg,
49505253
const sqlite3_api_routines *pApi
49515254
){
49525255
int rc = SQLITE_OK;
5256
+ int i;
5257
+#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
5258
+ (void)pApi; /* Unused parameter */
5259
+#else
49535260
SQLITE_EXTENSION_INIT2(pApi);
5261
+#endif
49545262
(void)pzErrMsg; /* Unused parameter */
4955
- rc = sqlite3_create_function(db, "percentile", 2,
4956
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
4957
- 0, percentStep, percentFinal);
4958
- if( rc==SQLITE_OK ){
4959
- rc = sqlite3_create_function(db, "median", 1,
4960
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
4961
- 0, percentStep, percentFinal);
4962
- }
4963
- if( rc==SQLITE_OK ){
4964
- rc = sqlite3_create_function(db, "percentile_cont", 2,
4965
- SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep,
4966
- 0, percentStep, percentFinal);
5263
+ for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){
5264
+ rc = sqlite3_create_window_function(db,
5265
+ aPercentFunc[i].zName,
5266
+ aPercentFunc[i].nArg,
5267
+ SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1,
5268
+ (void*)&aPercentFunc[i],
5269
+ percentStep, percentFinal, percentValue, percentInverse, 0);
5270
+ if( rc ) break;
49675271
}
49685272
return rc;
49695273
}
49705274
49715275
/************************* End ../ext/misc/percentile.c ********************/
@@ -22375,14 +22679,15 @@
2237522679
sqlite3_bind_double(pStmt, i, INFINITY);
2237622680
#endif
2237722681
}else if( strncmp(zVar, "$int_", 5)==0 ){
2237822682
sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
2237922683
}else if( strncmp(zVar, "$text_", 6)==0 ){
22380
- char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
22684
+ size_t szVar = strlen(zVar);
22685
+ char *zBuf = sqlite3_malloc64( szVar-5 );
2238122686
if( zBuf ){
22382
- memcpy(zBuf, &zVar[6], strlen(zVar)-5);
22383
- sqlite3_bind_text64(pStmt, i, zBuf, -1, sqlite3_free, SQLITE_UTF8);
22687
+ memcpy(zBuf, &zVar[6], szVar-5);
22688
+ sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
2238422689
}
2238522690
}else{
2238622691
sqlite3_bind_null(pStmt, i);
2238722692
}
2238822693
sqlite3_reset(pQ);
@@ -29871,11 +30176,11 @@
2987130176
sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
2987230177
newOpt = curOpt;
2987330178
for(ii=2; ii<nArg; ii++){
2987430179
const char *z = azArg[ii];
2987530180
int useLabel = 0;
29876
- const char *zLabel;
30181
+ const char *zLabel = 0;
2987730182
if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
2987830183
useLabel = z[0];
2987930184
zLabel = &z[1];
2988030185
}else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){
2988130186
useLabel = '+';
@@ -29888,15 +30193,15 @@
2988830193
for(jj=0; jj<ArraySize(aLabel); jj++){
2988930194
if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
2989030195
}
2989130196
if( jj>=ArraySize(aLabel) ){
2989230197
eputf("Error: no such optimization: \"%s\"\n", zLabel);
29893
- eputf("Should be one of:");
30198
+ eputz("Should be one of:");
2989430199
for(jj=0; jj<ArraySize(aLabel); jj++){
2989530200
eputf(" %s", aLabel[jj].zLabel);
2989630201
}
29897
- eputf("\n");
30202
+ eputz("\n");
2989830203
rc = 1;
2989930204
goto meta_command_exit;
2990030205
}
2990130206
if( useLabel=='+' ){
2990230207
newOpt &= ~aLabel[jj].mask;
@@ -29909,13 +30214,13 @@
2990930214
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
2991030215
}else if( nArg<3 ){
2991130216
curOpt = ~newOpt;
2991230217
}
2991330218
if( newOpt==0 ){
29914
- oputf("+All\n");
30219
+ oputz("+All\n");
2991530220
}else if( newOpt==0xffffffff ){
29916
- oputf("-All\n");
30221
+ oputz("-All\n");
2991730222
}else{
2991830223
int jj;
2991930224
for(jj=0; jj<ArraySize(aLabel); jj++){
2992030225
unsigned int m = aLabel[jj].mask;
2992130226
if( !aLabel[jj].bDsply ) continue;
2992230227
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -262,10 +262,11 @@
262 /* Deselect most features from the console I/O package for Fiddle. */
263 # define SQLITE_CIO_NO_REDIRECT
264 # define SQLITE_CIO_NO_CLASSIFY
265 # define SQLITE_CIO_NO_TRANSLATE
266 # define SQLITE_CIO_NO_SETMODE
 
267 #endif
268 /************************* Begin ../ext/consio/console_io.h ******************/
269 /*
270 ** 2023 November 1
271 **
@@ -442,16 +443,23 @@
442 #ifdef CONSIO_EPUTB
443 SQLITE_INTERNAL_LINKAGE int
444 ePutbUtf8(const char *cBuf, int nAccept);
445 #endif
446
 
 
 
 
 
 
 
 
447 /*
448 ** Collect input like fgets(...) with special provisions for input
449 ** from the console on platforms that require same. Defers to the
450 ** C library fgets() when input is not from the console. Newline
451 ** translation may be done as set by set{Binary,Text}Mode(). As a
452 ** convenience, pfIn==NULL is treated as stdin.
453 */
454 SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
455 /* Like fGetsUtf8 except stream is always the designated input. */
456 /* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */
457
@@ -1144,10 +1152,90 @@
1144 # if CIO_WIN_WC_XLATE
1145 }
1146 # endif
1147 }
1148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1149 # ifdef CONSIO_EPUTB
1150 SQLITE_INTERNAL_LINKAGE int
1151 ePutbUtf8(const char *cBuf, int nAccept){
1152 FILE *pfErr;
1153 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1155,11 +1243,11 @@
1155 # if CIO_WIN_WC_XLATE
1156 if( pstReachesConsole(ppst) ){
1157 return conZstrEmit(ppst, cBuf, nAccept);
1158 }else {
1159 # endif
1160 return (int)fwrite(cBuf, 1, nAccept, pfErr);
1161 # if CIO_WIN_WC_XLATE
1162 }
1163 # endif
1164 }
1165 # endif /* defined(CONSIO_EPUTB) */
@@ -1221,11 +1309,11 @@
1221 return cBuf;
1222 }else return 0;
1223 # endif
1224 }else{
1225 # endif
1226 return fgets(cBuf, ncMax, pfIn);
1227 # if CIO_WIN_WC_XLATE
1228 }
1229 # endif
1230 }
1231 #endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
@@ -1265,15 +1353,16 @@
1265 # define oputz(z) oPutsUtf8(z)
1266 # define oputf oPrintfUtf8
1267 # define eputz(z) ePutsUtf8(z)
1268 # define eputf ePrintfUtf8
1269 # define oputb(buf,na) oPutbUtf8(buf,na)
 
1270
1271 #else
1272 /* For Fiddle, all console handling and emit redirection is omitted. */
1273 /* These next 3 macros are for emitting formatted output. When complaints
1274 * from the WASM build are issued for non-formatted output, (when a mere
1275 * string literal is to be emitted, the ?putz(z) forms should be used.
1276 * (This permits compile-time checking of format string / argument mismatch.)
1277 */
1278 # define oputf(fmt, ...) printf(fmt,__VA_ARGS__)
1279 # define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__)
@@ -1281,10 +1370,11 @@
1281 /* These next 3 macros are for emitting simple string literals. */
1282 # define oputz(z) fputs(z,stdout)
1283 # define eputz(z) fputs(z,stderr)
1284 # define sputz(fp,z) fputs(z,fp)
1285 # define oputb(buf,na) fwrite(buf,1,na,stdout)
 
1286 #endif
1287
1288 /* True if the timer is enabled */
1289 static int enableTimer = 0;
1290
@@ -4689,11 +4779,11 @@
4689 ** May you share freely, never taking more than you give.
4690 **
4691 ******************************************************************************
4692 **
4693 ** This file contains code to implement the percentile(Y,P) SQL function
4694 ** as described below:
4695 **
4696 ** (1) The percentile(Y,P) function is an aggregate function taking
4697 ** exactly two arguments.
4698 **
4699 ** (2) If the P argument to percentile(Y,P) is not the same for every
@@ -4738,48 +4828,173 @@
4738 ** file that compiles into a shared-library or DLL that can be loaded
4739 ** into SQLite using the sqlite3_load_extension() interface.
4740 **
4741 ** (13) A separate median(Y) function is the equivalent percentile(Y,50).
4742 **
4743 ** (14) A separate percentile_cond(Y,X) function is the equivalent of
4744 ** percentile(Y,X*100.0).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4745 */
4746 /* #include "sqlite3ext.h" */
4747 SQLITE_EXTENSION_INIT1
 
 
 
 
 
 
4748 #include <assert.h>
4749 #include <string.h>
4750 #include <stdlib.h>
4751
4752 /* The following object is the session context for a single percentile()
4753 ** function. We have to remember all input Y values until the very end.
4754 ** Those values are accumulated in the Percentile.a[] array.
4755 */
4756 typedef struct Percentile Percentile;
4757 struct Percentile {
4758 unsigned nAlloc; /* Number of slots allocated for a[] */
4759 unsigned nUsed; /* Number of slots actually used in a[] */
4760 double rPct; /* 1.0 more than the value for P */
 
 
 
4761 double *a; /* Array of Y values */
4762 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4763
4764 /*
4765 ** Return TRUE if the input floating-point number is an infinity.
4766 */
4767 static int isInfinity(double r){
4768 sqlite3_uint64 u;
4769 assert( sizeof(u)==sizeof(r) );
4770 memcpy(&u, &r, sizeof(u));
4771 return ((u>>52)&0x7ff)==0x7ff;
4772 }
4773
4774 /*
4775 ** Return TRUE if two doubles differ by 0.001 or less
4776 */
4777 static int sameValue(double a, double b){
4778 a -= b;
4779 return a>=-0.001 && a<=0.001;
4780 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4781
4782 /*
4783 ** The "step" function for percentile(Y,P) is called once for each
4784 ** input row.
4785 */
@@ -4790,45 +5005,38 @@
4790 double y;
4791 assert( argc==2 || argc==1 );
4792
4793 if( argc==1 ){
4794 /* Requirement 13: median(Y) is the same as percentile(Y,50). */
4795 rPct = 50.0;
4796 }else if( sqlite3_user_data(pCtx)==0 ){
4797 /* Requirement 3: P must be a number between 0 and 100 */
4798 eType = sqlite3_value_numeric_type(argv[1]);
4799 rPct = sqlite3_value_double(argv[1]);
4800 if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
4801 || rPct<0.0 || rPct>100.0 ){
4802 sqlite3_result_error(pCtx, "2nd argument to percentile() is not "
4803 "a number between 0.0 and 100.0", -1);
4804 return;
4805 }
4806 }else{
4807 /* Requirement 3: P must be a number between 0 and 1 */
4808 eType = sqlite3_value_numeric_type(argv[1]);
4809 rPct = sqlite3_value_double(argv[1]);
4810 if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
4811 || rPct<0.0 || rPct>1.0 ){
4812 sqlite3_result_error(pCtx, "2nd argument to percentile_cont() is not "
4813 "a number between 0.0 and 1.0", -1);
4814 return;
4815 }
4816 rPct *= 100.0;
4817 }
4818
4819 /* Allocate the session context. */
4820 p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
4821 if( p==0 ) return;
4822
4823 /* Remember the P value. Throw an error if the P value is different
4824 ** from any prior row, per Requirement (2). */
4825 if( p->rPct==0.0 ){
4826 p->rPct = rPct+1.0;
4827 }else if( !sameValue(p->rPct,rPct+1.0) ){
4828 sqlite3_result_error(pCtx, "2nd argument to percentile() is not the "
4829 "same for all input rows", -1);
 
4830 return;
4831 }
4832
4833 /* Ignore rows for which Y is NULL */
4834 eType = sqlite3_value_type(argv[0]);
@@ -4835,19 +5043,18 @@
4835 if( eType==SQLITE_NULL ) return;
4836
4837 /* If not NULL, then Y must be numeric. Otherwise throw an error.
4838 ** Requirement 4 */
4839 if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
4840 sqlite3_result_error(pCtx, "1st argument to percentile() is not "
4841 "numeric", -1);
4842 return;
4843 }
4844
4845 /* Throw an error if the Y value is infinity or NaN */
4846 y = sqlite3_value_double(argv[0]);
4847 if( isInfinity(y) ){
4848 sqlite3_result_error(pCtx, "Inf input to percentile()", -1);
4849 return;
4850 }
4851
4852 /* Allocate and store the Y */
4853 if( p->nUsed>=p->nAlloc ){
@@ -4860,112 +5067,209 @@
4860 return;
4861 }
4862 p->nAlloc = n;
4863 p->a = a;
4864 }
4865 p->a[p->nUsed++] = y;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4866 }
4867
 
 
 
 
 
4868 /*
4869 ** Sort an array of doubles.
 
 
 
 
 
 
 
 
 
4870 */
4871 static void sortDoubles(double *a, int n){
4872 int iLt; /* Entries with index less than iLt are less than rPivot */
4873 int iGt; /* Entries with index iGt or more are greater than rPivot */
4874 int i; /* Loop counter */
4875 double rPivot; /* The pivot value */
4876 double rTmp; /* Temporary used to swap two values */
4877
4878 if( n<2 ) return;
4879 if( n>5 ){
4880 rPivot = (a[0] + a[n/2] + a[n-1])/3.0;
4881 }else{
4882 rPivot = a[n/2];
4883 }
4884 iLt = i = 0;
4885 iGt = n;
4886 while( i<iGt ){
 
 
 
 
 
 
4887 if( a[i]<rPivot ){
4888 if( i>iLt ){
4889 rTmp = a[i];
4890 a[i] = a[iLt];
4891 a[iLt] = rTmp;
4892 }
4893 iLt++;
4894 i++;
4895 }else if( a[i]>rPivot ){
4896 do{
4897 iGt--;
4898 }while( iGt>i && a[iGt]>rPivot );
4899 rTmp = a[i];
4900 a[i] = a[iGt];
4901 a[iGt] = rTmp;
4902 }else{
4903 i++;
4904 }
4905 }
4906 if( iLt>=2 ) sortDoubles(a, iLt);
4907 if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt);
4908
4909 /* Uncomment for testing */
4910 #if 0
4911 for(i=0; i<n-1; i++){
4912 assert( a[i]<=a[i+1] );
4913 }
4914 #endif
4915 }
 
4916
4917 /*
4918 ** Called to compute the final output of percentile() and to clean
4919 ** up all allocated memory.
4920 */
4921 static void percentFinal(sqlite3_context *pCtx){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4922 Percentile *p;
 
4923 unsigned i1, i2;
4924 double v1, v2;
4925 double ix, vx;
4926 p = (Percentile*)sqlite3_aggregate_context(pCtx, 0);
4927 if( p==0 ) return;
4928 if( p->a==0 ) return;
4929 if( p->nUsed ){
4930 sortDoubles(p->a, p->nUsed);
4931 ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
 
 
 
 
4932 i1 = (unsigned)ix;
4933 i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
4934 v1 = p->a[i1];
4935 v2 = p->a[i2];
4936 vx = v1 + (v2-v1)*(ix-i1);
 
 
 
 
4937 sqlite3_result_double(pCtx, vx);
4938 }
4939 sqlite3_free(p->a);
4940 memset(p, 0, sizeof(*p));
 
 
 
 
 
 
 
 
 
 
4941 }
4942
4943
4944 #ifdef _WIN32
4945
4946 #endif
4947 int sqlite3_percentile_init(
4948 sqlite3 *db,
4949 char **pzErrMsg,
4950 const sqlite3_api_routines *pApi
4951 ){
4952 int rc = SQLITE_OK;
 
 
 
 
4953 SQLITE_EXTENSION_INIT2(pApi);
 
4954 (void)pzErrMsg; /* Unused parameter */
4955 rc = sqlite3_create_function(db, "percentile", 2,
4956 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
4957 0, percentStep, percentFinal);
4958 if( rc==SQLITE_OK ){
4959 rc = sqlite3_create_function(db, "median", 1,
4960 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
4961 0, percentStep, percentFinal);
4962 }
4963 if( rc==SQLITE_OK ){
4964 rc = sqlite3_create_function(db, "percentile_cont", 2,
4965 SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep,
4966 0, percentStep, percentFinal);
4967 }
4968 return rc;
4969 }
4970
4971 /************************* End ../ext/misc/percentile.c ********************/
@@ -22375,14 +22679,15 @@
22375 sqlite3_bind_double(pStmt, i, INFINITY);
22376 #endif
22377 }else if( strncmp(zVar, "$int_", 5)==0 ){
22378 sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
22379 }else if( strncmp(zVar, "$text_", 6)==0 ){
22380 char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
 
22381 if( zBuf ){
22382 memcpy(zBuf, &zVar[6], strlen(zVar)-5);
22383 sqlite3_bind_text64(pStmt, i, zBuf, -1, sqlite3_free, SQLITE_UTF8);
22384 }
22385 }else{
22386 sqlite3_bind_null(pStmt, i);
22387 }
22388 sqlite3_reset(pQ);
@@ -29871,11 +30176,11 @@
29871 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
29872 newOpt = curOpt;
29873 for(ii=2; ii<nArg; ii++){
29874 const char *z = azArg[ii];
29875 int useLabel = 0;
29876 const char *zLabel;
29877 if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
29878 useLabel = z[0];
29879 zLabel = &z[1];
29880 }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){
29881 useLabel = '+';
@@ -29888,15 +30193,15 @@
29888 for(jj=0; jj<ArraySize(aLabel); jj++){
29889 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
29890 }
29891 if( jj>=ArraySize(aLabel) ){
29892 eputf("Error: no such optimization: \"%s\"\n", zLabel);
29893 eputf("Should be one of:");
29894 for(jj=0; jj<ArraySize(aLabel); jj++){
29895 eputf(" %s", aLabel[jj].zLabel);
29896 }
29897 eputf("\n");
29898 rc = 1;
29899 goto meta_command_exit;
29900 }
29901 if( useLabel=='+' ){
29902 newOpt &= ~aLabel[jj].mask;
@@ -29909,13 +30214,13 @@
29909 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
29910 }else if( nArg<3 ){
29911 curOpt = ~newOpt;
29912 }
29913 if( newOpt==0 ){
29914 oputf("+All\n");
29915 }else if( newOpt==0xffffffff ){
29916 oputf("-All\n");
29917 }else{
29918 int jj;
29919 for(jj=0; jj<ArraySize(aLabel); jj++){
29920 unsigned int m = aLabel[jj].mask;
29921 if( !aLabel[jj].bDsply ) continue;
29922
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -262,10 +262,11 @@
262 /* Deselect most features from the console I/O package for Fiddle. */
263 # define SQLITE_CIO_NO_REDIRECT
264 # define SQLITE_CIO_NO_CLASSIFY
265 # define SQLITE_CIO_NO_TRANSLATE
266 # define SQLITE_CIO_NO_SETMODE
267 # define SQLITE_CIO_NO_FLUSH
268 #endif
269 /************************* Begin ../ext/consio/console_io.h ******************/
270 /*
271 ** 2023 November 1
272 **
@@ -442,16 +443,23 @@
443 #ifdef CONSIO_EPUTB
444 SQLITE_INTERNAL_LINKAGE int
445 ePutbUtf8(const char *cBuf, int nAccept);
446 #endif
447
448 /*
449 ** Flush the given output stream. Return non-zero for success, else 0.
450 */
451 #if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
452 SQLITE_INTERNAL_LINKAGE int
453 fFlushBuffer(FILE *pfOut);
454 #endif
455
456 /*
457 ** Collect input like fgets(...) with special provisions for input
458 ** from the console on such platforms as require same. Newline
459 ** translation may be done as set by set{Binary,Text}Mode().
460 ** As a convenience, pfIn==NULL is treated as stdin.
 
461 */
462 SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
463 /* Like fGetsUtf8 except stream is always the designated input. */
464 /* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */
465
@@ -1144,10 +1152,90 @@
1152 # if CIO_WIN_WC_XLATE
1153 }
1154 # endif
1155 }
1156
1157 /*
1158 ** Flush the given output stream. Return non-zero for success, else 0.
1159 */
1160 #if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
1161 SQLITE_INTERNAL_LINKAGE int
1162 fFlushBuffer(FILE *pfOut){
1163 # if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
1164 return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
1165 # else
1166 return fflush(pfOut);
1167 # endif
1168 }
1169 #endif
1170
1171 #if CIO_WIN_WC_XLATE \
1172 && !defined(SHELL_OMIT_FIO_DUPE) \
1173 && defined(SQLITE_USE_ONLY_WIN32)
1174 static struct FileAltIds {
1175 int fd;
1176 HANDLE fh;
1177 } altIdsOfFile(FILE *pf){
1178 struct FileAltIds rv = { _fileno(pf) };
1179 union { intptr_t osfh; HANDLE fh; } fid = {
1180 (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
1181 };
1182 rv.fh = fid.fh;
1183 return rv;
1184 }
1185
1186 SQLITE_INTERNAL_LINKAGE size_t
1187 cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
1188 size_t rv = 0;
1189 struct FileAltIds fai = altIdsOfFile(pf);
1190 int fmode = _setmode(fai.fd, _O_BINARY);
1191 _setmode(fai.fd, fmode);
1192 while( rv < ocnt ){
1193 size_t nbo = osz;
1194 while( nbo > 0 ){
1195 DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
1196 BOOL wrc = TRUE;
1197 BOOL genCR = (fmode & _O_TEXT)!=0;
1198 if( genCR ){
1199 const char *pnl = (const char*)memchr(buf, '\n', nbo);
1200 if( pnl ) nbo = pnl - (const char*)buf;
1201 else genCR = 0;
1202 }
1203 if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
1204 if( genCR && wrc ){
1205 wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
1206 ++dwno; /* Skip over the LF */
1207 }
1208 if( !wrc ) return rv;
1209 buf = (const char*)buf + dwno;
1210 nbo += dwno;
1211 }
1212 ++rv;
1213 }
1214 return rv;
1215 }
1216
1217 SQLITE_INTERNAL_LINKAGE char *
1218 cfGets(char *cBuf, int n, FILE *pf){
1219 int nci = 0;
1220 struct FileAltIds fai = altIdsOfFile(pf);
1221 int fmode = _setmode(fai.fd, _O_BINARY);
1222 BOOL eatCR = (fmode & _O_TEXT)!=0;
1223 _setmode(fai.fd, fmode);
1224 while( nci < n-1 ){
1225 DWORD nr;
1226 if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
1227 if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
1228 }
1229 if( nci < n ) cBuf[nci] = 0;
1230 return (nci>0)? cBuf : 0;
1231 }
1232 # else
1233 # define cfWrite(b,os,no,f) fwrite(b,os,no,f)
1234 # define cfGets(b,n,f) fgets(b,n,f)
1235 # endif
1236
1237 # ifdef CONSIO_EPUTB
1238 SQLITE_INTERNAL_LINKAGE int
1239 ePutbUtf8(const char *cBuf, int nAccept){
1240 FILE *pfErr;
1241 PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
@@ -1155,11 +1243,11 @@
1243 # if CIO_WIN_WC_XLATE
1244 if( pstReachesConsole(ppst) ){
1245 return conZstrEmit(ppst, cBuf, nAccept);
1246 }else {
1247 # endif
1248 return (int)cfWrite(cBuf, 1, nAccept, pfErr);
1249 # if CIO_WIN_WC_XLATE
1250 }
1251 # endif
1252 }
1253 # endif /* defined(CONSIO_EPUTB) */
@@ -1221,11 +1309,11 @@
1309 return cBuf;
1310 }else return 0;
1311 # endif
1312 }else{
1313 # endif
1314 return cfGets(cBuf, ncMax, pfIn);
1315 # if CIO_WIN_WC_XLATE
1316 }
1317 # endif
1318 }
1319 #endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
@@ -1265,15 +1353,16 @@
1353 # define oputz(z) oPutsUtf8(z)
1354 # define oputf oPrintfUtf8
1355 # define eputz(z) ePutsUtf8(z)
1356 # define eputf ePrintfUtf8
1357 # define oputb(buf,na) oPutbUtf8(buf,na)
1358 # define fflush(s) fFlushBuffer(s);
1359
1360 #else
1361 /* For Fiddle, all console handling and emit redirection is omitted. */
1362 /* These next 3 macros are for emitting formatted output. When complaints
1363 * from the WASM build are issued for non-formatted output, when a mere
1364 * string literal is to be emitted, the ?putz(z) forms should be used.
1365 * (This permits compile-time checking of format string / argument mismatch.)
1366 */
1367 # define oputf(fmt, ...) printf(fmt,__VA_ARGS__)
1368 # define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__)
@@ -1281,10 +1370,11 @@
1370 /* These next 3 macros are for emitting simple string literals. */
1371 # define oputz(z) fputs(z,stdout)
1372 # define eputz(z) fputs(z,stderr)
1373 # define sputz(fp,z) fputs(z,fp)
1374 # define oputb(buf,na) fwrite(buf,1,na,stdout)
1375 # undef fflush
1376 #endif
1377
1378 /* True if the timer is enabled */
1379 static int enableTimer = 0;
1380
@@ -4689,11 +4779,11 @@
4779 ** May you share freely, never taking more than you give.
4780 **
4781 ******************************************************************************
4782 **
4783 ** This file contains code to implement the percentile(Y,P) SQL function
4784 ** and similar as described below:
4785 **
4786 ** (1) The percentile(Y,P) function is an aggregate function taking
4787 ** exactly two arguments.
4788 **
4789 ** (2) If the P argument to percentile(Y,P) is not the same for every
@@ -4738,48 +4828,173 @@
4828 ** file that compiles into a shared-library or DLL that can be loaded
4829 ** into SQLite using the sqlite3_load_extension() interface.
4830 **
4831 ** (13) A separate median(Y) function is the equivalent percentile(Y,50).
4832 **
4833 ** (14) A separate percentile_cont(Y,P) function is equivalent to
4834 ** percentile(Y,P/100.0). In other words, the fraction value in
4835 ** the second argument is in the range of 0 to 1 instead of 0 to 100.
4836 **
4837 ** (15) A separate percentile_disc(Y,P) function is like
4838 ** percentile_cont(Y,P) except that instead of returning the weighted
4839 ** average of the nearest two input values, it returns the next lower
4840 ** value. So the percentile_disc(Y,P) will always return a value
4841 ** that was one of the inputs.
4842 **
4843 ** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and
4844 ** percentile_disc(Y,P) can be used as window functions.
4845 **
4846 ** Differences from standard SQL:
4847 **
4848 ** * The percentile_cont(X,P) function is equivalent to the following in
4849 ** standard SQL:
4850 **
4851 ** (percentile_cont(P) WITHIN GROUP (ORDER BY X))
4852 **
4853 ** The SQLite syntax is much more compact. The standard SQL syntax
4854 ** is also supported if SQLite is compiled with the
4855 ** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option.
4856 **
4857 ** * No median(X) function exists in the SQL standard. App developers
4858 ** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)".
4859 **
4860 ** * No percentile(Y,P) function exists in the SQL standard. Instead of
4861 ** percential(Y,P), developers must write this:
4862 ** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that
4863 ** the fraction parameter to percentile() goes from 0 to 100 whereas
4864 ** the fraction parameter in SQL standard percentile_cont() goes from
4865 ** 0 to 1.
4866 **
4867 ** Implementation notes as of 2024-08-31:
4868 **
4869 ** * The regular aggregate-function versions of these routines work
4870 ** by accumulating all values in an array of doubles, then sorting
4871 ** that array using quicksort before computing the answer. Thus
4872 ** the runtime is O(NlogN) where N is the number of rows of input.
4873 **
4874 ** * For the window-function versions of these routines, the array of
4875 ** inputs is sorted as soon as the first value is computed. Thereafter,
4876 ** the array is kept in sorted order using an insert-sort. This
4877 ** results in O(N*K) performance where K is the size of the window.
4878 ** One can imagine alternative implementations that give O(N*logN*logK)
4879 ** performance, but they require more complex logic and data structures.
4880 ** The developers have elected to keep the asymptotically slower
4881 ** algorithm for now, for simplicity, under the theory that window
4882 ** functions are seldom used and when they are, the window size K is
4883 ** often small. The developers might revisit that decision later,
4884 ** should the need arise.
4885 */
4886 #if defined(SQLITE3_H)
4887 /* no-op */
4888 #elif defined(SQLITE_STATIC_PERCENTILE)
4889 /* # include "sqlite3.h" */
4890 #else
4891 /* # include "sqlite3ext.h" */
4892 SQLITE_EXTENSION_INIT1
4893 #endif
4894 #include <assert.h>
4895 #include <string.h>
4896 #include <stdlib.h>
4897
4898 /* The following object is the group context for a single percentile()
4899 ** aggregate. Remember all input Y values until the very end.
4900 ** Those values are accumulated in the Percentile.a[] array.
4901 */
4902 typedef struct Percentile Percentile;
4903 struct Percentile {
4904 unsigned nAlloc; /* Number of slots allocated for a[] */
4905 unsigned nUsed; /* Number of slots actually used in a[] */
4906 char bSorted; /* True if a[] is already in sorted order */
4907 char bKeepSorted; /* True if advantageous to keep a[] sorted */
4908 char bPctValid; /* True if rPct is valid */
4909 double rPct; /* Fraction. 0.0 to 1.0 */
4910 double *a; /* Array of Y values */
4911 };
4912
4913 /* Details of each function in the percentile family */
4914 typedef struct PercentileFunc PercentileFunc;
4915 struct PercentileFunc {
4916 const char *zName; /* Function name */
4917 char nArg; /* Number of arguments */
4918 char mxFrac; /* Maximum value of the "fraction" input */
4919 char bDiscrete; /* True for percentile_disc() */
4920 };
4921 static const PercentileFunc aPercentFunc[] = {
4922 { "median", 1, 1, 0 },
4923 { "percentile", 2, 100, 0 },
4924 { "percentile_cont", 2, 1, 0 },
4925 { "percentile_disc", 2, 1, 1 },
4926 };
4927
4928 /*
4929 ** Return TRUE if the input floating-point number is an infinity.
4930 */
4931 static int percentIsInfinity(double r){
4932 sqlite3_uint64 u;
4933 assert( sizeof(u)==sizeof(r) );
4934 memcpy(&u, &r, sizeof(u));
4935 return ((u>>52)&0x7ff)==0x7ff;
4936 }
4937
4938 /*
4939 ** Return TRUE if two doubles differ by 0.001 or less.
4940 */
4941 static int percentSameValue(double a, double b){
4942 a -= b;
4943 return a>=-0.001 && a<=0.001;
4944 }
4945
4946 /*
4947 ** Search p (which must have p->bSorted) looking for an entry with
4948 ** value y. Return the index of that entry.
4949 **
4950 ** If bExact is true, return -1 if the entry is not found.
4951 **
4952 ** If bExact is false, return the index at which a new entry with
4953 ** value y should be insert in order to keep the values in sorted
4954 ** order. The smallest return value in this case will be 0, and
4955 ** the largest return value will be p->nUsed.
4956 */
4957 static int percentBinarySearch(Percentile *p, double y, int bExact){
4958 int iFirst = 0; /* First element of search range */
4959 int iLast = p->nUsed - 1; /* Last element of search range */
4960 while( iLast>=iFirst ){
4961 int iMid = (iFirst+iLast)/2;
4962 double x = p->a[iMid];
4963 if( x<y ){
4964 iFirst = iMid + 1;
4965 }else if( x>y ){
4966 iLast = iMid - 1;
4967 }else{
4968 return iMid;
4969 }
4970 }
4971 if( bExact ) return -1;
4972 return iFirst;
4973 }
4974
4975 /*
4976 ** Generate an error for a percentile function.
4977 **
4978 ** The error format string must have exactly one occurrance of "%%s()"
4979 ** (with two '%' characters). That substring will be replaced by the name
4980 ** of the function.
4981 */
4982 static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
4983 PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
4984 char *zMsg1;
4985 char *zMsg2;
4986 va_list ap;
4987
4988 va_start(ap, zFormat);
4989 zMsg1 = sqlite3_vmprintf(zFormat, ap);
4990 va_end(ap);
4991 zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0;
4992 sqlite3_result_error(pCtx, zMsg2, -1);
4993 sqlite3_free(zMsg1);
4994 sqlite3_free(zMsg2);
4995 }
4996
4997 /*
4998 ** The "step" function for percentile(Y,P) is called once for each
4999 ** input row.
5000 */
@@ -4790,45 +5005,38 @@
5005 double y;
5006 assert( argc==2 || argc==1 );
5007
5008 if( argc==1 ){
5009 /* Requirement 13: median(Y) is the same as percentile(Y,50). */
5010 rPct = 0.5;
5011 }else{
5012 /* Requirement 3: P must be a number between 0 and 100 */
5013 PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
5014 eType = sqlite3_value_numeric_type(argv[1]);
5015 rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac;
5016 if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
5017 || rPct<0.0 || rPct>1.0
5018 ){
5019 percentError(pCtx, "the fraction argument to %%s()"
5020 " is not between 0.0 and %.1f",
5021 (double)pFunc->mxFrac);
5022 return;
5023 }
 
 
 
 
 
 
 
 
5024 }
5025
5026 /* Allocate the session context. */
5027 p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
5028 if( p==0 ) return;
5029
5030 /* Remember the P value. Throw an error if the P value is different
5031 ** from any prior row, per Requirement (2). */
5032 if( !p->bPctValid ){
5033 p->rPct = rPct;
5034 p->bPctValid = 1;
5035 }else if( !percentSameValue(p->rPct,rPct) ){
5036 percentError(pCtx, "the fraction argument to %%s()"
5037 " is not the same for all input rows");
5038 return;
5039 }
5040
5041 /* Ignore rows for which Y is NULL */
5042 eType = sqlite3_value_type(argv[0]);
@@ -4835,19 +5043,18 @@
5043 if( eType==SQLITE_NULL ) return;
5044
5045 /* If not NULL, then Y must be numeric. Otherwise throw an error.
5046 ** Requirement 4 */
5047 if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
5048 percentError(pCtx, "input to %%s() is not numeric");
 
5049 return;
5050 }
5051
5052 /* Throw an error if the Y value is infinity or NaN */
5053 y = sqlite3_value_double(argv[0]);
5054 if( percentIsInfinity(y) ){
5055 percentError(pCtx, "Inf input to %%s()");
5056 return;
5057 }
5058
5059 /* Allocate and store the Y */
5060 if( p->nUsed>=p->nAlloc ){
@@ -4860,112 +5067,209 @@
5067 return;
5068 }
5069 p->nAlloc = n;
5070 p->a = a;
5071 }
5072 if( p->nUsed==0 ){
5073 p->a[p->nUsed++] = y;
5074 p->bSorted = 1;
5075 }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
5076 p->a[p->nUsed++] = y;
5077 }else if( p->bKeepSorted ){
5078 int i;
5079 i = percentBinarySearch(p, y, 0);
5080 if( i<p->nUsed ){
5081 memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
5082 }
5083 p->a[i] = y;
5084 p->nUsed++;
5085 }else{
5086 p->a[p->nUsed++] = y;
5087 p->bSorted = 0;
5088 }
5089 }
5090
5091 /*
5092 ** Interchange two doubles.
5093 */
5094 #define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
5095
5096 /*
5097 ** Sort an array of doubles.
5098 **
5099 ** Algorithm: quicksort
5100 **
5101 ** This is implemented separately rather than using the qsort() routine
5102 ** from the standard library because:
5103 **
5104 ** (1) To avoid a dependency on qsort()
5105 ** (2) To avoid the function call to the comparison routine for each
5106 ** comparison.
5107 */
5108 static void percentSort(double *a, unsigned int n){
5109 int iLt; /* Entries before a[iLt] are less than rPivot */
5110 int iGt; /* Entries at or after a[iGt] are greater than rPivot */
5111 int i; /* Loop counter */
5112 double rPivot; /* The pivot value */
5113
5114 assert( n>=2 );
5115 if( a[0]>a[n-1] ){
5116 SWAP_DOUBLE(a[0],a[n-1])
5117 }
5118 if( n==2 ) return;
5119 iGt = n-1;
5120 i = n/2;
5121 if( a[0]>a[i] ){
5122 SWAP_DOUBLE(a[0],a[i])
5123 }else if( a[i]>a[iGt] ){
5124 SWAP_DOUBLE(a[i],a[iGt])
5125 }
5126 if( n==3 ) return;
5127 rPivot = a[i];
5128 iLt = i = 1;
5129 do{
5130 if( a[i]<rPivot ){
5131 if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
 
 
 
 
5132 iLt++;
5133 i++;
5134 }else if( a[i]>rPivot ){
5135 do{
5136 iGt--;
5137 }while( iGt>i && a[iGt]>rPivot );
5138 SWAP_DOUBLE(a[i],a[iGt])
 
 
5139 }else{
5140 i++;
5141 }
5142 }while( i<iGt );
5143 if( iLt>=2 ) percentSort(a, iLt);
5144 if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
5145
5146 /* Uncomment for testing */
5147 #if 0
5148 for(i=0; i<n-1; i++){
5149 assert( a[i]<=a[i+1] );
5150 }
5151 #endif
5152 }
5153
5154
5155 /*
5156 ** The "inverse" function for percentile(Y,P) is called to remove a
5157 ** row that was previously inserted by "step".
5158 */
5159 static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
5160 Percentile *p;
5161 int eType;
5162 double y;
5163 int i;
5164 assert( argc==2 || argc==1 );
5165
5166 /* Allocate the session context. */
5167 p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
5168 assert( p!=0 );
5169
5170 /* Ignore rows for which Y is NULL */
5171 eType = sqlite3_value_type(argv[0]);
5172 if( eType==SQLITE_NULL ) return;
5173
5174 /* If not NULL, then Y must be numeric. Otherwise throw an error.
5175 ** Requirement 4 */
5176 if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
5177 return;
5178 }
5179
5180 /* Ignore the Y value if it is infinity or NaN */
5181 y = sqlite3_value_double(argv[0]);
5182 if( percentIsInfinity(y) ){
5183 return;
5184 }
5185 if( p->bSorted==0 ){
5186 assert( p->nUsed>1 );
5187 percentSort(p->a, p->nUsed);
5188 p->bSorted = 1;
5189 }
5190 p->bKeepSorted = 1;
5191
5192 /* Find and remove the row */
5193 i = percentBinarySearch(p, y, 1);
5194 if( i>=0 ){
5195 p->nUsed--;
5196 if( i<p->nUsed ){
5197 memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
5198 }
5199 }
5200 }
5201
5202 /*
5203 ** Compute the final output of percentile(). Clean up all allocated
5204 ** memory if and only if bIsFinal is true.
5205 */
5206 static void percentCompute(sqlite3_context *pCtx, int bIsFinal){
5207 Percentile *p;
5208 PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
5209 unsigned i1, i2;
5210 double v1, v2;
5211 double ix, vx;
5212 p = (Percentile*)sqlite3_aggregate_context(pCtx, 0);
5213 if( p==0 ) return;
5214 if( p->a==0 ) return;
5215 if( p->nUsed ){
5216 if( p->bSorted==0 ){
5217 assert( p->nUsed>1 );
5218 percentSort(p->a, p->nUsed);
5219 p->bSorted = 1;
5220 }
5221 ix = p->rPct*(p->nUsed-1);
5222 i1 = (unsigned)ix;
5223 if( pFunc->bDiscrete ){
5224 vx = p->a[i1];
5225 }else{
5226 i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
5227 v1 = p->a[i1];
5228 v2 = p->a[i2];
5229 vx = v1 + (v2-v1)*(ix-i1);
5230 }
5231 sqlite3_result_double(pCtx, vx);
5232 }
5233 if( bIsFinal ){
5234 sqlite3_free(p->a);
5235 memset(p, 0, sizeof(*p));
5236 }else{
5237 p->bKeepSorted = 1;
5238 }
5239 }
5240 static void percentFinal(sqlite3_context *pCtx){
5241 percentCompute(pCtx, 1);
5242 }
5243 static void percentValue(sqlite3_context *pCtx){
5244 percentCompute(pCtx, 0);
5245 }
5246
5247 #if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE)
 
5248
5249 #endif
5250 int sqlite3_percentile_init(
5251 sqlite3 *db,
5252 char **pzErrMsg,
5253 const sqlite3_api_routines *pApi
5254 ){
5255 int rc = SQLITE_OK;
5256 int i;
5257 #if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
5258 (void)pApi; /* Unused parameter */
5259 #else
5260 SQLITE_EXTENSION_INIT2(pApi);
5261 #endif
5262 (void)pzErrMsg; /* Unused parameter */
5263 for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){
5264 rc = sqlite3_create_window_function(db,
5265 aPercentFunc[i].zName,
5266 aPercentFunc[i].nArg,
5267 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1,
5268 (void*)&aPercentFunc[i],
5269 percentStep, percentFinal, percentValue, percentInverse, 0);
5270 if( rc ) break;
 
 
 
 
5271 }
5272 return rc;
5273 }
5274
5275 /************************* End ../ext/misc/percentile.c ********************/
@@ -22375,14 +22679,15 @@
22679 sqlite3_bind_double(pStmt, i, INFINITY);
22680 #endif
22681 }else if( strncmp(zVar, "$int_", 5)==0 ){
22682 sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
22683 }else if( strncmp(zVar, "$text_", 6)==0 ){
22684 size_t szVar = strlen(zVar);
22685 char *zBuf = sqlite3_malloc64( szVar-5 );
22686 if( zBuf ){
22687 memcpy(zBuf, &zVar[6], szVar-5);
22688 sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
22689 }
22690 }else{
22691 sqlite3_bind_null(pStmt, i);
22692 }
22693 sqlite3_reset(pQ);
@@ -29871,11 +30176,11 @@
30176 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt);
30177 newOpt = curOpt;
30178 for(ii=2; ii<nArg; ii++){
30179 const char *z = azArg[ii];
30180 int useLabel = 0;
30181 const char *zLabel = 0;
30182 if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
30183 useLabel = z[0];
30184 zLabel = &z[1];
30185 }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){
30186 useLabel = '+';
@@ -29888,15 +30193,15 @@
30193 for(jj=0; jj<ArraySize(aLabel); jj++){
30194 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break;
30195 }
30196 if( jj>=ArraySize(aLabel) ){
30197 eputf("Error: no such optimization: \"%s\"\n", zLabel);
30198 eputz("Should be one of:");
30199 for(jj=0; jj<ArraySize(aLabel); jj++){
30200 eputf(" %s", aLabel[jj].zLabel);
30201 }
30202 eputz("\n");
30203 rc = 1;
30204 goto meta_command_exit;
30205 }
30206 if( useLabel=='+' ){
30207 newOpt &= ~aLabel[jj].mask;
@@ -29909,13 +30214,13 @@
30214 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt);
30215 }else if( nArg<3 ){
30216 curOpt = ~newOpt;
30217 }
30218 if( newOpt==0 ){
30219 oputz("+All\n");
30220 }else if( newOpt==0xffffffff ){
30221 oputz("-All\n");
30222 }else{
30223 int jj;
30224 for(jj=0; jj<ArraySize(aLabel); jj++){
30225 unsigned int m = aLabel[jj].mask;
30226 if( !aLabel[jj].bDsply ) continue;
30227
+84 -50
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,13 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 9a9d0f6301faefe324261f03543023ffb6a9 with changes in files:
22
-**
23
-** src/shell.c.in
21
+** 7891a266c4425722ae8b9231397ef9e42e24.
2422
*/
2523
#define SQLITE_CORE 1
2624
#define SQLITE_AMALGAMATION 1
2725
#ifndef SQLITE_PRIVATE
2826
# define SQLITE_PRIVATE static
@@ -464,11 +462,11 @@
464462
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
465463
** [sqlite_version()] and [sqlite_source_id()].
466464
*/
467465
#define SQLITE_VERSION "3.47.0"
468466
#define SQLITE_VERSION_NUMBER 3047000
469
-#define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
467
+#define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
470468
471469
/*
472470
** CAPI3REF: Run-Time Library Version Numbers
473471
** KEYWORDS: sqlite3_version sqlite3_sourceid
474472
**
@@ -5931,18 +5929,28 @@
59315929
** might become a no-op if the function is used as term in an
59325930
** [expression index]. On the other hand, SQL functions that never invoke
59335931
** [sqlite3_result_subtype()] should avoid setting this property, as the
59345932
** purpose of this property is to disable certain optimizations that are
59355933
** incompatible with subtypes.
5934
+**
5935
+** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
5936
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
5937
+** that internally orders the values provided to the first argument. The
5938
+** ordered-set aggregate SQL notation with a single ORDER BY term can be
5939
+** used to invoke this function. If the ordered-set aggregate notation is
5940
+** used on a function that lacks this flag, then an error is raised. Note
5941
+** that the ordered-set aggregate syntax is only available if SQLite is
5942
+** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
59365943
** </dd>
59375944
** </dl>
59385945
*/
59395946
#define SQLITE_DETERMINISTIC 0x000000800
59405947
#define SQLITE_DIRECTONLY 0x000080000
59415948
#define SQLITE_SUBTYPE 0x000100000
59425949
#define SQLITE_INNOCUOUS 0x000200000
59435950
#define SQLITE_RESULT_SUBTYPE 0x001000000
5951
+#define SQLITE_SELFORDER1 0x002000000
59445952
59455953
/*
59465954
** CAPI3REF: Deprecated Functions
59475955
** DEPRECATED
59485956
**
@@ -13610,22 +13618,23 @@
1361013618
** an nLocale byte buffer containing the name of the locale to use as utf-8
1361113619
** text. pLocale is not nul-terminated.
1361213620
**
1361313621
** FTS5_TOKENIZER
1361413622
**
13615
-** There is also an fts5_tokenizer object. This is an older version of
13616
-** fts5_tokenizer_v2. It is similar except that:
13623
+** There is also an fts5_tokenizer object. This is an older, deprecated,
13624
+** version of fts5_tokenizer_v2. It is similar except that:
1361713625
**
1361813626
** <ul>
1361913627
** <li> There is no "iVersion" field, and
1362013628
** <li> The xTokenize() method does not take a locale argument.
1362113629
** </ul>
1362213630
**
13623
-** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13624
-** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13625
-** registered using either API may be retrieved using both xFindTokenizer()
13626
-** and xFindTokenizer_v2().
13631
+** Legacy fts5_tokenizer tokenizers must be registered using the
13632
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
13633
+**
13634
+** Tokenizer implementations registered using either API may be retrieved
13635
+** using both xFindTokenizer() and xFindTokenizer_v2().
1362713636
**
1362813637
** SYNONYM SUPPORT
1362913638
**
1363013639
** Custom tokenizers may also support synonyms. Consider a case in which a
1363113640
** user wishes to query for a phrase such as "first place". Using the
@@ -14820,10 +14829,12 @@
1482014829
** substitute integer for floating-point
1482114830
*/
1482214831
#ifdef SQLITE_OMIT_FLOATING_POINT
1482314832
# define double sqlite_int64
1482414833
# define float sqlite_int64
14834
+# define fabs(X) ((X)<0?-(X):(X))
14835
+# define sqlite3IsOverflow(X) 0
1482514836
# define LONGDOUBLE_TYPE sqlite_int64
1482614837
# ifndef SQLITE_BIG_DBL
1482714838
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
1482814839
# endif
1482914840
# define SQLITE_OMIT_DATETIME_FUNCS 1
@@ -22355,10 +22366,13 @@
2235522366
#ifdef SQLITE_ENABLE_NULL_TRIM
2235622367
"ENABLE_NULL_TRIM",
2235722368
#endif
2235822369
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
2235922370
"ENABLE_OFFSET_SQL_FUNC",
22371
+#endif
22372
+#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
22373
+ "ENABLE_ORDERED_SET_AGGREGATES",
2236022374
#endif
2236122375
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
2236222376
"ENABLE_OVERSIZE_CELL_CHECK",
2236322377
#endif
2236422378
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -76734,11 +76748,11 @@
7673476748
}
7673576749
if( pCur->iPage>0
7673676750
&& indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
7673776751
&& pIdxKey->errCode==SQLITE_OK
7673876752
){
76739
- pCur->curFlags &= ~BTCF_ValidOvfl;
76753
+ pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
7674076754
if( !pCur->pPage->isInit ){
7674176755
return SQLITE_CORRUPT_BKPT;
7674276756
}
7674376757
goto bypass_moveto_root; /* Start search on the current page */
7674476758
}
@@ -102708,10 +102722,15 @@
102708102722
}
102709102723
if( pTab && !HasRowid(pTab) ){
102710102724
pTab = 0;
102711102725
sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
102712102726
}
102727
+ if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){
102728
+ pTab = 0;
102729
+ sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s",
102730
+ zTable);
102731
+ }
102713102732
#ifndef SQLITE_OMIT_VIEW
102714102733
if( pTab && IsView(pTab) ){
102715102734
pTab = 0;
102716102735
sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
102717102736
}
@@ -108285,13 +108304,13 @@
108285108304
assert( pExpr->pLeft->op==TK_ORDER );
108286108305
assert( ExprUseXList(pExpr->pLeft) );
108287108306
sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList);
108288108307
}
108289108308
#ifndef SQLITE_OMIT_WINDOWFUNC
108290
- if( pWin ){
108309
+ if( pWin && pParse->nErr==0 ){
108291108310
Select *pSel = pNC->pWinSelect;
108292
- assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
108311
+ assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin );
108293108312
if( IN_RENAME_OBJECT==0 ){
108294108313
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
108295108314
if( pParse->db->mallocFailed ) break;
108296108315
}
108297108316
sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -131211,11 +131230,15 @@
131211131230
131212131231
/*
131213131232
** group_concat(EXPR, ?SEPARATOR?)
131214131233
** string_agg(EXPR, SEPARATOR)
131215131234
**
131216
-** The SEPARATOR goes before the EXPR string. This is tragic. The
131235
+** Content is accumulated in GroupConcatCtx.str with the SEPARATOR
131236
+** coming before the EXPR value, except for the first entry which
131237
+** omits the SEPARATOR.
131238
+**
131239
+** It is tragic that the SEPARATOR goes before the EXPR string. The
131217131240
** groupConcatInverse() implementation would have been easier if the
131218131241
** SEPARATOR were appended after EXPR. And the order is undocumented,
131219131242
** so we could change it, in theory. But the old behavior has been
131220131243
** around for so long that we dare not, for fear of breaking something.
131221131244
*/
@@ -131315,11 +131338,11 @@
131315131338
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
131316131339
pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
131317131340
/* pGCC is always non-NULL since groupConcatStep() will have always
131318131341
** run first to initialize it */
131319131342
if( ALWAYS(pGCC) ){
131320
- int nVS;
131343
+ int nVS; /* Number of characters to remove */
131321131344
/* Must call sqlite3_value_text() to convert the argument into text prior
131322131345
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
131323131346
(void)sqlite3_value_text(argv[0]);
131324131347
nVS = sqlite3_value_bytes(argv[0]);
131325131348
pGCC->nAccum -= 1;
@@ -155831,10 +155854,13 @@
155831155854
int nRes; /* Bytes of reserved space at the end of each page */
155832155855
int nDb; /* Number of attached databases */
155833155856
const char *zDbMain; /* Schema name of database to vacuum */
155834155857
const char *zOut; /* Name of output file */
155835155858
u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
155859
+ u64 iRandom; /* Random value used for zDbVacuum[] */
155860
+ char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */
155861
+
155836155862
155837155863
if( !db->autoCommit ){
155838155864
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
155839155865
return SQLITE_ERROR; /* IMP: R-12218-18073 */
155840155866
}
@@ -155871,31 +155897,33 @@
155871155897
155872155898
zDbMain = db->aDb[iDb].zDbSName;
155873155899
pMain = db->aDb[iDb].pBt;
155874155900
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
155875155901
155876
- /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
155902
+ /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma
155877155903
** can be set to 'off' for this file, as it is not recovered if a crash
155878155904
** occurs anyway. The integrity of the database is maintained by a
155879155905
** (possibly synchronous) transaction opened on the main database before
155880155906
** sqlite3BtreeCopyFile() is called.
155881155907
**
155882155908
** An optimization would be to use a non-journaled pager.
155883
- ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
155909
+ ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but
155884155910
** that actually made the VACUUM run slower. Very little journalling
155885155911
** actually occurs when doing a vacuum since the vacuum_db is initially
155886155912
** empty. Only the journal header is written. Apparently it takes more
155887155913
** time to parse and run the PRAGMA to turn journalling off than it does
155888155914
** to write the journal header file.
155889155915
*/
155916
+ sqlite3_randomness(sizeof(iRandom),&iRandom);
155917
+ sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom);
155890155918
nDb = db->nDb;
155891
- rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
155919
+ rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum);
155892155920
db->openFlags = saved_openFlags;
155893155921
if( rc!=SQLITE_OK ) goto end_of_vacuum;
155894155922
assert( (db->nDb-1)==nDb );
155895155923
pDb = &db->aDb[nDb];
155896
- assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
155924
+ assert( strcmp(pDb->zDbSName,zDbVacuum)==0 );
155897155925
pTemp = pDb->pBt;
155898155926
if( pOut ){
155899155927
sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
155900155928
i64 sz = 0;
155901155929
if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
@@ -155968,15 +155996,15 @@
155968155996
/* Loop through the tables in the main database. For each, do
155969155997
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
155970155998
** the contents to the temporary database.
155971155999
*/
155972156000
rc = execSqlF(db, pzErrMsg,
155973
- "SELECT'INSERT INTO vacuum_db.'||quote(name)"
156001
+ "SELECT'INSERT INTO %s.'||quote(name)"
155974156002
"||' SELECT*FROM\"%w\".'||quote(name)"
155975
- "FROM vacuum_db.sqlite_schema "
156003
+ "FROM %s.sqlite_schema "
155976156004
"WHERE type='table'AND coalesce(rootpage,1)>0",
155977
- zDbMain
156005
+ zDbVacuum, zDbMain, zDbVacuum
155978156006
);
155979156007
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
155980156008
db->mDbFlags &= ~DBFLAG_Vacuum;
155981156009
if( rc!=SQLITE_OK ) goto end_of_vacuum;
155982156010
@@ -155984,15 +156012,15 @@
155984156012
** over to the temporary database. None of these objects has any
155985156013
** associated storage, so all we have to do is copy their entries
155986156014
** from the schema table.
155987156015
*/
155988156016
rc = execSqlF(db, pzErrMsg,
155989
- "INSERT INTO vacuum_db.sqlite_schema"
156017
+ "INSERT INTO %s.sqlite_schema"
155990156018
" SELECT*FROM \"%w\".sqlite_schema"
155991156019
" WHERE type IN('view','trigger')"
155992156020
" OR(type='table'AND rootpage=0)",
155993
- zDbMain
156021
+ zDbVacuum, zDbMain
155994156022
);
155995156023
if( rc ) goto end_of_vacuum;
155996156024
155997156025
/* At this point, there is a write transaction open on both the
155998156026
** vacuum database and the main database. Assuming no error occurs,
@@ -166900,10 +166928,11 @@
166900166928
pNew->iSortIdx = 0;
166901166929
pNew->rSetup = 0;
166902166930
pNew->prereq = mPrereq;
166903166931
pNew->nOut = rSize;
166904166932
pNew->u.btree.pIndex = pProbe;
166933
+ pNew->u.btree.pOrderBy = 0;
166905166934
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
166906166935
166907166936
/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
166908166937
assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
166909166938
if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
@@ -182810,11 +182839,12 @@
182810182839
}
182811182840
182812182841
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
182813182842
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
182814182843
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
182815
- SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
182844
+ SQLITE_SUBTYPE|SQLITE_INNOCUOUS|
182845
+ SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1);
182816182846
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
182817182847
182818182848
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
182819182849
** the meaning is inverted. So flip the bit. */
182820182850
assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
@@ -233058,22 +233088,23 @@
233058233088
** an nLocale byte buffer containing the name of the locale to use as utf-8
233059233089
** text. pLocale is not nul-terminated.
233060233090
**
233061233091
** FTS5_TOKENIZER
233062233092
**
233063
-** There is also an fts5_tokenizer object. This is an older version of
233064
-** fts5_tokenizer_v2. It is similar except that:
233093
+** There is also an fts5_tokenizer object. This is an older, deprecated,
233094
+** version of fts5_tokenizer_v2. It is similar except that:
233065233095
**
233066233096
** <ul>
233067233097
** <li> There is no "iVersion" field, and
233068233098
** <li> The xTokenize() method does not take a locale argument.
233069233099
** </ul>
233070233100
**
233071
-** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
233072
-** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
233073
-** registered using either API may be retrieved using both xFindTokenizer()
233074
-** and xFindTokenizer_v2().
233101
+** Legacy fts5_tokenizer tokenizers must be registered using the
233102
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
233103
+**
233104
+** Tokenizer implementations registered using either API may be retrieved
233105
+** using both xFindTokenizer() and xFindTokenizer_v2().
233075233106
**
233076233107
** SYNONYM SUPPORT
233077233108
**
233078233109
** Custom tokenizers may also support synonyms. Consider a case in which a
233079233110
** user wishes to query for a phrase such as "first place". Using the
@@ -244112,11 +244143,11 @@
244112244143
iOff = 4;
244113244144
}
244114244145
244115244146
if( iOff<pIter->iEndofDoclist ){
244116244147
/* Next entry is on the current page */
244117
- i64 iDelta;
244148
+ u64 iDelta;
244118244149
iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
244119244150
pIter->iLeafOffset = iOff;
244120244151
pIter->iRowid += iDelta;
244121244152
}else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
244122244153
if( pIter->pSeg ){
@@ -251426,12 +251457,11 @@
251426251457
rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
251427251458
}
251428251459
251429251460
/* Load the initial configuration */
251430251461
if( rc==SQLITE_OK ){
251431
- rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
251432
- sqlite3Fts5IndexRollback(pTab->p.pIndex);
251462
+ rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
251433251463
}
251434251464
251435251465
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
251436251466
rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1);
251437251467
}
@@ -253067,13 +253097,15 @@
253067253097
253068253098
/*
253069253099
** Implementation of xBegin() method.
253070253100
*/
253071253101
static int fts5BeginMethod(sqlite3_vtab *pVtab){
253072
- fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
253073
- fts5NewTransaction((Fts5FullTable*)pVtab);
253074
- return SQLITE_OK;
253102
+ int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
253103
+ if( rc==SQLITE_OK ){
253104
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
253105
+ }
253106
+ return rc;
253075253107
}
253076253108
253077253109
/*
253078253110
** Implementation of xCommit() method. This is a no-op. The contents of
253079253111
** the pending-terms hash-table have already been flushed into the database
@@ -254266,11 +254298,13 @@
254266254298
** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
254267254299
** via the fts5_tokenizer API.
254268254300
*/
254269254301
typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
254270254302
struct Fts5VtoVTokenizer {
254271
- Fts5TokenizerModule *pMod;
254303
+ int bV2Native; /* True if v2 native tokenizer */
254304
+ fts5_tokenizer x1; /* Tokenizer functions */
254305
+ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
254272254306
Fts5Tokenizer *pReal;
254273254307
};
254274254308
254275254309
/*
254276254310
** Create a wrapper tokenizer. The context argument pCtx points to the
@@ -254286,11 +254320,13 @@
254286254320
Fts5VtoVTokenizer *pNew = 0;
254287254321
int rc = SQLITE_OK;
254288254322
254289254323
pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
254290254324
if( rc==SQLITE_OK ){
254291
- pNew->pMod = pMod;
254325
+ pNew->x1 = pMod->x1;
254326
+ pNew->x2 = pMod->x2;
254327
+ pNew->bV2Native = pMod->bV2Native;
254292254328
if( pMod->bV2Native ){
254293254329
rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254294254330
}else{
254295254331
rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254296254332
}
@@ -254308,15 +254344,14 @@
254308254344
** Delete an Fts5VtoVTokenizer wrapper tokenizer.
254309254345
*/
254310254346
static void fts5VtoVDelete(Fts5Tokenizer *pTok){
254311254347
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254312254348
if( p ){
254313
- Fts5TokenizerModule *pMod = p->pMod;
254314
- if( pMod->bV2Native ){
254315
- pMod->x2.xDelete(p->pReal);
254349
+ if( p->bV2Native ){
254350
+ p->x2.xDelete(p->pReal);
254316254351
}else{
254317
- pMod->x1.xDelete(p->pReal);
254352
+ p->x1.xDelete(p->pReal);
254318254353
}
254319254354
sqlite3_free(p);
254320254355
}
254321254356
}
254322254357
@@ -254330,13 +254365,12 @@
254330254365
void *pCtx, int flags,
254331254366
const char *pText, int nText,
254332254367
int (*xToken)(void*, int, const char*, int, int, int)
254333254368
){
254334254369
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254335
- Fts5TokenizerModule *pMod = p->pMod;
254336
- assert( pMod->bV2Native );
254337
- return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
254370
+ assert( p->bV2Native );
254371
+ return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
254338254372
}
254339254373
254340254374
/*
254341254375
** xTokenizer method for a wrapper tokenizer that offers the v2 interface
254342254376
** (with locale support).
@@ -254347,13 +254381,13 @@
254347254381
const char *pText, int nText,
254348254382
const char *pLocale, int nLocale,
254349254383
int (*xToken)(void*, int, const char*, int, int, int)
254350254384
){
254351254385
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254352
- Fts5TokenizerModule *pMod = p->pMod;
254353
- assert( pMod->bV2Native==0 );
254354
- return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254386
+ assert( p->bV2Native==0 );
254387
+ UNUSED_PARAM2(pLocale,nLocale);
254388
+ return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254355254389
}
254356254390
254357254391
/*
254358254392
** Register a new tokenizer. This is the implementation of the
254359254393
** fts5_api.xCreateTokenizer_v2() method.
@@ -254591,11 +254625,11 @@
254591254625
int nArg, /* Number of args */
254592254626
sqlite3_value **apUnused /* Function arguments */
254593254627
){
254594254628
assert( nArg==0 );
254595254629
UNUSED_PARAM2(nArg, apUnused);
254596
- sqlite3_result_text(pCtx, "fts5: 2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b31f96", -1, SQLITE_TRANSIENT);
254630
+ sqlite3_result_text(pCtx, "fts5: 2024-09-02 18:41:59 e6bec37ea1ca51e1d048941ce4c5211d8fc5c5e3556a1441f9c79b036843f9e3", -1, SQLITE_TRANSIENT);
254597254631
}
254598254632
254599254633
/*
254600254634
** Implementation of fts5_locale(LOCALE, TEXT) function.
254601254635
**
254602254636
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,13 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 9a9d0f6301faefe324261f03543023ffb6a9 with changes in files:
22 **
23 ** src/shell.c.in
24 */
25 #define SQLITE_CORE 1
26 #define SQLITE_AMALGAMATION 1
27 #ifndef SQLITE_PRIVATE
28 # define SQLITE_PRIVATE static
@@ -464,11 +462,11 @@
464 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
465 ** [sqlite_version()] and [sqlite_source_id()].
466 */
467 #define SQLITE_VERSION "3.47.0"
468 #define SQLITE_VERSION_NUMBER 3047000
469 #define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
470
471 /*
472 ** CAPI3REF: Run-Time Library Version Numbers
473 ** KEYWORDS: sqlite3_version sqlite3_sourceid
474 **
@@ -5931,18 +5929,28 @@
5931 ** might become a no-op if the function is used as term in an
5932 ** [expression index]. On the other hand, SQL functions that never invoke
5933 ** [sqlite3_result_subtype()] should avoid setting this property, as the
5934 ** purpose of this property is to disable certain optimizations that are
5935 ** incompatible with subtypes.
 
 
 
 
 
 
 
 
 
5936 ** </dd>
5937 ** </dl>
5938 */
5939 #define SQLITE_DETERMINISTIC 0x000000800
5940 #define SQLITE_DIRECTONLY 0x000080000
5941 #define SQLITE_SUBTYPE 0x000100000
5942 #define SQLITE_INNOCUOUS 0x000200000
5943 #define SQLITE_RESULT_SUBTYPE 0x001000000
 
5944
5945 /*
5946 ** CAPI3REF: Deprecated Functions
5947 ** DEPRECATED
5948 **
@@ -13610,22 +13618,23 @@
13610 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13611 ** text. pLocale is not nul-terminated.
13612 **
13613 ** FTS5_TOKENIZER
13614 **
13615 ** There is also an fts5_tokenizer object. This is an older version of
13616 ** fts5_tokenizer_v2. It is similar except that:
13617 **
13618 ** <ul>
13619 ** <li> There is no "iVersion" field, and
13620 ** <li> The xTokenize() method does not take a locale argument.
13621 ** </ul>
13622 **
13623 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13624 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13625 ** registered using either API may be retrieved using both xFindTokenizer()
13626 ** and xFindTokenizer_v2().
 
13627 **
13628 ** SYNONYM SUPPORT
13629 **
13630 ** Custom tokenizers may also support synonyms. Consider a case in which a
13631 ** user wishes to query for a phrase such as "first place". Using the
@@ -14820,10 +14829,12 @@
14820 ** substitute integer for floating-point
14821 */
14822 #ifdef SQLITE_OMIT_FLOATING_POINT
14823 # define double sqlite_int64
14824 # define float sqlite_int64
 
 
14825 # define LONGDOUBLE_TYPE sqlite_int64
14826 # ifndef SQLITE_BIG_DBL
14827 # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
14828 # endif
14829 # define SQLITE_OMIT_DATETIME_FUNCS 1
@@ -22355,10 +22366,13 @@
22355 #ifdef SQLITE_ENABLE_NULL_TRIM
22356 "ENABLE_NULL_TRIM",
22357 #endif
22358 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
22359 "ENABLE_OFFSET_SQL_FUNC",
 
 
 
22360 #endif
22361 #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
22362 "ENABLE_OVERSIZE_CELL_CHECK",
22363 #endif
22364 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -76734,11 +76748,11 @@
76734 }
76735 if( pCur->iPage>0
76736 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
76737 && pIdxKey->errCode==SQLITE_OK
76738 ){
76739 pCur->curFlags &= ~BTCF_ValidOvfl;
76740 if( !pCur->pPage->isInit ){
76741 return SQLITE_CORRUPT_BKPT;
76742 }
76743 goto bypass_moveto_root; /* Start search on the current page */
76744 }
@@ -102708,10 +102722,15 @@
102708 }
102709 if( pTab && !HasRowid(pTab) ){
102710 pTab = 0;
102711 sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
102712 }
 
 
 
 
 
102713 #ifndef SQLITE_OMIT_VIEW
102714 if( pTab && IsView(pTab) ){
102715 pTab = 0;
102716 sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
102717 }
@@ -108285,13 +108304,13 @@
108285 assert( pExpr->pLeft->op==TK_ORDER );
108286 assert( ExprUseXList(pExpr->pLeft) );
108287 sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList);
108288 }
108289 #ifndef SQLITE_OMIT_WINDOWFUNC
108290 if( pWin ){
108291 Select *pSel = pNC->pWinSelect;
108292 assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
108293 if( IN_RENAME_OBJECT==0 ){
108294 sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
108295 if( pParse->db->mallocFailed ) break;
108296 }
108297 sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -131211,11 +131230,15 @@
131211
131212 /*
131213 ** group_concat(EXPR, ?SEPARATOR?)
131214 ** string_agg(EXPR, SEPARATOR)
131215 **
131216 ** The SEPARATOR goes before the EXPR string. This is tragic. The
 
 
 
 
131217 ** groupConcatInverse() implementation would have been easier if the
131218 ** SEPARATOR were appended after EXPR. And the order is undocumented,
131219 ** so we could change it, in theory. But the old behavior has been
131220 ** around for so long that we dare not, for fear of breaking something.
131221 */
@@ -131315,11 +131338,11 @@
131315 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
131316 pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
131317 /* pGCC is always non-NULL since groupConcatStep() will have always
131318 ** run first to initialize it */
131319 if( ALWAYS(pGCC) ){
131320 int nVS;
131321 /* Must call sqlite3_value_text() to convert the argument into text prior
131322 ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
131323 (void)sqlite3_value_text(argv[0]);
131324 nVS = sqlite3_value_bytes(argv[0]);
131325 pGCC->nAccum -= 1;
@@ -155831,10 +155854,13 @@
155831 int nRes; /* Bytes of reserved space at the end of each page */
155832 int nDb; /* Number of attached databases */
155833 const char *zDbMain; /* Schema name of database to vacuum */
155834 const char *zOut; /* Name of output file */
155835 u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
 
 
 
155836
155837 if( !db->autoCommit ){
155838 sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
155839 return SQLITE_ERROR; /* IMP: R-12218-18073 */
155840 }
@@ -155871,31 +155897,33 @@
155871
155872 zDbMain = db->aDb[iDb].zDbSName;
155873 pMain = db->aDb[iDb].pBt;
155874 isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
155875
155876 /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
155877 ** can be set to 'off' for this file, as it is not recovered if a crash
155878 ** occurs anyway. The integrity of the database is maintained by a
155879 ** (possibly synchronous) transaction opened on the main database before
155880 ** sqlite3BtreeCopyFile() is called.
155881 **
155882 ** An optimization would be to use a non-journaled pager.
155883 ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
155884 ** that actually made the VACUUM run slower. Very little journalling
155885 ** actually occurs when doing a vacuum since the vacuum_db is initially
155886 ** empty. Only the journal header is written. Apparently it takes more
155887 ** time to parse and run the PRAGMA to turn journalling off than it does
155888 ** to write the journal header file.
155889 */
 
 
155890 nDb = db->nDb;
155891 rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
155892 db->openFlags = saved_openFlags;
155893 if( rc!=SQLITE_OK ) goto end_of_vacuum;
155894 assert( (db->nDb-1)==nDb );
155895 pDb = &db->aDb[nDb];
155896 assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
155897 pTemp = pDb->pBt;
155898 if( pOut ){
155899 sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
155900 i64 sz = 0;
155901 if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
@@ -155968,15 +155996,15 @@
155968 /* Loop through the tables in the main database. For each, do
155969 ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
155970 ** the contents to the temporary database.
155971 */
155972 rc = execSqlF(db, pzErrMsg,
155973 "SELECT'INSERT INTO vacuum_db.'||quote(name)"
155974 "||' SELECT*FROM\"%w\".'||quote(name)"
155975 "FROM vacuum_db.sqlite_schema "
155976 "WHERE type='table'AND coalesce(rootpage,1)>0",
155977 zDbMain
155978 );
155979 assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
155980 db->mDbFlags &= ~DBFLAG_Vacuum;
155981 if( rc!=SQLITE_OK ) goto end_of_vacuum;
155982
@@ -155984,15 +156012,15 @@
155984 ** over to the temporary database. None of these objects has any
155985 ** associated storage, so all we have to do is copy their entries
155986 ** from the schema table.
155987 */
155988 rc = execSqlF(db, pzErrMsg,
155989 "INSERT INTO vacuum_db.sqlite_schema"
155990 " SELECT*FROM \"%w\".sqlite_schema"
155991 " WHERE type IN('view','trigger')"
155992 " OR(type='table'AND rootpage=0)",
155993 zDbMain
155994 );
155995 if( rc ) goto end_of_vacuum;
155996
155997 /* At this point, there is a write transaction open on both the
155998 ** vacuum database and the main database. Assuming no error occurs,
@@ -166900,10 +166928,11 @@
166900 pNew->iSortIdx = 0;
166901 pNew->rSetup = 0;
166902 pNew->prereq = mPrereq;
166903 pNew->nOut = rSize;
166904 pNew->u.btree.pIndex = pProbe;
 
166905 b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
166906
166907 /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
166908 assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
166909 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
@@ -182810,11 +182839,12 @@
182810 }
182811
182812 assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
182813 assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
182814 extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
182815 SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
 
182816 enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
182817
182818 /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
182819 ** the meaning is inverted. So flip the bit. */
182820 assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
@@ -233058,22 +233088,23 @@
233058 ** an nLocale byte buffer containing the name of the locale to use as utf-8
233059 ** text. pLocale is not nul-terminated.
233060 **
233061 ** FTS5_TOKENIZER
233062 **
233063 ** There is also an fts5_tokenizer object. This is an older version of
233064 ** fts5_tokenizer_v2. It is similar except that:
233065 **
233066 ** <ul>
233067 ** <li> There is no "iVersion" field, and
233068 ** <li> The xTokenize() method does not take a locale argument.
233069 ** </ul>
233070 **
233071 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
233072 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
233073 ** registered using either API may be retrieved using both xFindTokenizer()
233074 ** and xFindTokenizer_v2().
 
233075 **
233076 ** SYNONYM SUPPORT
233077 **
233078 ** Custom tokenizers may also support synonyms. Consider a case in which a
233079 ** user wishes to query for a phrase such as "first place". Using the
@@ -244112,11 +244143,11 @@
244112 iOff = 4;
244113 }
244114
244115 if( iOff<pIter->iEndofDoclist ){
244116 /* Next entry is on the current page */
244117 i64 iDelta;
244118 iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
244119 pIter->iLeafOffset = iOff;
244120 pIter->iRowid += iDelta;
244121 }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
244122 if( pIter->pSeg ){
@@ -251426,12 +251457,11 @@
251426 rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
251427 }
251428
251429 /* Load the initial configuration */
251430 if( rc==SQLITE_OK ){
251431 rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
251432 sqlite3Fts5IndexRollback(pTab->p.pIndex);
251433 }
251434
251435 if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
251436 rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1);
251437 }
@@ -253067,13 +253097,15 @@
253067
253068 /*
253069 ** Implementation of xBegin() method.
253070 */
253071 static int fts5BeginMethod(sqlite3_vtab *pVtab){
253072 fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
253073 fts5NewTransaction((Fts5FullTable*)pVtab);
253074 return SQLITE_OK;
 
 
253075 }
253076
253077 /*
253078 ** Implementation of xCommit() method. This is a no-op. The contents of
253079 ** the pending-terms hash-table have already been flushed into the database
@@ -254266,11 +254298,13 @@
254266 ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
254267 ** via the fts5_tokenizer API.
254268 */
254269 typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
254270 struct Fts5VtoVTokenizer {
254271 Fts5TokenizerModule *pMod;
 
 
254272 Fts5Tokenizer *pReal;
254273 };
254274
254275 /*
254276 ** Create a wrapper tokenizer. The context argument pCtx points to the
@@ -254286,11 +254320,13 @@
254286 Fts5VtoVTokenizer *pNew = 0;
254287 int rc = SQLITE_OK;
254288
254289 pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
254290 if( rc==SQLITE_OK ){
254291 pNew->pMod = pMod;
 
 
254292 if( pMod->bV2Native ){
254293 rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254294 }else{
254295 rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254296 }
@@ -254308,15 +254344,14 @@
254308 ** Delete an Fts5VtoVTokenizer wrapper tokenizer.
254309 */
254310 static void fts5VtoVDelete(Fts5Tokenizer *pTok){
254311 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254312 if( p ){
254313 Fts5TokenizerModule *pMod = p->pMod;
254314 if( pMod->bV2Native ){
254315 pMod->x2.xDelete(p->pReal);
254316 }else{
254317 pMod->x1.xDelete(p->pReal);
254318 }
254319 sqlite3_free(p);
254320 }
254321 }
254322
@@ -254330,13 +254365,12 @@
254330 void *pCtx, int flags,
254331 const char *pText, int nText,
254332 int (*xToken)(void*, int, const char*, int, int, int)
254333 ){
254334 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254335 Fts5TokenizerModule *pMod = p->pMod;
254336 assert( pMod->bV2Native );
254337 return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
254338 }
254339
254340 /*
254341 ** xTokenizer method for a wrapper tokenizer that offers the v2 interface
254342 ** (with locale support).
@@ -254347,13 +254381,13 @@
254347 const char *pText, int nText,
254348 const char *pLocale, int nLocale,
254349 int (*xToken)(void*, int, const char*, int, int, int)
254350 ){
254351 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254352 Fts5TokenizerModule *pMod = p->pMod;
254353 assert( pMod->bV2Native==0 );
254354 return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254355 }
254356
254357 /*
254358 ** Register a new tokenizer. This is the implementation of the
254359 ** fts5_api.xCreateTokenizer_v2() method.
@@ -254591,11 +254625,11 @@
254591 int nArg, /* Number of args */
254592 sqlite3_value **apUnused /* Function arguments */
254593 ){
254594 assert( nArg==0 );
254595 UNUSED_PARAM2(nArg, apUnused);
254596 sqlite3_result_text(pCtx, "fts5: 2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b31f96", -1, SQLITE_TRANSIENT);
254597 }
254598
254599 /*
254600 ** Implementation of fts5_locale(LOCALE, TEXT) function.
254601 **
254602
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,13 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 7891a266c4425722ae8b9231397ef9e42e24.
 
 
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -464,11 +462,11 @@
462 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463 ** [sqlite_version()] and [sqlite_source_id()].
464 */
465 #define SQLITE_VERSION "3.47.0"
466 #define SQLITE_VERSION_NUMBER 3047000
467 #define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
468
469 /*
470 ** CAPI3REF: Run-Time Library Version Numbers
471 ** KEYWORDS: sqlite3_version sqlite3_sourceid
472 **
@@ -5931,18 +5929,28 @@
5929 ** might become a no-op if the function is used as term in an
5930 ** [expression index]. On the other hand, SQL functions that never invoke
5931 ** [sqlite3_result_subtype()] should avoid setting this property, as the
5932 ** purpose of this property is to disable certain optimizations that are
5933 ** incompatible with subtypes.
5934 **
5935 ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
5936 ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
5937 ** that internally orders the values provided to the first argument. The
5938 ** ordered-set aggregate SQL notation with a single ORDER BY term can be
5939 ** used to invoke this function. If the ordered-set aggregate notation is
5940 ** used on a function that lacks this flag, then an error is raised. Note
5941 ** that the ordered-set aggregate syntax is only available if SQLite is
5942 ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
5943 ** </dd>
5944 ** </dl>
5945 */
5946 #define SQLITE_DETERMINISTIC 0x000000800
5947 #define SQLITE_DIRECTONLY 0x000080000
5948 #define SQLITE_SUBTYPE 0x000100000
5949 #define SQLITE_INNOCUOUS 0x000200000
5950 #define SQLITE_RESULT_SUBTYPE 0x001000000
5951 #define SQLITE_SELFORDER1 0x002000000
5952
5953 /*
5954 ** CAPI3REF: Deprecated Functions
5955 ** DEPRECATED
5956 **
@@ -13610,22 +13618,23 @@
13618 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13619 ** text. pLocale is not nul-terminated.
13620 **
13621 ** FTS5_TOKENIZER
13622 **
13623 ** There is also an fts5_tokenizer object. This is an older, deprecated,
13624 ** version of fts5_tokenizer_v2. It is similar except that:
13625 **
13626 ** <ul>
13627 ** <li> There is no "iVersion" field, and
13628 ** <li> The xTokenize() method does not take a locale argument.
13629 ** </ul>
13630 **
13631 ** Legacy fts5_tokenizer tokenizers must be registered using the
13632 ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
13633 **
13634 ** Tokenizer implementations registered using either API may be retrieved
13635 ** using both xFindTokenizer() and xFindTokenizer_v2().
13636 **
13637 ** SYNONYM SUPPORT
13638 **
13639 ** Custom tokenizers may also support synonyms. Consider a case in which a
13640 ** user wishes to query for a phrase such as "first place". Using the
@@ -14820,10 +14829,12 @@
14829 ** substitute integer for floating-point
14830 */
14831 #ifdef SQLITE_OMIT_FLOATING_POINT
14832 # define double sqlite_int64
14833 # define float sqlite_int64
14834 # define fabs(X) ((X)<0?-(X):(X))
14835 # define sqlite3IsOverflow(X) 0
14836 # define LONGDOUBLE_TYPE sqlite_int64
14837 # ifndef SQLITE_BIG_DBL
14838 # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
14839 # endif
14840 # define SQLITE_OMIT_DATETIME_FUNCS 1
@@ -22355,10 +22366,13 @@
22366 #ifdef SQLITE_ENABLE_NULL_TRIM
22367 "ENABLE_NULL_TRIM",
22368 #endif
22369 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
22370 "ENABLE_OFFSET_SQL_FUNC",
22371 #endif
22372 #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
22373 "ENABLE_ORDERED_SET_AGGREGATES",
22374 #endif
22375 #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
22376 "ENABLE_OVERSIZE_CELL_CHECK",
22377 #endif
22378 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -76734,11 +76748,11 @@
76748 }
76749 if( pCur->iPage>0
76750 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
76751 && pIdxKey->errCode==SQLITE_OK
76752 ){
76753 pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
76754 if( !pCur->pPage->isInit ){
76755 return SQLITE_CORRUPT_BKPT;
76756 }
76757 goto bypass_moveto_root; /* Start search on the current page */
76758 }
@@ -102708,10 +102722,15 @@
102722 }
102723 if( pTab && !HasRowid(pTab) ){
102724 pTab = 0;
102725 sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
102726 }
102727 if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){
102728 pTab = 0;
102729 sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s",
102730 zTable);
102731 }
102732 #ifndef SQLITE_OMIT_VIEW
102733 if( pTab && IsView(pTab) ){
102734 pTab = 0;
102735 sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
102736 }
@@ -108285,13 +108304,13 @@
108304 assert( pExpr->pLeft->op==TK_ORDER );
108305 assert( ExprUseXList(pExpr->pLeft) );
108306 sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList);
108307 }
108308 #ifndef SQLITE_OMIT_WINDOWFUNC
108309 if( pWin && pParse->nErr==0 ){
108310 Select *pSel = pNC->pWinSelect;
108311 assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin );
108312 if( IN_RENAME_OBJECT==0 ){
108313 sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
108314 if( pParse->db->mallocFailed ) break;
108315 }
108316 sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -131211,11 +131230,15 @@
131230
131231 /*
131232 ** group_concat(EXPR, ?SEPARATOR?)
131233 ** string_agg(EXPR, SEPARATOR)
131234 **
131235 ** Content is accumulated in GroupConcatCtx.str with the SEPARATOR
131236 ** coming before the EXPR value, except for the first entry which
131237 ** omits the SEPARATOR.
131238 **
131239 ** It is tragic that the SEPARATOR goes before the EXPR string. The
131240 ** groupConcatInverse() implementation would have been easier if the
131241 ** SEPARATOR were appended after EXPR. And the order is undocumented,
131242 ** so we could change it, in theory. But the old behavior has been
131243 ** around for so long that we dare not, for fear of breaking something.
131244 */
@@ -131315,11 +131338,11 @@
131338 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
131339 pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
131340 /* pGCC is always non-NULL since groupConcatStep() will have always
131341 ** run first to initialize it */
131342 if( ALWAYS(pGCC) ){
131343 int nVS; /* Number of characters to remove */
131344 /* Must call sqlite3_value_text() to convert the argument into text prior
131345 ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
131346 (void)sqlite3_value_text(argv[0]);
131347 nVS = sqlite3_value_bytes(argv[0]);
131348 pGCC->nAccum -= 1;
@@ -155831,10 +155854,13 @@
155854 int nRes; /* Bytes of reserved space at the end of each page */
155855 int nDb; /* Number of attached databases */
155856 const char *zDbMain; /* Schema name of database to vacuum */
155857 const char *zOut; /* Name of output file */
155858 u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
155859 u64 iRandom; /* Random value used for zDbVacuum[] */
155860 char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */
155861
155862
155863 if( !db->autoCommit ){
155864 sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
155865 return SQLITE_ERROR; /* IMP: R-12218-18073 */
155866 }
@@ -155871,31 +155897,33 @@
155897
155898 zDbMain = db->aDb[iDb].zDbSName;
155899 pMain = db->aDb[iDb].pBt;
155900 isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
155901
155902 /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma
155903 ** can be set to 'off' for this file, as it is not recovered if a crash
155904 ** occurs anyway. The integrity of the database is maintained by a
155905 ** (possibly synchronous) transaction opened on the main database before
155906 ** sqlite3BtreeCopyFile() is called.
155907 **
155908 ** An optimization would be to use a non-journaled pager.
155909 ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but
155910 ** that actually made the VACUUM run slower. Very little journalling
155911 ** actually occurs when doing a vacuum since the vacuum_db is initially
155912 ** empty. Only the journal header is written. Apparently it takes more
155913 ** time to parse and run the PRAGMA to turn journalling off than it does
155914 ** to write the journal header file.
155915 */
155916 sqlite3_randomness(sizeof(iRandom),&iRandom);
155917 sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom);
155918 nDb = db->nDb;
155919 rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum);
155920 db->openFlags = saved_openFlags;
155921 if( rc!=SQLITE_OK ) goto end_of_vacuum;
155922 assert( (db->nDb-1)==nDb );
155923 pDb = &db->aDb[nDb];
155924 assert( strcmp(pDb->zDbSName,zDbVacuum)==0 );
155925 pTemp = pDb->pBt;
155926 if( pOut ){
155927 sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
155928 i64 sz = 0;
155929 if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
@@ -155968,15 +155996,15 @@
155996 /* Loop through the tables in the main database. For each, do
155997 ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
155998 ** the contents to the temporary database.
155999 */
156000 rc = execSqlF(db, pzErrMsg,
156001 "SELECT'INSERT INTO %s.'||quote(name)"
156002 "||' SELECT*FROM\"%w\".'||quote(name)"
156003 "FROM %s.sqlite_schema "
156004 "WHERE type='table'AND coalesce(rootpage,1)>0",
156005 zDbVacuum, zDbMain, zDbVacuum
156006 );
156007 assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
156008 db->mDbFlags &= ~DBFLAG_Vacuum;
156009 if( rc!=SQLITE_OK ) goto end_of_vacuum;
156010
@@ -155984,15 +156012,15 @@
156012 ** over to the temporary database. None of these objects has any
156013 ** associated storage, so all we have to do is copy their entries
156014 ** from the schema table.
156015 */
156016 rc = execSqlF(db, pzErrMsg,
156017 "INSERT INTO %s.sqlite_schema"
156018 " SELECT*FROM \"%w\".sqlite_schema"
156019 " WHERE type IN('view','trigger')"
156020 " OR(type='table'AND rootpage=0)",
156021 zDbVacuum, zDbMain
156022 );
156023 if( rc ) goto end_of_vacuum;
156024
156025 /* At this point, there is a write transaction open on both the
156026 ** vacuum database and the main database. Assuming no error occurs,
@@ -166900,10 +166928,11 @@
166928 pNew->iSortIdx = 0;
166929 pNew->rSetup = 0;
166930 pNew->prereq = mPrereq;
166931 pNew->nOut = rSize;
166932 pNew->u.btree.pIndex = pProbe;
166933 pNew->u.btree.pOrderBy = 0;
166934 b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
166935
166936 /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
166937 assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
166938 if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
@@ -182810,11 +182839,12 @@
182839 }
182840
182841 assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
182842 assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
182843 extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
182844 SQLITE_SUBTYPE|SQLITE_INNOCUOUS|
182845 SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1);
182846 enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
182847
182848 /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
182849 ** the meaning is inverted. So flip the bit. */
182850 assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
@@ -233058,22 +233088,23 @@
233088 ** an nLocale byte buffer containing the name of the locale to use as utf-8
233089 ** text. pLocale is not nul-terminated.
233090 **
233091 ** FTS5_TOKENIZER
233092 **
233093 ** There is also an fts5_tokenizer object. This is an older, deprecated,
233094 ** version of fts5_tokenizer_v2. It is similar except that:
233095 **
233096 ** <ul>
233097 ** <li> There is no "iVersion" field, and
233098 ** <li> The xTokenize() method does not take a locale argument.
233099 ** </ul>
233100 **
233101 ** Legacy fts5_tokenizer tokenizers must be registered using the
233102 ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
233103 **
233104 ** Tokenizer implementations registered using either API may be retrieved
233105 ** using both xFindTokenizer() and xFindTokenizer_v2().
233106 **
233107 ** SYNONYM SUPPORT
233108 **
233109 ** Custom tokenizers may also support synonyms. Consider a case in which a
233110 ** user wishes to query for a phrase such as "first place". Using the
@@ -244112,11 +244143,11 @@
244143 iOff = 4;
244144 }
244145
244146 if( iOff<pIter->iEndofDoclist ){
244147 /* Next entry is on the current page */
244148 u64 iDelta;
244149 iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
244150 pIter->iLeafOffset = iOff;
244151 pIter->iRowid += iDelta;
244152 }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){
244153 if( pIter->pSeg ){
@@ -251426,12 +251457,11 @@
251457 rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
251458 }
251459
251460 /* Load the initial configuration */
251461 if( rc==SQLITE_OK ){
251462 rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
 
251463 }
251464
251465 if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
251466 rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1);
251467 }
@@ -253067,13 +253097,15 @@
253097
253098 /*
253099 ** Implementation of xBegin() method.
253100 */
253101 static int fts5BeginMethod(sqlite3_vtab *pVtab){
253102 int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
253103 if( rc==SQLITE_OK ){
253104 fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
253105 }
253106 return rc;
253107 }
253108
253109 /*
253110 ** Implementation of xCommit() method. This is a no-op. The contents of
253111 ** the pending-terms hash-table have already been flushed into the database
@@ -254266,11 +254298,13 @@
254298 ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
254299 ** via the fts5_tokenizer API.
254300 */
254301 typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
254302 struct Fts5VtoVTokenizer {
254303 int bV2Native; /* True if v2 native tokenizer */
254304 fts5_tokenizer x1; /* Tokenizer functions */
254305 fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
254306 Fts5Tokenizer *pReal;
254307 };
254308
254309 /*
254310 ** Create a wrapper tokenizer. The context argument pCtx points to the
@@ -254286,11 +254320,13 @@
254320 Fts5VtoVTokenizer *pNew = 0;
254321 int rc = SQLITE_OK;
254322
254323 pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
254324 if( rc==SQLITE_OK ){
254325 pNew->x1 = pMod->x1;
254326 pNew->x2 = pMod->x2;
254327 pNew->bV2Native = pMod->bV2Native;
254328 if( pMod->bV2Native ){
254329 rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254330 }else{
254331 rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
254332 }
@@ -254308,15 +254344,14 @@
254344 ** Delete an Fts5VtoVTokenizer wrapper tokenizer.
254345 */
254346 static void fts5VtoVDelete(Fts5Tokenizer *pTok){
254347 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254348 if( p ){
254349 if( p->bV2Native ){
254350 p->x2.xDelete(p->pReal);
 
254351 }else{
254352 p->x1.xDelete(p->pReal);
254353 }
254354 sqlite3_free(p);
254355 }
254356 }
254357
@@ -254330,13 +254365,12 @@
254365 void *pCtx, int flags,
254366 const char *pText, int nText,
254367 int (*xToken)(void*, int, const char*, int, int, int)
254368 ){
254369 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254370 assert( p->bV2Native );
254371 return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
 
254372 }
254373
254374 /*
254375 ** xTokenizer method for a wrapper tokenizer that offers the v2 interface
254376 ** (with locale support).
@@ -254347,13 +254381,13 @@
254381 const char *pText, int nText,
254382 const char *pLocale, int nLocale,
254383 int (*xToken)(void*, int, const char*, int, int, int)
254384 ){
254385 Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
254386 assert( p->bV2Native==0 );
254387 UNUSED_PARAM2(pLocale,nLocale);
254388 return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
254389 }
254390
254391 /*
254392 ** Register a new tokenizer. This is the implementation of the
254393 ** fts5_api.xCreateTokenizer_v2() method.
@@ -254591,11 +254625,11 @@
254625 int nArg, /* Number of args */
254626 sqlite3_value **apUnused /* Function arguments */
254627 ){
254628 assert( nArg==0 );
254629 UNUSED_PARAM2(nArg, apUnused);
254630 sqlite3_result_text(pCtx, "fts5: 2024-09-02 18:41:59 e6bec37ea1ca51e1d048941ce4c5211d8fc5c5e3556a1441f9c79b036843f9e3", -1, SQLITE_TRANSIENT);
254631 }
254632
254633 /*
254634 ** Implementation of fts5_locale(LOCALE, TEXT) function.
254635 **
254636
+18 -7
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.47.0"
150150
#define SQLITE_VERSION_NUMBER 3047000
151
-#define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
151
+#define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -5613,18 +5613,28 @@
56135613
** might become a no-op if the function is used as term in an
56145614
** [expression index]. On the other hand, SQL functions that never invoke
56155615
** [sqlite3_result_subtype()] should avoid setting this property, as the
56165616
** purpose of this property is to disable certain optimizations that are
56175617
** incompatible with subtypes.
5618
+**
5619
+** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
5620
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
5621
+** that internally orders the values provided to the first argument. The
5622
+** ordered-set aggregate SQL notation with a single ORDER BY term can be
5623
+** used to invoke this function. If the ordered-set aggregate notation is
5624
+** used on a function that lacks this flag, then an error is raised. Note
5625
+** that the ordered-set aggregate syntax is only available if SQLite is
5626
+** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
56185627
** </dd>
56195628
** </dl>
56205629
*/
56215630
#define SQLITE_DETERMINISTIC 0x000000800
56225631
#define SQLITE_DIRECTONLY 0x000080000
56235632
#define SQLITE_SUBTYPE 0x000100000
56245633
#define SQLITE_INNOCUOUS 0x000200000
56255634
#define SQLITE_RESULT_SUBTYPE 0x001000000
5635
+#define SQLITE_SELFORDER1 0x002000000
56265636
56275637
/*
56285638
** CAPI3REF: Deprecated Functions
56295639
** DEPRECATED
56305640
**
@@ -13292,22 +13302,23 @@
1329213302
** an nLocale byte buffer containing the name of the locale to use as utf-8
1329313303
** text. pLocale is not nul-terminated.
1329413304
**
1329513305
** FTS5_TOKENIZER
1329613306
**
13297
-** There is also an fts5_tokenizer object. This is an older version of
13298
-** fts5_tokenizer_v2. It is similar except that:
13307
+** There is also an fts5_tokenizer object. This is an older, deprecated,
13308
+** version of fts5_tokenizer_v2. It is similar except that:
1329913309
**
1330013310
** <ul>
1330113311
** <li> There is no "iVersion" field, and
1330213312
** <li> The xTokenize() method does not take a locale argument.
1330313313
** </ul>
1330413314
**
13305
-** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13306
-** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13307
-** registered using either API may be retrieved using both xFindTokenizer()
13308
-** and xFindTokenizer_v2().
13315
+** Legacy fts5_tokenizer tokenizers must be registered using the
13316
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
13317
+**
13318
+** Tokenizer implementations registered using either API may be retrieved
13319
+** using both xFindTokenizer() and xFindTokenizer_v2().
1330913320
**
1331013321
** SYNONYM SUPPORT
1331113322
**
1331213323
** Custom tokenizers may also support synonyms. Consider a case in which a
1331313324
** user wishes to query for a phrase such as "first place". Using the
1331413325
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-08-23 17:40:29 9a9d0f6301faefe324261f03543023ffb6a90823349c6946abb0df2f69b3alt1"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -5613,18 +5613,28 @@
5613 ** might become a no-op if the function is used as term in an
5614 ** [expression index]. On the other hand, SQL functions that never invoke
5615 ** [sqlite3_result_subtype()] should avoid setting this property, as the
5616 ** purpose of this property is to disable certain optimizations that are
5617 ** incompatible with subtypes.
 
 
 
 
 
 
 
 
 
5618 ** </dd>
5619 ** </dl>
5620 */
5621 #define SQLITE_DETERMINISTIC 0x000000800
5622 #define SQLITE_DIRECTONLY 0x000080000
5623 #define SQLITE_SUBTYPE 0x000100000
5624 #define SQLITE_INNOCUOUS 0x000200000
5625 #define SQLITE_RESULT_SUBTYPE 0x001000000
 
5626
5627 /*
5628 ** CAPI3REF: Deprecated Functions
5629 ** DEPRECATED
5630 **
@@ -13292,22 +13302,23 @@
13292 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13293 ** text. pLocale is not nul-terminated.
13294 **
13295 ** FTS5_TOKENIZER
13296 **
13297 ** There is also an fts5_tokenizer object. This is an older version of
13298 ** fts5_tokenizer_v2. It is similar except that:
13299 **
13300 ** <ul>
13301 ** <li> There is no "iVersion" field, and
13302 ** <li> The xTokenize() method does not take a locale argument.
13303 ** </ul>
13304 **
13305 ** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
13306 ** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
13307 ** registered using either API may be retrieved using both xFindTokenizer()
13308 ** and xFindTokenizer_v2().
 
13309 **
13310 ** SYNONYM SUPPORT
13311 **
13312 ** Custom tokenizers may also support synonyms. Consider a case in which a
13313 ** user wishes to query for a phrase such as "first place". Using the
13314
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -5613,18 +5613,28 @@
5613 ** might become a no-op if the function is used as term in an
5614 ** [expression index]. On the other hand, SQL functions that never invoke
5615 ** [sqlite3_result_subtype()] should avoid setting this property, as the
5616 ** purpose of this property is to disable certain optimizations that are
5617 ** incompatible with subtypes.
5618 **
5619 ** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
5620 ** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
5621 ** that internally orders the values provided to the first argument. The
5622 ** ordered-set aggregate SQL notation with a single ORDER BY term can be
5623 ** used to invoke this function. If the ordered-set aggregate notation is
5624 ** used on a function that lacks this flag, then an error is raised. Note
5625 ** that the ordered-set aggregate syntax is only available if SQLite is
5626 ** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
5627 ** </dd>
5628 ** </dl>
5629 */
5630 #define SQLITE_DETERMINISTIC 0x000000800
5631 #define SQLITE_DIRECTONLY 0x000080000
5632 #define SQLITE_SUBTYPE 0x000100000
5633 #define SQLITE_INNOCUOUS 0x000200000
5634 #define SQLITE_RESULT_SUBTYPE 0x001000000
5635 #define SQLITE_SELFORDER1 0x002000000
5636
5637 /*
5638 ** CAPI3REF: Deprecated Functions
5639 ** DEPRECATED
5640 **
@@ -13292,22 +13302,23 @@
13302 ** an nLocale byte buffer containing the name of the locale to use as utf-8
13303 ** text. pLocale is not nul-terminated.
13304 **
13305 ** FTS5_TOKENIZER
13306 **
13307 ** There is also an fts5_tokenizer object. This is an older, deprecated,
13308 ** version of fts5_tokenizer_v2. It is similar except that:
13309 **
13310 ** <ul>
13311 ** <li> There is no "iVersion" field, and
13312 ** <li> The xTokenize() method does not take a locale argument.
13313 ** </ul>
13314 **
13315 ** Legacy fts5_tokenizer tokenizers must be registered using the
13316 ** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
13317 **
13318 ** Tokenizer implementations registered using either API may be retrieved
13319 ** using both xFindTokenizer() and xFindTokenizer_v2().
13320 **
13321 ** SYNONYM SUPPORT
13322 **
13323 ** Custom tokenizers may also support synonyms. Consider a case in which a
13324 ** user wishes to query for a phrase such as "first place". Using the
13325

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button