| | @@ -16,11 +16,11 @@ |
| 16 | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | 19 | ** |
| 20 | 20 | ** The content in this amalgamation comes from Fossil check-in |
| 21 | | -** 7e4134e3ff1ca8712f5fc78fadae66554945 with changes in files: |
| 21 | +** 9ac4a33a2932d353c4871fd8e09c10addf82 with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -467,14 +467,14 @@ |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.54.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3054000 |
| 472 | | -#define SQLITE_SOURCE_ID "2026-05-04 10:14:13 7e4134e3ff1ca8712f5fc78fadae665549450988dc43af27c7fe0c77f10ce3fb" |
| 472 | +#define SQLITE_SOURCE_ID "2026-05-21 15:14:35 9ac4a33a2932d353c4871fd8e09c10addf827f1fc3fc9380037d738cf2cd0353" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-05-04T10:14:13.819Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-05-21T15:14:35.420Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -4373,12 +4373,11 @@ |
| 4373 | 4373 | ** parameter on F or if the value of P does not match any of the |
| 4374 | 4374 | ** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). |
| 4375 | 4375 | ** |
| 4376 | 4376 | ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a |
| 4377 | 4377 | ** 64-bit signed integer and returns that integer, or D if P does not |
| 4378 | | -** exist. If the value of P is something other than an integer, then |
| 4379 | | -** zero is returned. |
| 4378 | +** exist or ff the value of P is something other than an integer. |
| 4380 | 4379 | ** |
| 4381 | 4380 | ** The sqlite3_uri_key(F,N) returns a pointer to the name (not |
| 4382 | 4381 | ** the value) of the N-th query parameter for filename F, or a NULL |
| 4383 | 4382 | ** pointer if N is less than zero or greater than the number of query |
| 4384 | 4383 | ** parameters minus 1. The N value is zero-based so N should be 0 to obtain |
| | @@ -18705,11 +18704,11 @@ |
| 18705 | 18704 | int aLimit[SQLITE_N_LIMIT]; /* Limits */ |
| 18706 | 18705 | int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ |
| 18707 | 18706 | struct sqlite3InitInfo { /* Information used during initialization */ |
| 18708 | 18707 | Pgno newTnum; /* Rootpage of table being initialized */ |
| 18709 | 18708 | u8 iDb; /* Which db file is being initialized */ |
| 18710 | | - u8 busy; /* TRUE if currently initializing */ |
| 18709 | + u8 busy; /* TRUE if initing. 2 if due to ADD COLUMN */ |
| 18711 | 18710 | unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ |
| 18712 | 18711 | unsigned imposterTable : 2; /* Building an imposter table */ |
| 18713 | 18712 | unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ |
| 18714 | 18713 | const char **azInit; /* "type", "name", and "tbl_name" columns */ |
| 18715 | 18714 | } init; |
| | @@ -21256,11 +21255,11 @@ |
| 21256 | 21255 | */ |
| 21257 | 21256 | #define INITFLAG_AlterMask 0x0007 /* Types of ALTER */ |
| 21258 | 21257 | #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ |
| 21259 | 21258 | #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ |
| 21260 | 21259 | #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ |
| 21261 | | -#define INITFLAG_AlterDropCons 0x0004 /* Reparse after an ADD COLUMN */ |
| 21260 | +#define INITFLAG_AlterDropCons 0x0004 /* Reparse after a DROP CONSTRAINT */ |
| 21262 | 21261 | |
| 21263 | 21262 | /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled |
| 21264 | 21263 | ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning |
| 21265 | 21264 | ** parameters are for temporary use during development, to help find |
| 21266 | 21265 | ** optimal values for parameters in the query planner. The should not |
| | @@ -22509,11 +22508,19 @@ |
| 22509 | 22508 | SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); |
| 22510 | 22509 | SQLITE_PRIVATE void sqlite3AlterFunctions(void); |
| 22511 | 22510 | SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); |
| 22512 | 22511 | SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); |
| 22513 | 22512 | SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*); |
| 22514 | | -SQLITE_PRIVATE void sqlite3AlterAddConstraint(Parse*,SrcList*,Token*,Token*,const char*,int); |
| 22513 | +SQLITE_PRIVATE void sqlite3AlterAddConstraint( |
| 22514 | + Parse *pParse, /* Parse context */ |
| 22515 | + SrcList *pSrc, /* Table to add constraint to */ |
| 22516 | + Token *pFirst, /* First token of new constraint */ |
| 22517 | + Token *pName, /* Name of new constraint. NULL if name omitted. */ |
| 22518 | + const char *zExpr, /* Text of CHECK expression */ |
| 22519 | + int nExpr, /* Size of pExpr in bytes */ |
| 22520 | + Expr *pExpr /* The parsed CHECK expression */ |
| 22521 | +); |
| 22515 | 22522 | SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); |
| 22516 | 22523 | SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *); |
| 22517 | 22524 | SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); |
| 22518 | 22525 | SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); |
| 22519 | 22526 | SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); |
| | @@ -32413,12 +32420,14 @@ |
| 32413 | 32420 | #define etSRCITEM 12 /* a pointer to a SrcItem */ |
| 32414 | 32421 | #define etPOINTER 13 /* The %p conversion */ |
| 32415 | 32422 | #define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */ |
| 32416 | 32423 | #define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ |
| 32417 | 32424 | #define etDECIMAL 16 /* %d or %u, but not %x, %o */ |
| 32425 | +#define etESCAPE_j 17 /* %j -> JSON string literal w/o "..." */ |
| 32426 | +#define etESCAPE_J 18 /* %J -> JSON string literal with "..." */ |
| 32418 | 32427 | |
| 32419 | | -#define etINVALID 17 /* Any unrecognized conversion type */ |
| 32428 | +#define etINVALID 19 /* Any unrecognized conversion type */ |
| 32420 | 32429 | |
| 32421 | 32430 | |
| 32422 | 32431 | /* |
| 32423 | 32432 | ** An "etByte" is an 8-bit unsigned value. |
| 32424 | 32433 | */ |
| | @@ -32444,24 +32453,24 @@ |
| 32444 | 32453 | #define FLAG_SIGNED 1 /* True if the value to convert is signed */ |
| 32445 | 32454 | #define FLAG_STRING 4 /* Allow infinite precision */ |
| 32446 | 32455 | |
| 32447 | 32456 | /* |
| 32448 | 32457 | ** The table is searched by hash. In the case of %C where C is the character |
| 32449 | | -** and that character has ASCII value j, then the hash is j%23. |
| 32458 | +** and that character has ASCII value j, then the hash is j%25. |
| 32450 | 32459 | ** |
| 32451 | 32460 | ** The order of the entries in fmtinfo[] and the hash chain was entered |
| 32452 | 32461 | ** manually, but based on the output of the following TCL script: |
| 32453 | 32462 | */ |
| 32454 | 32463 | #if 0 /***** Beginning of script ******/ |
| 32455 | | -foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} { |
| 32464 | +foreach c {d s g z q Q w c o u x X f e E G i n % p T S r J j} { |
| 32456 | 32465 | scan $c %c x |
| 32457 | 32466 | set n($c) $x |
| 32458 | 32467 | } |
| 32459 | 32468 | set mx [llength [array names n]] |
| 32460 | 32469 | puts "count: $mx" |
| 32461 | 32470 | |
| 32462 | | -set mx 27 |
| 32471 | +set mx 25 |
| 32463 | 32472 | puts "*********** mx=$mx ************" |
| 32464 | 32473 | for {set r 0} {$r<$mx} {incr r} { |
| 32465 | 32474 | puts -nonewline [format %2d: $r] |
| 32466 | 32475 | foreach c [array names n] { |
| 32467 | 32476 | if {($n($c))%$mx==$r} {puts -nonewline " $c"} |
| | @@ -32469,35 +32478,38 @@ |
| 32469 | 32478 | puts "" |
| 32470 | 32479 | } |
| 32471 | 32480 | #endif /***** End of script ********/ |
| 32472 | 32481 | |
| 32473 | 32482 | static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; |
| 32483 | +static const char aHex[] = "0123456789abcdef"; |
| 32474 | 32484 | static const char aPrefix[] = "-x0\000X0"; |
| 32475 | | -static const et_info fmtinfo[23] = { |
| 32476 | | - /* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 }, |
| 32477 | | - /* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */ |
| 32478 | | - /* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 }, |
| 32479 | | - /* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */ |
| 32480 | | - /* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, |
| 32481 | | - /* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, |
| 32482 | | - /* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */ |
| 32483 | | - /* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 }, |
| 32484 | | - /* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 32485 | | - /* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, |
| 32486 | | - /* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, |
| 32487 | | - /* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, |
| 32488 | | - /* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 }, |
| 32489 | | - /* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 32490 | | - /* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 }, |
| 32491 | | - /* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, |
| 32492 | | - /* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */ |
| 32493 | | - /* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */ |
| 32494 | | - /* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, |
| 32495 | | - /* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 }, |
| 32496 | | - /* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, |
| 32497 | | - /* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 }, |
| 32498 | | - /* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 } |
| 32485 | +static const et_info fmtinfo[25] = { |
| 32486 | + /* 0 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 32487 | + /* 1 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, |
| 32488 | + /* 2 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, |
| 32489 | + /* 3 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, |
| 32490 | + /* 4 */ { 'j', 0, 0, etESCAPE_j, 0, 0, 0 }, /* Hash: 6 */ |
| 32491 | + /* 5 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, |
| 32492 | + /* 6 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 4 }, |
| 32493 | + /* 7 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, /* Hash: 12 */ |
| 32494 | + /* 8 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, |
| 32495 | + /* 9 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, |
| 32496 | + /* 10 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, |
| 32497 | + /* 11 */ { 'o', 8, 0, etRADIX, 0, 2, 0 }, |
| 32498 | + /* 12 */ { '%', 0, 0, etPERCENT, 0, 0, 7 }, |
| 32499 | + /* 13 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 16 }, |
| 32500 | + /* 14 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 }, |
| 32501 | + /* 15 */ { 's', 0, 4, etSTRING, 0, 0, 0 }, |
| 32502 | + /* 16 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 13 */ |
| 32503 | + /* 17 */ { 'u', 10, 0, etDECIMAL, 0, 0, 0 }, |
| 32504 | + /* 18 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, /* Hash: 19 */ |
| 32505 | + /* 19 */ { 'E', 0, 1, etEXP, 14, 0, 18 }, |
| 32506 | + /* 20 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, |
| 32507 | + /* 21 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, |
| 32508 | + /* 22 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 0 }, |
| 32509 | + /* 23 */ { 'J', 0, 0, etESCAPE_J, 0, 0, 0 }, /* Hash: 24 */ |
| 32510 | + /* 24 */ { 'c', 0, 0, etCHARX, 0, 0, 23 } |
| 32499 | 32511 | }; |
| 32500 | 32512 | |
| 32501 | 32513 | /* Additional Notes: |
| 32502 | 32514 | ** |
| 32503 | 32515 | ** %S Takes a pointer to SrcItem. Shows name or database.name |
| | @@ -32754,12 +32766,12 @@ |
| 32754 | 32766 | break; |
| 32755 | 32767 | } |
| 32756 | 32768 | } |
| 32757 | 32769 | #else |
| 32758 | 32770 | /* Fast hash-table lookup */ |
| 32759 | | - assert( ArraySize(fmtinfo)==23 ); |
| 32760 | | - idx = ((unsigned)c) % 23; |
| 32771 | + assert( ArraySize(fmtinfo)==25 ); |
| 32772 | + idx = ((unsigned)c) % 25; |
| 32761 | 32773 | if( fmtinfo[idx].fmttype==c |
| 32762 | 32774 | || fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c |
| 32763 | 32775 | ){ |
| 32764 | 32776 | infop = &fmtinfo[idx]; |
| 32765 | 32777 | xtype = infop->type; |
| | @@ -33126,11 +33138,11 @@ |
| 33126 | 33138 | length = width; |
| 33127 | 33139 | } |
| 33128 | 33140 | |
| 33129 | 33141 | if( zExtra==0 ){ |
| 33130 | 33142 | /* The result is being rendered directory into pAccum. This |
| 33131 | | - ** is the command and fast case */ |
| 33143 | + ** is the common and fast case */ |
| 33132 | 33144 | pAccum->nChar += length; |
| 33133 | 33145 | zOut[length] = 0; |
| 33134 | 33146 | continue; |
| 33135 | 33147 | }else{ |
| 33136 | 33148 | /* We were unable to render directly into pAccum because we |
| | @@ -33246,10 +33258,87 @@ |
| 33246 | 33258 | /* Adjust width to account for extra bytes in UTF-8 characters */ |
| 33247 | 33259 | int ii = length - 1; |
| 33248 | 33260 | while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; |
| 33249 | 33261 | } |
| 33250 | 33262 | break; |
| 33263 | + case etESCAPE_j: /* %j: JSON string literal w/o "..." */ |
| 33264 | + case etESCAPE_J: { /* %J: Generate a JSON string literal */ |
| 33265 | + char *escarg; |
| 33266 | + i64 i, j, px, iStart; |
| 33267 | + unsigned char ch; |
| 33268 | + |
| 33269 | + if( bArgList ){ |
| 33270 | + escarg = getTextArg(pArgList); |
| 33271 | + }else{ |
| 33272 | + escarg = va_arg(ap,char*); |
| 33273 | + } |
| 33274 | + iStart = sqlite3_str_length(pAccum); |
| 33275 | + if( escarg==0 ){ |
| 33276 | + if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "null", 4); |
| 33277 | + }else{ |
| 33278 | + if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1); |
| 33279 | + px = precision; |
| 33280 | + testcase( px==0 ); |
| 33281 | + if( px<0 ){ |
| 33282 | + px = 0x7fffffff; |
| 33283 | + }else if( flag_altform2 ){ |
| 33284 | + /* Convert precision from code-points to bytes */ |
| 33285 | + for(i=0; i<px && escarg[i]; i++){ |
| 33286 | + if( (escarg[i]&0xc0)==0x80 ) px++; |
| 33287 | + } |
| 33288 | + if( i==px ){ |
| 33289 | + while( (escarg[px]&0xc0)==0x80 ) px++; |
| 33290 | + } |
| 33291 | + } |
| 33292 | + for(i=j=0; i<px; i++){ |
| 33293 | + if( (ch = ((u8*)escarg)[i])<=0x1f || ch=='"' || ch=='\\' ){ |
| 33294 | + if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j); |
| 33295 | + j = i+1; |
| 33296 | + if( ch==0 ) break; |
| 33297 | + sqlite3_str_appendchar(pAccum, 1, '\\'); |
| 33298 | + if( ch>0x1f ){ |
| 33299 | + sqlite3_str_appendchar(pAccum, 1, ch); |
| 33300 | + }else if( ((1u<<ch)&0x3700)!=0 ){ |
| 33301 | + ch = "btn?fr"[ch-8]; |
| 33302 | + sqlite3_str_appendchar(pAccum, 1, ch); |
| 33303 | + }else{ |
| 33304 | + sqlite3_str_append(pAccum, "u00", 3); |
| 33305 | + sqlite3_str_appendchar(pAccum, 1, aHex[ch>>4]); |
| 33306 | + sqlite3_str_appendchar(pAccum, 1, aHex[ch&0xf]); |
| 33307 | + } |
| 33308 | + } |
| 33309 | + } |
| 33310 | + if( j<i ) sqlite3_str_append(pAccum, &escarg[j], i-j); |
| 33311 | + if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1); |
| 33312 | + } |
| 33313 | + if( width>0 && sqlite3_str_errcode(pAccum)==SQLITE_OK ){ |
| 33314 | + sqlite3_int64 n = sqlite3_str_length(pAccum) - iStart; |
| 33315 | + sqlite3_int64 len = n; |
| 33316 | + char *zz; |
| 33317 | + if( flag_altform2 && n>0 ){ |
| 33318 | + zz = sqlite3_str_value(pAccum); |
| 33319 | + for(i=iStart; zz[i]; i++){ |
| 33320 | + if( (zz[i]&0xc0)==0x80 ) len--; |
| 33321 | + } |
| 33322 | + } |
| 33323 | + if( width>len ){ |
| 33324 | + sqlite3_int64 sp = width-len; |
| 33325 | + assert( sp>0 && sp<0x7fffffff ); |
| 33326 | + sqlite3_str_appendchar(pAccum, (int)sp, ' '); |
| 33327 | + if( !flag_leftjustify |
| 33328 | + && n>0 |
| 33329 | + && sqlite3_str_errcode(pAccum)==0 |
| 33330 | + ){ |
| 33331 | + zz = sqlite3_str_value(pAccum); |
| 33332 | + zz += iStart; |
| 33333 | + memmove(zz+sp, zz, n); |
| 33334 | + memset(zz, ' ', sp); |
| 33335 | + } |
| 33336 | + } |
| 33337 | + } |
| 33338 | + continue; |
| 33339 | + } |
| 33251 | 33340 | case etESCAPE_q: /* %q: Escape ' characters */ |
| 33252 | 33341 | case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ |
| 33253 | 33342 | case etESCAPE_w: { /* %w: Escape " characters */ |
| 33254 | 33343 | i64 i, j, k, n; |
| 33255 | 33344 | int needQuote = 0; |
| | @@ -33337,11 +33426,11 @@ |
| 33337 | 33426 | bufpt[j-1] = '\\'; |
| 33338 | 33427 | bufpt[j++] = 'u'; |
| 33339 | 33428 | bufpt[j++] = '0'; |
| 33340 | 33429 | bufpt[j++] = '0'; |
| 33341 | 33430 | bufpt[j++] = ch>=0x10 ? '1' : '0'; |
| 33342 | | - bufpt[j++] = "0123456789abcdef"[ch&0xf]; |
| 33431 | + bufpt[j++] = aHex[ch&0xf]; |
| 33343 | 33432 | } |
| 33344 | 33433 | } |
| 33345 | 33434 | }else{ |
| 33346 | 33435 | for(i=0; i<k; i++){ |
| 33347 | 33436 | bufpt[j++] = ch = escarg[i]; |
| | @@ -45345,13 +45434,13 @@ |
| 45345 | 45434 | |
| 45346 | 45435 | /* Minimum number of regions required to be mapped. */ |
| 45347 | 45436 | nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; |
| 45348 | 45437 | |
| 45349 | 45438 | if( pShmNode->nRegion<nReqRegion ){ |
| 45350 | | - char **apNew; /* New apRegion[] array */ |
| 45351 | | - int nByte = nReqRegion*szRegion; /* Minimum required file size */ |
| 45352 | | - struct stat sStat; /* Used by fstat() */ |
| 45439 | + char **apNew; /* New apRegion[] array */ |
| 45440 | + i64 nByte = nReqRegion*(i64)szRegion; /* Minimum required file size */ |
| 45441 | + struct stat sStat; /* Used by fstat() */ |
| 45353 | 45442 | |
| 45354 | 45443 | pShmNode->szRegion = szRegion; |
| 45355 | 45444 | |
| 45356 | 45445 | if( pShmNode->hShm>=0 ){ |
| 45357 | 45446 | /* The requested region is not mapped into this processes address space. |
| | @@ -45378,11 +45467,11 @@ |
| 45378 | 45467 | ** pages forces the OS to allocate them immediately, which reduces |
| 45379 | 45468 | ** the chances of SIGBUS while accessing the mapped region later on. |
| 45380 | 45469 | */ |
| 45381 | 45470 | else{ |
| 45382 | 45471 | static const int pgsz = 4096; |
| 45383 | | - int iPg; |
| 45472 | + i64 iPg; |
| 45384 | 45473 | |
| 45385 | 45474 | /* Write to the last byte of each newly allocated or extended page */ |
| 45386 | 45475 | assert( (nByte % pgsz)==0 ); |
| 45387 | 45476 | for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ |
| 45388 | 45477 | int x = 0; |
| | @@ -45404,12 +45493,12 @@ |
| 45404 | 45493 | rc = SQLITE_IOERR_NOMEM_BKPT; |
| 45405 | 45494 | goto shmpage_out; |
| 45406 | 45495 | } |
| 45407 | 45496 | pShmNode->apRegion = apNew; |
| 45408 | 45497 | while( pShmNode->nRegion<nReqRegion ){ |
| 45409 | | - int nMap = szRegion*nShmPerMap; |
| 45410 | | - int i; |
| 45498 | + i64 nMap = (i64)szRegion*(i64)nShmPerMap; |
| 45499 | + i64 i; |
| 45411 | 45500 | void *pMem; |
| 45412 | 45501 | if( pShmNode->hShm>=0 ){ |
| 45413 | 45502 | pMem = osMmap(0, nMap, |
| 45414 | 45503 | pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 45415 | 45504 | MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion |
| | @@ -49195,107 +49284,154 @@ |
| 49195 | 49284 | |
| 49196 | 49285 | { "CreateFileW", (SYSCALL)CreateFileW, 0 }, |
| 49197 | 49286 | #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
| 49198 | 49287 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[2].pCurrent) |
| 49199 | 49288 | |
| 49289 | +#if defined(SQLITE_UWP) |
| 49290 | + { "CreateFileMappingFromApp",(SYSCALL)CreateFileMappingFromApp,0 }, |
| 49291 | +#else |
| 49292 | + { "CreateFileMappingFromApp",(SYSCALL)0, 0 }, |
| 49293 | +#endif |
| 49294 | +#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE,\ |
| 49295 | + PSECURITY_ATTRIBUTES, \ |
| 49296 | + ULONG,ULONG64,PCWSTR))aSyscall[3].pCurrent) |
| 49297 | + |
| 49298 | +#if !defined(SQLITE_UWP) |
| 49200 | 49299 | { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, |
| 49300 | +#else |
| 49301 | + { "CreateFileMappingW", (SYSCALL)0, 0 }, |
| 49302 | +#endif |
| 49201 | 49303 | #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ |
| 49202 | | - DWORD,DWORD,DWORD,LPCWSTR))aSyscall[3].pCurrent) |
| 49304 | + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[4].pCurrent) |
| 49203 | 49305 | |
| 49204 | 49306 | { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, |
| 49205 | | -#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[4].pCurrent) |
| 49307 | +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[5].pCurrent) |
| 49206 | 49308 | |
| 49207 | 49309 | { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, |
| 49208 | | -#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[5].pCurrent) |
| 49310 | +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[6].pCurrent) |
| 49209 | 49311 | |
| 49210 | 49312 | { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, |
| 49211 | 49313 | #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ |
| 49212 | | - DWORD,va_list*))aSyscall[6].pCurrent) |
| 49314 | + DWORD,va_list*))aSyscall[7].pCurrent) |
| 49213 | 49315 | |
| 49214 | | -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 49316 | +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) |
| 49215 | 49317 | { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, |
| 49216 | 49318 | #else |
| 49217 | 49319 | { "FreeLibrary", (SYSCALL)0, 0 }, |
| 49218 | 49320 | #endif |
| 49219 | 49321 | |
| 49220 | | -#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[7].pCurrent) |
| 49322 | +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[8].pCurrent) |
| 49221 | 49323 | |
| 49222 | 49324 | { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, |
| 49223 | | -#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[8].pCurrent) |
| 49325 | +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[9].pCurrent) |
| 49224 | 49326 | |
| 49225 | 49327 | { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, |
| 49226 | | -#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent) |
| 49328 | +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) |
| 49227 | 49329 | |
| 49228 | 49330 | { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, |
| 49229 | 49331 | #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ |
| 49230 | | - LPVOID))aSyscall[10].pCurrent) |
| 49332 | + LPVOID))aSyscall[11].pCurrent) |
| 49231 | 49333 | |
| 49232 | | - { "GetFileSize", (SYSCALL)GetFileSize, 0 }, |
| 49233 | | -#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[11].pCurrent) |
| 49334 | + { "GetFileSizeEx", (SYSCALL)GetFileSizeEx, 0 }, |
| 49335 | +#define osGetFileSizeEx ((BOOL(WINAPI*)(HANDLE, \ |
| 49336 | + PLARGE_INTEGER))aSyscall[12].pCurrent) |
| 49234 | 49337 | |
| 49235 | 49338 | { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, |
| 49236 | 49339 | #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ |
| 49237 | | - LPWSTR*))aSyscall[12].pCurrent) |
| 49340 | + LPWSTR*))aSyscall[13].pCurrent) |
| 49238 | 49341 | |
| 49239 | 49342 | { "GetLastError", (SYSCALL)GetLastError, 0 }, |
| 49240 | | -#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[13].pCurrent) |
| 49343 | +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[14].pCurrent) |
| 49241 | 49344 | |
| 49242 | | -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 49345 | +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) |
| 49243 | 49346 | { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, |
| 49244 | 49347 | #else |
| 49245 | 49348 | { "GetProcAddressA", (SYSCALL)0, 0 }, |
| 49246 | 49349 | #endif |
| 49247 | 49350 | #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ |
| 49248 | | - LPCSTR))aSyscall[14].pCurrent) |
| 49351 | + LPCSTR))aSyscall[15].pCurrent) |
| 49249 | 49352 | |
| 49250 | 49353 | { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, |
| 49251 | | -#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[15].pCurrent) |
| 49252 | | - |
| 49253 | | - { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, |
| 49254 | | -#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[16].pCurrent) |
| 49354 | +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[16].pCurrent) |
| 49255 | 49355 | |
| 49256 | 49356 | { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, |
| 49257 | 49357 | #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ |
| 49258 | 49358 | LPFILETIME))aSyscall[17].pCurrent) |
| 49259 | 49359 | |
| 49360 | +#ifdef SQLITE_UWP |
| 49361 | + { "GetTempPathW", (SYSCALL)0, 0 }, |
| 49362 | +#else |
| 49260 | 49363 | { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, |
| 49364 | +#endif |
| 49261 | 49365 | #define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[18].pCurrent) |
| 49262 | 49366 | |
| 49263 | | - { "GetTickCount", (SYSCALL)GetTickCount, 0 }, |
| 49264 | | -#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[19].pCurrent) |
| 49367 | + { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, |
| 49368 | +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[19].pCurrent) |
| 49265 | 49369 | |
| 49370 | +#ifdef SQLITE_UWP |
| 49371 | + { "HeapAlloc", (SYSCALL)0, 0 }, |
| 49372 | +#else |
| 49266 | 49373 | { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, |
| 49374 | +#endif |
| 49267 | 49375 | #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ |
| 49268 | 49376 | SIZE_T))aSyscall[20].pCurrent) |
| 49269 | 49377 | |
| 49378 | +#ifdef SQLITE_UWP |
| 49379 | + { "HeapCreate", (SYSCALL)0, 0 }, |
| 49380 | +#else |
| 49270 | 49381 | { "HeapCreate", (SYSCALL)HeapCreate, 0 }, |
| 49382 | +#endif |
| 49271 | 49383 | #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ |
| 49272 | 49384 | SIZE_T))aSyscall[21].pCurrent) |
| 49273 | 49385 | |
| 49386 | +#ifdef SQLITE_UWP |
| 49387 | + { "HeapDestroy", (SYSCALL)0, 0 }, |
| 49388 | +#else |
| 49274 | 49389 | { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, |
| 49390 | +#endif |
| 49275 | 49391 | #define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[22].pCurrent) |
| 49276 | 49392 | |
| 49393 | +#ifdef SQLITE_UWP |
| 49394 | + { "HeapFree", (SYSCALL)0, 0 }, |
| 49395 | +#else |
| 49277 | 49396 | { "HeapFree", (SYSCALL)HeapFree, 0 }, |
| 49397 | +#endif |
| 49278 | 49398 | #define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[23].pCurrent) |
| 49279 | 49399 | |
| 49400 | +#ifdef SQLITE_UWP |
| 49401 | + { "HeapReAlloc", (SYSCALL)0, 0 }, |
| 49402 | +#else |
| 49280 | 49403 | { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, |
| 49404 | +#endif |
| 49281 | 49405 | #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ |
| 49282 | 49406 | SIZE_T))aSyscall[24].pCurrent) |
| 49283 | 49407 | |
| 49408 | +#ifdef SQLITE_UWP |
| 49409 | + { "HeapSize", (SYSCALL)0, 0 }, |
| 49410 | +#else |
| 49284 | 49411 | { "HeapSize", (SYSCALL)HeapSize, 0 }, |
| 49412 | +#endif |
| 49285 | 49413 | #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ |
| 49286 | 49414 | LPCVOID))aSyscall[25].pCurrent) |
| 49287 | 49415 | |
| 49416 | +#ifdef SQLITE_UWP |
| 49417 | + { "HeapValidate", (SYSCALL)0, 0 }, |
| 49418 | +#else |
| 49288 | 49419 | { "HeapValidate", (SYSCALL)HeapValidate, 0 }, |
| 49420 | +#endif |
| 49289 | 49421 | #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ |
| 49290 | 49422 | LPCVOID))aSyscall[26].pCurrent) |
| 49291 | 49423 | |
| 49424 | +#ifdef SQLITE_UWP |
| 49425 | + { "HeapCompact", (SYSCALL)0, 0 }, |
| 49426 | +#else |
| 49292 | 49427 | { "HeapCompact", (SYSCALL)HeapCompact, 0 }, |
| 49428 | +#endif |
| 49293 | 49429 | #define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[27].pCurrent) |
| 49294 | 49430 | |
| 49295 | 49431 | |
| 49296 | | -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 49432 | +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) |
| 49297 | 49433 | { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, |
| 49298 | 49434 | #else |
| 49299 | 49435 | { "LoadLibraryW", (SYSCALL)0, 0 }, |
| 49300 | 49436 | #endif |
| 49301 | 49437 | #define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[28].pCurrent) |
| | @@ -49305,72 +49441,82 @@ |
| 49305 | 49441 | |
| 49306 | 49442 | { "LockFileEx", (SYSCALL)LockFileEx, 0 }, |
| 49307 | 49443 | #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 49308 | 49444 | LPOVERLAPPED))aSyscall[30].pCurrent) |
| 49309 | 49445 | |
| 49310 | | -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
| 49446 | +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ |
| 49447 | + && !defined(SQLITE_UWP) |
| 49311 | 49448 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 49312 | 49449 | #else |
| 49313 | 49450 | { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 49314 | 49451 | #endif |
| 49315 | 49452 | #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 49316 | 49453 | SIZE_T))aSyscall[31].pCurrent) |
| 49454 | + |
| 49455 | +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ |
| 49456 | + && defined(SQLITE_UWP) |
| 49457 | + { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 49458 | +#else |
| 49459 | + { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 49460 | +#endif |
| 49461 | +#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ |
| 49462 | + SIZE_T))aSyscall[32].pCurrent) |
| 49317 | 49463 | |
| 49318 | 49464 | { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, |
| 49319 | 49465 | #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ |
| 49320 | | - int))aSyscall[32].pCurrent) |
| 49466 | + int))aSyscall[33].pCurrent) |
| 49321 | 49467 | |
| 49322 | 49468 | { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, |
| 49323 | 49469 | #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ |
| 49324 | | - LARGE_INTEGER*))aSyscall[33].pCurrent) |
| 49470 | + LARGE_INTEGER*))aSyscall[34].pCurrent) |
| 49325 | 49471 | |
| 49326 | 49472 | { "ReadFile", (SYSCALL)ReadFile, 0 }, |
| 49327 | 49473 | #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ |
| 49328 | | - LPOVERLAPPED))aSyscall[34].pCurrent) |
| 49474 | + LPOVERLAPPED))aSyscall[35].pCurrent) |
| 49329 | 49475 | |
| 49330 | 49476 | { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, |
| 49331 | | -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[35].pCurrent) |
| 49477 | +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent) |
| 49332 | 49478 | |
| 49333 | | - { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, |
| 49334 | | -#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ |
| 49335 | | - DWORD))aSyscall[36].pCurrent) |
| 49479 | + { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 49480 | +#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER,\ |
| 49481 | + PLARGE_INTEGER,DWORD))aSyscall[37].pCurrent) |
| 49336 | 49482 | |
| 49337 | 49483 | { "Sleep", (SYSCALL)Sleep, 0 }, |
| 49338 | | -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[37].pCurrent) |
| 49484 | +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[38].pCurrent) |
| 49339 | 49485 | |
| 49340 | 49486 | { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, |
| 49341 | 49487 | #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 49342 | | - LPOVERLAPPED))aSyscall[38].pCurrent) |
| 49488 | + LPOVERLAPPED))aSyscall[39].pCurrent) |
| 49343 | 49489 | |
| 49344 | 49490 | #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
| 49345 | 49491 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 49346 | 49492 | #else |
| 49347 | 49493 | { "UnmapViewOfFile", (SYSCALL)0, 0 }, |
| 49348 | 49494 | #endif |
| 49349 | | -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[39].pCurrent) |
| 49495 | +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[40].pCurrent) |
| 49350 | 49496 | |
| 49351 | 49497 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 49352 | 49498 | #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ |
| 49353 | | - LPCSTR,LPBOOL))aSyscall[40].pCurrent) |
| 49499 | + LPCSTR,LPBOOL))aSyscall[41].pCurrent) |
| 49354 | 49500 | |
| 49355 | 49501 | { "WriteFile", (SYSCALL)WriteFile, 0 }, |
| 49356 | 49502 | #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ |
| 49357 | | - LPOVERLAPPED))aSyscall[41].pCurrent) |
| 49503 | + LPOVERLAPPED))aSyscall[42].pCurrent) |
| 49358 | 49504 | |
| 49359 | 49505 | { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, |
| 49360 | 49506 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 49361 | | - DWORD))aSyscall[42].pCurrent) |
| 49507 | + DWORD))aSyscall[43].pCurrent) |
| 49362 | 49508 | |
| 49363 | 49509 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 49364 | 49510 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 49365 | | - BOOL))aSyscall[43].pCurrent) |
| 49511 | + BOOL))aSyscall[44].pCurrent) |
| 49366 | 49512 | |
| 49367 | 49513 | { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, |
| 49368 | | -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) |
| 49514 | +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[45].pCurrent) |
| 49369 | 49515 | |
| 49370 | 49516 | { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 49371 | | -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[45].pCurrent) |
| 49517 | +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[46].pCurrent) |
| 49372 | 49518 | |
| 49373 | 49519 | /* |
| 49374 | 49520 | ** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" |
| 49375 | 49521 | ** is really just a macro that uses a compiler intrinsic (e.g. x64). |
| 49376 | 49522 | ** So do not try to make this is into a redefinable interface. |
| | @@ -49379,95 +49525,93 @@ |
| 49379 | 49525 | { "InterlockedCompareExchange", (SYSCALL)0, 0 }, |
| 49380 | 49526 | #define osInterlockedCompareExchange InterlockedCompareExchange |
| 49381 | 49527 | #else |
| 49382 | 49528 | { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, |
| 49383 | 49529 | #define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*,\ |
| 49384 | | - LONG,LONG))aSyscall[46].pCurrent) |
| 49530 | + LONG,LONG))aSyscall[47].pCurrent) |
| 49385 | 49531 | #endif /* defined(InterlockedCompareExchange) */ |
| 49386 | 49532 | |
| 49387 | 49533 | #if SQLITE_WIN32_USE_UUID |
| 49388 | 49534 | { "UuidCreate", (SYSCALL)UuidCreate, 0 }, |
| 49389 | 49535 | #else |
| 49390 | 49536 | { "UuidCreate", (SYSCALL)0, 0 }, |
| 49391 | 49537 | #endif |
| 49392 | | -#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[47].pCurrent) |
| 49538 | +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[48].pCurrent) |
| 49393 | 49539 | |
| 49394 | 49540 | #if SQLITE_WIN32_USE_UUID |
| 49395 | 49541 | { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, |
| 49396 | 49542 | #else |
| 49397 | 49543 | { "UuidCreateSequential", (SYSCALL)0, 0 }, |
| 49398 | 49544 | #endif |
| 49399 | 49545 | #define osUuidCreateSequential \ |
| 49400 | | - ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[48].pCurrent) |
| 49546 | + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[49].pCurrent) |
| 49401 | 49547 | |
| 49402 | 49548 | #if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 |
| 49403 | 49549 | { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, |
| 49404 | 49550 | #else |
| 49405 | 49551 | { "FlushViewOfFile", (SYSCALL)0, 0 }, |
| 49406 | 49552 | #endif |
| 49407 | 49553 | #define osFlushViewOfFile \ |
| 49408 | | - ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[49].pCurrent) |
| 49554 | + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[50].pCurrent) |
| 49409 | 49555 | |
| 49410 | 49556 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 49411 | 49557 | { "CreateEvent", (SYSCALL)CreateEvent, 0 }, |
| 49412 | 49558 | #else |
| 49413 | 49559 | { "CreateEvent", (SYSCALL)0, 0 }, |
| 49414 | 49560 | #endif |
| 49415 | | -#define osCreateEvent ( \ |
| 49416 | | - (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ |
| 49417 | | - aSyscall[50].pCurrent \ |
| 49418 | | -) |
| 49561 | +#define osCreateEvent ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ |
| 49562 | + BOOL,LPCSTR))aSyscall[51].pCurrent) |
| 49419 | 49563 | |
| 49420 | 49564 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 49421 | 49565 | { "CancelIo", (SYSCALL)CancelIo, 0 }, |
| 49422 | 49566 | #else |
| 49423 | 49567 | { "CancelIo", (SYSCALL)0, 0 }, |
| 49424 | 49568 | #endif |
| 49425 | | -#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) |
| 49569 | +#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent) |
| 49426 | 49570 | |
| 49427 | 49571 | #ifndef _WIN32 |
| 49428 | 49572 | { "getenv", (SYSCALL)getenv, 0 }, |
| 49429 | 49573 | #else |
| 49430 | 49574 | { "getenv", (SYSCALL)0, 0 }, |
| 49431 | 49575 | #endif |
| 49432 | | -#define osGetenv ((const char *(*)(const char *))aSyscall[52].pCurrent) |
| 49576 | +#define osGetenv ((const char *(*)(const char *))aSyscall[53].pCurrent) |
| 49433 | 49577 | |
| 49434 | 49578 | #ifndef _WIN32 |
| 49435 | 49579 | { "getcwd", (SYSCALL)getcwd, 0 }, |
| 49436 | 49580 | #else |
| 49437 | 49581 | { "getcwd", (SYSCALL)0, 0 }, |
| 49438 | 49582 | #endif |
| 49439 | | -#define osGetcwd ((char*(*)(char*,size_t))aSyscall[53].pCurrent) |
| 49583 | +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[54].pCurrent) |
| 49440 | 49584 | |
| 49441 | 49585 | #ifndef _WIN32 |
| 49442 | 49586 | { "readlink", (SYSCALL)readlink, 0 }, |
| 49443 | 49587 | #else |
| 49444 | 49588 | { "readlink", (SYSCALL)0, 0 }, |
| 49445 | 49589 | #endif |
| 49446 | | -#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[54].pCurrent) |
| 49590 | +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[55].pCurrent) |
| 49447 | 49591 | |
| 49448 | 49592 | #ifndef _WIN32 |
| 49449 | 49593 | { "lstat", (SYSCALL)lstat, 0 }, |
| 49450 | 49594 | #else |
| 49451 | 49595 | { "lstat", (SYSCALL)0, 0 }, |
| 49452 | 49596 | #endif |
| 49453 | | -#define osLstat ((int(*)(const char*,struct stat*))aSyscall[55].pCurrent) |
| 49597 | +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[56].pCurrent) |
| 49454 | 49598 | |
| 49455 | 49599 | #ifndef _WIN32 |
| 49456 | 49600 | { "__errno", (SYSCALL)__errno, 0 }, |
| 49457 | 49601 | #else |
| 49458 | 49602 | { "__errno", (SYSCALL)0, 0 }, |
| 49459 | 49603 | #endif |
| 49460 | | -#define osErrno (*((int*(*)(void))aSyscall[56].pCurrent)()) |
| 49604 | +#define osErrno (*((int*(*)(void))aSyscall[57].pCurrent)()) |
| 49461 | 49605 | |
| 49462 | 49606 | #ifndef _WIN32 |
| 49463 | 49607 | { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, |
| 49464 | 49608 | #else |
| 49465 | 49609 | { "cygwin_conv_path", (SYSCALL)0, 0 }, |
| 49466 | 49610 | #endif |
| 49467 | 49611 | #define osCygwin_conv_path ((size_t(*)(unsigned int, \ |
| 49468 | | - const void *, void *, size_t))aSyscall[57].pCurrent) |
| 49612 | + const void *, void *, size_t))aSyscall[58].pCurrent) |
| 49469 | 49613 | |
| 49470 | 49614 | }; /* End of the overrideable system calls */ |
| 49471 | 49615 | |
| 49472 | 49616 | /* |
| 49473 | 49617 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -49551,10 +49695,13 @@ |
| 49551 | 49695 | } |
| 49552 | 49696 | return 0; |
| 49553 | 49697 | } |
| 49554 | 49698 | |
| 49555 | 49699 | #ifdef SQLITE_WIN32_MALLOC |
| 49700 | +#ifdef SQLITE_UWP |
| 49701 | +# error SQLITE_WIN32_MALLOC is incompatible with SQLITE_UWP |
| 49702 | +#endif |
| 49556 | 49703 | /* |
| 49557 | 49704 | ** If a Win32 native heap has been configured, this function will attempt to |
| 49558 | 49705 | ** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one |
| 49559 | 49706 | ** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The |
| 49560 | 49707 | ** "pnLargest" argument, if non-zero, will be used to return the size of the |
| | @@ -50509,31 +50656,15 @@ |
| 50509 | 50656 | ** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite |
| 50510 | 50657 | ** error code. |
| 50511 | 50658 | */ |
| 50512 | 50659 | static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ |
| 50513 | 50660 | int rc = SQLITE_OK; /* Return value */ |
| 50514 | | - |
| 50515 | | - LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 50516 | | - LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 50517 | | - DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 50518 | | - |
| 50519 | | - upperBits = (LONG)((iOffset>>32) & 0x7fffffff); |
| 50520 | | - lowerBits = (LONG)(iOffset & 0xffffffff); |
| 50521 | | - |
| 50522 | | - dwRet = osSetFilePointer(h, lowerBits, &upperBits, FILE_BEGIN); |
| 50523 | | - |
| 50524 | | - /* API oddity: If successful, SetFilePointer() returns a dword |
| 50525 | | - ** containing the lower 32-bits of the new file-offset. Or, if it fails, |
| 50526 | | - ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, |
| 50527 | | - ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine |
| 50528 | | - ** whether an error has actually occurred, it is also necessary to call |
| 50529 | | - ** GetLastError(). */ |
| 50530 | | - if( dwRet==INVALID_SET_FILE_POINTER ){ |
| 50531 | | - DWORD lastErrno = osGetLastError(); |
| 50532 | | - if( lastErrno!=NO_ERROR ){ |
| 50533 | | - rc = SQLITE_IOERR_SEEK; |
| 50534 | | - } |
| 50661 | + LARGE_INTEGER x; /* The offset */ |
| 50662 | + |
| 50663 | + x.QuadPart = iOffset; |
| 50664 | + if( osSetFilePointerEx(h, x, 0, FILE_BEGIN)==0 ){ |
| 50665 | + rc = SQLITE_IOERR_SEEK; |
| 50535 | 50666 | } |
| 50536 | 50667 | OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset,sqlite3ErrName(rc))); |
| 50537 | 50668 | return rc; |
| 50538 | 50669 | } |
| 50539 | 50670 | |
| | @@ -50812,18 +50943,17 @@ |
| 50812 | 50943 | ** Determine the size in bytes of the file opened by the handle passed as |
| 50813 | 50944 | ** the first argument. |
| 50814 | 50945 | */ |
| 50815 | 50946 | static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ |
| 50816 | 50947 | int rc = SQLITE_OK; |
| 50817 | | - DWORD upperBits = 0; |
| 50818 | | - DWORD lowerBits = 0; |
| 50819 | | - |
| 50948 | + LARGE_INTEGER x; |
| 50820 | 50949 | assert( pnByte ); |
| 50821 | | - lowerBits = osGetFileSize(h, &upperBits); |
| 50822 | | - *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 50823 | | - if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ |
| 50950 | + if( osGetFileSizeEx(h, &x)==0 ){ |
| 50824 | 50951 | rc = SQLITE_IOERR_FSTAT; |
| 50952 | + *pnByte = 0; |
| 50953 | + }else{ |
| 50954 | + *pnByte = x.QuadPart; |
| 50825 | 50955 | } |
| 50826 | 50956 | return rc; |
| 50827 | 50957 | } |
| 50828 | 50958 | |
| 50829 | 50959 | /* |
| | @@ -51020,21 +51150,18 @@ |
| 51020 | 51150 | assert( id!=0 ); |
| 51021 | 51151 | assert( pSize!=0 ); |
| 51022 | 51152 | SimulateIOError(return SQLITE_IOERR_FSTAT); |
| 51023 | 51153 | OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); |
| 51024 | 51154 | { |
| 51025 | | - DWORD upperBits; |
| 51026 | | - DWORD lowerBits; |
| 51027 | | - DWORD lastErrno; |
| 51028 | | - |
| 51029 | | - lowerBits = osGetFileSize(pFile->h, &upperBits); |
| 51030 | | - *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 51031 | | - if( (lowerBits == INVALID_FILE_SIZE) |
| 51032 | | - && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 51033 | | - pFile->lastErrno = lastErrno; |
| 51155 | + LARGE_INTEGER x; |
| 51156 | + if( osGetFileSizeEx(pFile->h, &x)==0 ){ |
| 51157 | + *pSize = 0; |
| 51158 | + pFile->lastErrno = osGetLastError(); |
| 51034 | 51159 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 51035 | 51160 | "winFileSize", pFile->zPath); |
| 51161 | + }else{ |
| 51162 | + *pSize = x.QuadPart; |
| 51036 | 51163 | } |
| 51037 | 51164 | } |
| 51038 | 51165 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 51039 | 51166 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| 51040 | 51167 | return rc; |
| | @@ -52373,11 +52500,11 @@ |
| 52373 | 52500 | |
| 52374 | 52501 | assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); |
| 52375 | 52502 | if( pShmNode->nRegion<=iRegion ){ |
| 52376 | 52503 | HANDLE hShared = pShmNode->hSharedShm; |
| 52377 | 52504 | struct ShmRegion *apNew; /* New aRegion[] array */ |
| 52378 | | - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ |
| 52505 | + i64 nByte = ((i64)iRegion+1)*(i64)szRegion; /* Minimum file size */ |
| 52379 | 52506 | sqlite3_int64 sz; /* Current size of wal-index file */ |
| 52380 | 52507 | |
| 52381 | 52508 | pShmNode->szRegion = szRegion; |
| 52382 | 52509 | |
| 52383 | 52510 | /* The requested region is not mapped into this processes address space. |
| | @@ -52404,11 +52531,11 @@ |
| 52404 | 52531 | } |
| 52405 | 52532 | } |
| 52406 | 52533 | |
| 52407 | 52534 | /* Map the requested memory region into this processes address space. */ |
| 52408 | 52535 | apNew = (struct ShmRegion*)sqlite3_realloc64( |
| 52409 | | - pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) |
| 52536 | + pShmNode->aRegion, ((i64)iRegion+1)*sizeof(apNew[0]) |
| 52410 | 52537 | ); |
| 52411 | 52538 | if( !apNew ){ |
| 52412 | 52539 | rc = SQLITE_IOERR_NOMEM_BKPT; |
| 52413 | 52540 | goto shmpage_out; |
| 52414 | 52541 | } |
| | @@ -52421,20 +52548,30 @@ |
| 52421 | 52548 | |
| 52422 | 52549 | while( pShmNode->nRegion<=iRegion ){ |
| 52423 | 52550 | HANDLE hMap = NULL; /* file-mapping handle */ |
| 52424 | 52551 | void *pMap = 0; /* Mapped memory region */ |
| 52425 | 52552 | |
| 52553 | +#ifdef SQLITE_UWP |
| 52554 | + hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); |
| 52555 | +#else |
| 52426 | 52556 | hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); |
| 52427 | | - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", |
| 52557 | +#endif |
| 52558 | + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%lld, rc=%s\n", |
| 52428 | 52559 | osGetCurrentProcessId(), pShmNode->nRegion, nByte, |
| 52429 | 52560 | hMap ? "ok" : "failed")); |
| 52430 | 52561 | if( hMap ){ |
| 52431 | | - int iOffset = pShmNode->nRegion*szRegion; |
| 52562 | + i64 iOffset = pShmNode->nRegion*szRegion; |
| 52432 | 52563 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 52564 | +#ifdef SQLITE_UWP |
| 52565 | + pMap = osMapViewOfFileFromApp(hMap, flags, |
| 52566 | + iOffset - iOffsetShift, (i64)szRegion + iOffsetShift |
| 52567 | + ); |
| 52568 | +#else |
| 52433 | 52569 | pMap = osMapViewOfFile(hMap, flags, |
| 52434 | | - 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 52570 | + 0, iOffset - iOffsetShift, (i64)szRegion + iOffsetShift |
| 52435 | 52571 | ); |
| 52572 | +#endif |
| 52436 | 52573 | OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", |
| 52437 | 52574 | osGetCurrentProcessId(), pShmNode->nRegion, iOffset, |
| 52438 | 52575 | szRegion, pMap ? "ok" : "failed")); |
| 52439 | 52576 | } |
| 52440 | 52577 | if( !pMap ){ |
| | @@ -52451,11 +52588,11 @@ |
| 52451 | 52588 | } |
| 52452 | 52589 | } |
| 52453 | 52590 | |
| 52454 | 52591 | shmpage_out: |
| 52455 | 52592 | if( pShmNode->nRegion>iRegion ){ |
| 52456 | | - int iOffset = iRegion*szRegion; |
| 52593 | + i64 iOffset = (i64)iRegion*(i64)szRegion; |
| 52457 | 52594 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 52458 | 52595 | char *p = (char *)pShmNode->aRegion[iRegion].pMap; |
| 52459 | 52596 | *pp = (void *)&p[iOffsetShift]; |
| 52460 | 52597 | }else{ |
| 52461 | 52598 | *pp = 0; |
| | @@ -52563,13 +52700,17 @@ |
| 52563 | 52700 | if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ |
| 52564 | 52701 | protect = PAGE_READWRITE; |
| 52565 | 52702 | flags |= FILE_MAP_WRITE; |
| 52566 | 52703 | } |
| 52567 | 52704 | #endif |
| 52705 | +#ifdef SQLITE_UWP |
| 52706 | + pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); |
| 52707 | +#else |
| 52568 | 52708 | pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, |
| 52569 | 52709 | (DWORD)((nMap>>32) & 0xffffffff), |
| 52570 | 52710 | (DWORD)(nMap & 0xffffffff), NULL); |
| 52711 | +#endif |
| 52571 | 52712 | if( pFd->hMap==NULL ){ |
| 52572 | 52713 | pFd->lastErrno = osGetLastError(); |
| 52573 | 52714 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 52574 | 52715 | "winMapfile1", pFd->zPath); |
| 52575 | 52716 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| | @@ -52577,11 +52718,15 @@ |
| 52577 | 52718 | osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 52578 | 52719 | return SQLITE_OK; |
| 52579 | 52720 | } |
| 52580 | 52721 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 52581 | 52722 | assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 52723 | +#ifdef SQLITE_UWP |
| 52724 | + pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); |
| 52725 | +#else |
| 52582 | 52726 | pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); |
| 52727 | +#endif |
| 52583 | 52728 | if( pNew==NULL ){ |
| 52584 | 52729 | osCloseHandle(pFd->hMap); |
| 52585 | 52730 | pFd->hMap = NULL; |
| 52586 | 52731 | pFd->lastErrno = osGetLastError(); |
| 52587 | 52732 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| | @@ -52920,11 +53065,11 @@ |
| 52920 | 53065 | if( !zWidePath ){ |
| 52921 | 53066 | sqlite3_free(zBuf); |
| 52922 | 53067 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 52923 | 53068 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52924 | 53069 | } |
| 52925 | | - if( osGetTempPathW(nMax, zWidePath)==0 ){ |
| 53070 | + if( osGetTempPathW==0 || osGetTempPathW(nMax, zWidePath)==0 ){ |
| 52926 | 53071 | sqlite3_free(zWidePath); |
| 52927 | 53072 | sqlite3_free(zBuf); |
| 52928 | 53073 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 52929 | 53074 | return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 52930 | 53075 | "winGetTempname2", 0); |
| | @@ -53723,37 +53868,37 @@ |
| 53723 | 53868 | /* |
| 53724 | 53869 | ** Interfaces for opening a shared library, finding entry points |
| 53725 | 53870 | ** within the shared library, and closing the shared library. |
| 53726 | 53871 | */ |
| 53727 | 53872 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 53728 | | - HANDLE h; |
| 53873 | + HANDLE h = 0; |
| 53729 | 53874 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 53730 | 53875 | UNUSED_PARAMETER(pVfs); |
| 53731 | 53876 | if( zConverted==0 ){ |
| 53732 | 53877 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 53733 | 53878 | return 0; |
| 53734 | 53879 | } |
| 53735 | | - h = osLoadLibraryW((LPCWSTR)zConverted); |
| 53880 | + h = osLoadLibraryW ? osLoadLibraryW((LPCWSTR)zConverted) : 0; |
| 53736 | 53881 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); |
| 53737 | 53882 | sqlite3_free(zConverted); |
| 53738 | 53883 | return (void*)h; |
| 53739 | 53884 | } |
| 53740 | 53885 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 53741 | 53886 | UNUSED_PARAMETER(pVfs); |
| 53742 | 53887 | winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 53743 | 53888 | } |
| 53744 | 53889 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 53745 | | - FARPROC proc; |
| 53890 | + FARPROC proc = 0; |
| 53746 | 53891 | UNUSED_PARAMETER(pVfs); |
| 53747 | | - proc = osGetProcAddressA((HANDLE)pH, zSym); |
| 53892 | + proc = osGetProcAddressA ? osGetProcAddressA((HANDLE)pH, zSym) : 0; |
| 53748 | 53893 | OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", |
| 53749 | 53894 | (void*)pH, zSym, (void*)proc)); |
| 53750 | 53895 | return (void(*)(void))proc; |
| 53751 | 53896 | } |
| 53752 | 53897 | static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ |
| 53753 | 53898 | UNUSED_PARAMETER(pVfs); |
| 53754 | | - osFreeLibrary((HANDLE)pHandle); |
| 53899 | + if( osFreeLibrary!=0 ) osFreeLibrary((HANDLE)pHandle); |
| 53755 | 53900 | OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); |
| 53756 | 53901 | } |
| 53757 | 53902 | #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ |
| 53758 | 53903 | #define winDlOpen 0 |
| 53759 | 53904 | #define winDlError 0 |
| | @@ -53798,36 +53943,39 @@ |
| 53798 | 53943 | e.a = (unsigned char*)zBuf; |
| 53799 | 53944 | e.na = nBuf; |
| 53800 | 53945 | e.nXor = 0; |
| 53801 | 53946 | e.i = 0; |
| 53802 | 53947 | { |
| 53803 | | - SYSTEMTIME x; |
| 53804 | | - osGetSystemTime(&x); |
| 53805 | | - xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); |
| 53948 | + FILETIME x; |
| 53949 | + osGetSystemTimeAsFileTime(&x); |
| 53950 | + xorMemory(&e, (unsigned char*)&x, sizeof(x)); |
| 53806 | 53951 | } |
| 53807 | 53952 | { |
| 53808 | 53953 | DWORD pid = osGetCurrentProcessId(); |
| 53809 | | - xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); |
| 53954 | + xorMemory(&e, (unsigned char*)&pid, sizeof(pid)); |
| 53810 | 53955 | } |
| 53811 | 53956 | { |
| 53812 | | - DWORD cnt = osGetTickCount(); |
| 53813 | | - xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); |
| 53957 | + ULONGLONG cnt = osGetTickCount64(); |
| 53958 | + xorMemory(&e, (unsigned char*)&cnt, sizeof(cnt)); |
| 53814 | 53959 | } |
| 53815 | 53960 | { |
| 53816 | 53961 | LARGE_INTEGER i; |
| 53817 | 53962 | osQueryPerformanceCounter(&i); |
| 53818 | | - xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); |
| 53963 | + xorMemory(&e, (unsigned char*)&i, sizeof(i)); |
| 53819 | 53964 | } |
| 53820 | 53965 | #if SQLITE_WIN32_USE_UUID |
| 53966 | +#ifdef SQLITE_UWP |
| 53967 | +# error SQLITE_WIN32_USE_UUID is incompatible with SQLITE_UWP |
| 53968 | +#endif |
| 53821 | 53969 | { |
| 53822 | 53970 | UUID id; |
| 53823 | | - memset(&id, 0, sizeof(UUID)); |
| 53971 | + memset(&id, 0, sizeof(id)); |
| 53824 | 53972 | osUuidCreate(&id); |
| 53825 | | - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); |
| 53973 | + xorMemory(&e, (unsigned char*)&id, sizeof(id)); |
| 53826 | 53974 | memset(&id, 0, sizeof(UUID)); |
| 53827 | 53975 | osUuidCreateSequential(&id); |
| 53828 | | - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); |
| 53976 | + xorMemory(&e, (unsigned char*)&id, sizeof(id)); |
| 53829 | 53977 | } |
| 53830 | 53978 | #endif /* SQLITE_WIN32_USE_UUID */ |
| 53831 | 53979 | return e.nXor>nBuf ? nBuf : e.nXor; |
| 53832 | 53980 | #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ |
| 53833 | 53981 | } |
| | @@ -54042,15 +54190,19 @@ |
| 54042 | 54190 | winNextSystemCall, /* xNextSystemCall */ |
| 54043 | 54191 | }; |
| 54044 | 54192 | |
| 54045 | 54193 | /* Double-check that the aSyscall[] array has been constructed |
| 54046 | 54194 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 54047 | | - assert( ArraySize(aSyscall)==58 ); |
| 54195 | + assert( ArraySize(aSyscall)==59 ); |
| 54048 | 54196 | assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 ); |
| 54049 | | - assert( strcmp(aSyscall[20].zName,"HeapAlloc")==0 ); |
| 54050 | | - assert( strcmp(aSyscall[40].zName,"WideCharToMultiByte")==0 ); |
| 54051 | | - assert( strcmp(aSyscall[57].zName,"cygwin_conv_path")==0 ); |
| 54197 | + assert( strcmp(aSyscall[8].zName,"FreeLibrary")==0 ); |
| 54198 | + assert( strcmp(aSyscall[16].zName,"GetSystemInfo")==0 ); |
| 54199 | + assert( strcmp(aSyscall[24].zName,"HeapReAlloc")==0 ); |
| 54200 | + assert( strcmp(aSyscall[32].zName,"MapViewOfFileFromApp")==0 ); |
| 54201 | + assert( strcmp(aSyscall[40].zName,"UnmapViewOfFile")==0 ); |
| 54202 | + assert( strcmp(aSyscall[48].zName,"UuidCreate")==0 ); |
| 54203 | + assert( strcmp(aSyscall[56].zName,"lstat")==0 ); |
| 54052 | 54204 | |
| 54053 | 54205 | /* get memory map allocation granularity */ |
| 54054 | 54206 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 54055 | 54207 | osGetSystemInfo(&winSysInfo); |
| 54056 | 54208 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| | @@ -71953,10 +72105,20 @@ |
| 71953 | 72105 | ** See the header comment on "btreeInt.h" for additional information. |
| 71954 | 72106 | ** Including a description of file format and an overview of operation. |
| 71955 | 72107 | */ |
| 71956 | 72108 | /* #include "btreeInt.h" */ |
| 71957 | 72109 | |
| 72110 | +/* |
| 72111 | +** Suppress false-positive compiler warnings from GCC. Warnings are |
| 72112 | +** re-enabled at the bottom of this source file. |
| 72113 | +*/ |
| 72114 | +#if defined(__GNUC__) && __GNUC__>=11 |
| 72115 | +# pragma GCC diagnostic push |
| 72116 | +# pragma GCC diagnostic ignored "-Wstringop-overread" |
| 72117 | +# pragma GCC diagnostic ignored "-Wstringop-overflow" |
| 72118 | +#endif |
| 72119 | + |
| 71958 | 72120 | /* |
| 71959 | 72121 | ** The header string that appears at the beginning of every |
| 71960 | 72122 | ** SQLite database. |
| 71961 | 72123 | */ |
| 71962 | 72124 | static const char zMagicHeader[] = SQLITE_FILE_HEADER; |
| | @@ -77228,10 +77390,18 @@ |
| 77228 | 77390 | DbPage *pDbPage; |
| 77229 | 77391 | rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, |
| 77230 | 77392 | (eOp==0 ? PAGER_GET_READONLY : 0) |
| 77231 | 77393 | ); |
| 77232 | 77394 | if( rc==SQLITE_OK ){ |
| 77395 | + if( eOp!=0 |
| 77396 | + && (sqlite3PagerPageRefcount(pDbPage)!=1 |
| 77397 | + || NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) |
| 77398 | + && sqlite3FaultSim(411)==SQLITE_OK |
| 77399 | + ){ |
| 77400 | + sqlite3PagerUnref(pDbPage); |
| 77401 | + return SQLITE_CORRUPT_PAGE(pPage); |
| 77402 | + } |
| 77233 | 77403 | aPayload = sqlite3PagerGetData(pDbPage); |
| 77234 | 77404 | nextPage = get4byte(aPayload); |
| 77235 | 77405 | rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); |
| 77236 | 77406 | sqlite3PagerUnref(pDbPage); |
| 77237 | 77407 | offset = 0; |
| | @@ -83504,10 +83674,17 @@ |
| 83504 | 83674 | SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ |
| 83505 | 83675 | testcase( p->sharable ); |
| 83506 | 83676 | return p->pBt->nRef; |
| 83507 | 83677 | } |
| 83508 | 83678 | #endif |
| 83679 | + |
| 83680 | +/* Re-enable GCC compiler warnings that were suppressed at the top |
| 83681 | +** of this source file to prevent annoying false-positives. |
| 83682 | +*/ |
| 83683 | +#if defined(__GNUC__) && __GNUC__>=11 |
| 83684 | +# pragma GCC diagnostic pop |
| 83685 | +#endif |
| 83509 | 83686 | |
| 83510 | 83687 | /************** End of btree.c ***********************************************/ |
| 83511 | 83688 | /************** Begin file backup.c ******************************************/ |
| 83512 | 83689 | /* |
| 83513 | 83690 | ** 2009 January 28 |
| | @@ -87107,15 +87284,25 @@ |
| 87107 | 87284 | /* |
| 87108 | 87285 | ** Add an OP_ParseSchema opcode. This routine is broken out from |
| 87109 | 87286 | ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees |
| 87110 | 87287 | ** as having been used. |
| 87111 | 87288 | ** |
| 87112 | | -** The zWhere string must have been obtained from sqlite3_malloc(). |
| 87289 | +** zWhere is a WHERE clause that defines which entries of the schema |
| 87290 | +** to reparse. If zWhere==0, that means all entries. p5 is a mask |
| 87291 | +** of INITFLAG_* values for the parse. |
| 87292 | +** |
| 87293 | +** In the current usage, the following are always true: |
| 87294 | +** |
| 87295 | +** ALTER TABLE: zWhere==0, p5!=0 |
| 87296 | +** Otherwise: zWhere!=0, p5==0 |
| 87297 | +** |
| 87298 | +** The zWhere string must have been obtained from sqlite3DbMalloc(). |
| 87113 | 87299 | ** This routine will take ownership of the allocated memory. |
| 87114 | 87300 | */ |
| 87115 | 87301 | SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ |
| 87116 | 87302 | int j; |
| 87303 | + assert( p5==0 || zWhere==0 ); |
| 87117 | 87304 | sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); |
| 87118 | 87305 | sqlite3VdbeChangeP5(p, p5); |
| 87119 | 87306 | for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j); |
| 87120 | 87307 | sqlite3MayAbort(p->pParse); |
| 87121 | 87308 | } |
| | @@ -95713,14 +95900,16 @@ |
| 95713 | 95900 | */ |
| 95714 | 95901 | SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ |
| 95715 | 95902 | int eType = sqlite3_value_type(pVal); |
| 95716 | 95903 | if( eType==SQLITE_TEXT ){ |
| 95717 | 95904 | Mem *pMem = (Mem*)pVal; |
| 95718 | | - assert( pMem->db!=0 ); |
| 95719 | | - sqlite3_mutex_enter(pMem->db->mutex); |
| 95905 | +#if SQLITE_THREADSAFE>0 |
| 95906 | + sqlite3_mutex *pMutex = pMem->db ? pMem->db->mutex : 0; |
| 95907 | +#endif |
| 95908 | + sqlite3_mutex_enter(pMutex); |
| 95720 | 95909 | applyNumericAffinity(pMem, 0); |
| 95721 | | - sqlite3_mutex_leave(pMem->db->mutex); |
| 95910 | + sqlite3_mutex_leave(pMutex); |
| 95722 | 95911 | eType = sqlite3_value_type(pVal); |
| 95723 | 95912 | } |
| 95724 | 95913 | return eType; |
| 95725 | 95914 | } |
| 95726 | 95915 | |
| | @@ -102423,15 +102612,22 @@ |
| 102423 | 102612 | goto abort_due_to_error; |
| 102424 | 102613 | } |
| 102425 | 102614 | break; |
| 102426 | 102615 | } |
| 102427 | 102616 | |
| 102428 | | -/* Opcode: ParseSchema P1 * * P4 * |
| 102617 | +/* Opcode: ParseSchema P1 * * P4 P5 |
| 102429 | 102618 | ** |
| 102430 | 102619 | ** Read and parse all entries from the schema table of database P1 |
| 102431 | 102620 | ** that match the WHERE clause P4. If P4 is a NULL pointer, then the |
| 102432 | 102621 | ** entire schema for P1 is reparsed. |
| 102622 | +** |
| 102623 | +** When P4 is NULL, the P5 value is used as the mFlags argument |
| 102624 | +** to sqlite3InitOne(). In other words, P5 should be a mask composed |
| 102625 | +** of INITFLAG_* values. |
| 102626 | +** |
| 102627 | +** The P4==0 case is only used by ALTER TABLE and P5!=0 for all such |
| 102628 | +** cases. For uses other than ALTER TABLE, P4<>0 and P5==0. |
| 102433 | 102629 | ** |
| 102434 | 102630 | ** This opcode invokes the parser to create a new virtual machine, |
| 102435 | 102631 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 102436 | 102632 | */ |
| 102437 | 102633 | case OP_ParseSchema: { |
| | @@ -102456,18 +102652,20 @@ |
| 102456 | 102652 | || db->mallocFailed |
| 102457 | 102653 | || (CORRUPT_DB && (db->flags & SQLITE_NoSchemaError)!=0) ); |
| 102458 | 102654 | |
| 102459 | 102655 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 102460 | 102656 | if( pOp->p4.z==0 ){ |
| 102657 | + assert( pOp->p5!=0 ); |
| 102461 | 102658 | sqlite3SchemaClear(db->aDb[iDb].pSchema); |
| 102462 | 102659 | db->mDbFlags &= ~DBFLAG_SchemaKnownOk; |
| 102463 | 102660 | rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); |
| 102464 | 102661 | db->mDbFlags |= DBFLAG_SchemaChange; |
| 102465 | 102662 | p->expired = 0; |
| 102466 | 102663 | }else |
| 102467 | 102664 | #endif |
| 102468 | 102665 | { |
| 102666 | + assert( pOp->p5==0 ); |
| 102469 | 102667 | zSchema = LEGACY_SCHEMA_TABLE; |
| 102470 | 102668 | initData.db = db; |
| 102471 | 102669 | initData.iDb = iDb; |
| 102472 | 102670 | initData.pzErrMsg = &p->zErrMsg; |
| 102473 | 102671 | initData.mInitFlags = 0; |
| | @@ -109972,10 +110170,11 @@ |
| 109972 | 110170 | } |
| 109973 | 110171 | extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); |
| 109974 | 110172 | pExpr->op = TK_FUNCTION; |
| 109975 | 110173 | pExpr->u.zToken = "coalesce"; |
| 109976 | 110174 | pExpr->x.pList = pFJMatch; |
| 110175 | + pExpr->affExpr = SQLITE_AFF_DEFER; |
| 109977 | 110176 | cnt = 1; |
| 109978 | 110177 | goto lookupname_end; |
| 109979 | 110178 | }else{ |
| 109980 | 110179 | sqlite3ExprListDelete(db, pFJMatch); |
| 109981 | 110180 | pFJMatch = 0; |
| | @@ -110137,10 +110336,30 @@ |
| 110137 | 110336 | sqlite3AtoF(p->u.zToken, &r); |
| 110138 | 110337 | assert( r>=0.0 ); |
| 110139 | 110338 | if( r>1.0 ) return -1; |
| 110140 | 110339 | return (int)(r*134217728.0); |
| 110141 | 110340 | } |
| 110341 | + |
| 110342 | +/* |
| 110343 | +** Set the EP_SubtArg property on every expression inside of |
| 110344 | +** pList. If any subexpression is actually a subquery, then |
| 110345 | +** also set the EP_SubtArg property on the first result-set |
| 110346 | +** column of that subquery. |
| 110347 | +*/ |
| 110348 | +static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){ |
| 110349 | + int nn, ii; |
| 110350 | + nn = pList ? pList->nExpr : 0; |
| 110351 | + for(ii=0; ii<nn; ii++){ |
| 110352 | + Expr *pExpr = pList->a[ii].pExpr; |
| 110353 | + ExprSetProperty(pExpr, EP_SubtArg); |
| 110354 | + if( pExpr->op==TK_SELECT ){ |
| 110355 | + assert( ExprUseXSelect(pExpr) ); |
| 110356 | + assert( pExpr->x.pSelect!=0 ); |
| 110357 | + resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList); |
| 110358 | + } |
| 110359 | + } |
| 110360 | +} |
| 110142 | 110361 | |
| 110143 | 110362 | /* |
| 110144 | 110363 | ** This routine is callback for sqlite3WalkExpr(). |
| 110145 | 110364 | ** |
| 110146 | 110365 | ** Resolve symbolic names into TK_COLUMN operators for the current |
| | @@ -110382,14 +110601,11 @@ |
| 110382 | 110601 | ** the function may return a value with a subtype back to its |
| 110383 | 110602 | ** caller using sqlite3_result_value(). */ |
| 110384 | 110603 | if( (pDef->funcFlags & SQLITE_SUBTYPE) |
| 110385 | 110604 | || ExprHasProperty(pExpr, EP_SubtArg) |
| 110386 | 110605 | ){ |
| 110387 | | - int ii; |
| 110388 | | - for(ii=0; ii<n; ii++){ |
| 110389 | | - ExprSetProperty(pList->a[ii].pExpr, EP_SubtArg); |
| 110390 | | - } |
| 110606 | + resolveSetExprSubtypeArg(pList); |
| 110391 | 110607 | } |
| 110392 | 110608 | |
| 110393 | 110609 | if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ |
| 110394 | 110610 | /* For the purposes of the EP_ConstFunc flag, date and time |
| 110395 | 110611 | ** functions and other functions that change slowly are considered |
| | @@ -110415,12 +110631,17 @@ |
| 110415 | 110631 | && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 |
| 110416 | 110632 | ){ |
| 110417 | 110633 | /* Internal-use-only functions are disallowed unless the |
| 110418 | 110634 | ** SQL is being compiled using sqlite3NestedParse() or |
| 110419 | 110635 | ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be |
| 110420 | | - ** used to activate internal functions for testing purposes */ |
| 110421 | | - no_such_func = 1; |
| 110636 | + ** used to activate internal functions for testing purposes. |
| 110637 | + ** |
| 110638 | + ** The 2 value for no_such_func means that the function is |
| 110639 | + ** an internal-use-only function which should be treated as a |
| 110640 | + ** non-existant function for name resolution purposes. |
| 110641 | + */ |
| 110642 | + no_such_func = 2; |
| 110422 | 110643 | pDef = 0; |
| 110423 | 110644 | }else |
| 110424 | 110645 | if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 |
| 110425 | 110646 | && !IN_RENAME_OBJECT |
| 110426 | 110647 | ){ |
| | @@ -110460,13 +110681,20 @@ |
| 110460 | 110681 | sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); |
| 110461 | 110682 | pNC->nNcErr++; |
| 110462 | 110683 | is_agg = 0; |
| 110463 | 110684 | } |
| 110464 | 110685 | #endif |
| 110465 | | - else if( no_such_func && pParse->db->init.busy==0 |
| 110686 | + else if( no_such_func |
| 110687 | + && (pParse->db->init.busy==0 || |
| 110688 | + (no_such_func==2 && pParse->db->init.busy==2)) |
| 110689 | + /* Suppress "no such function" errors when reading |
| 110690 | + ** the sqlite_schema table. Except, do raise the error |
| 110691 | + ** if init.busy is 2, meaning the schema parse is due |
| 110692 | + ** to an ALTER TABLE ADD COLUMN statement, and the function |
| 110693 | + ** is an internal-use-only function (no_such_func==2). */ |
| 110466 | 110694 | #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION |
| 110467 | | - && pParse->explain==0 |
| 110695 | + && pParse->explain==0 |
| 110468 | 110696 | #endif |
| 110469 | 110697 | ){ |
| 110470 | 110698 | sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); |
| 110471 | 110699 | pNC->nNcErr++; |
| 110472 | 110700 | }else if( wrong_num_args ){ |
| | @@ -111849,11 +112077,13 @@ |
| 111849 | 112077 | ** Return TRUE if the two expressions have equivalent collating sequences. |
| 111850 | 112078 | */ |
| 111851 | 112079 | SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){ |
| 111852 | 112080 | CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); |
| 111853 | 112081 | CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); |
| 111854 | | - return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; |
| 112082 | + assert( (pColl1==pColl2) == |
| 112083 | + (sqlite3_stricmp(pColl1->zName,pColl2->zName)==0) ); |
| 112084 | + return pColl1==pColl2; |
| 111855 | 112085 | } |
| 111856 | 112086 | |
| 111857 | 112087 | /* |
| 111858 | 112088 | ** pExpr is an operand of a comparison operator. aff2 is the |
| 111859 | 112089 | ** type affinity of the other operand. This routine returns the |
| | @@ -116203,40 +116433,51 @@ |
| 116203 | 116433 | } |
| 116204 | 116434 | return target; |
| 116205 | 116435 | } |
| 116206 | 116436 | |
| 116207 | 116437 | /* |
| 116208 | | -** Expression Node callback for sqlite3ExprCanReturnSubtype(). |
| 116209 | | -** |
| 116210 | | -** Only a function call is able to return a subtype. So if the node |
| 116211 | | -** is not a function call, return WRC_Prune immediately. |
| 116212 | | -** |
| 116213 | | -** A function call is able to return a subtype if it has the |
| 116214 | | -** SQLITE_RESULT_SUBTYPE property. |
| 116215 | | -** |
| 116216 | | -** Assume that every function is able to pass-through a subtype from |
| 116217 | | -** one of its argument (using sqlite3_result_value()). Most functions |
| 116218 | | -** are not this way, but we don't have a mechanism to distinguish those |
| 116219 | | -** that are from those that are not, so assume they all work this way. |
| 116220 | | -** That means that if one of its arguments is another function and that |
| 116221 | | -** other function is able to return a subtype, then this function is |
| 116222 | | -** able to return a subtype. |
| 116438 | +** Expression Node callback for sqlite3ExprCanReturnSubtype(). If |
| 116439 | +** pExpr is able to return a subtype, set pWalker->eCode and abort |
| 116440 | +** the search. If pExpr can never return a subtype, prune search. |
| 116441 | +** |
| 116442 | +** The only expressions that can return a subtype are: |
| 116443 | +** |
| 116444 | +** 1. A function |
| 116445 | +** 2. The no-op "+" operator |
| 116446 | +** 3. A CASE...END expression |
| 116447 | +** 4. A CAST() expression |
| 116448 | +** 5. A "expr COLLATE colseq" expression. |
| 116449 | +** |
| 116450 | +** For any other kind of expression, prune the search. |
| 116451 | +** |
| 116452 | +** For case 1, the expression can yield a subtype if the function has |
| 116453 | +** the SQLITE_RESULT_SUBTYPE property. Functions can also return |
| 116454 | +** a subtype (via sqlite3_result_value()) if any of the arguments can |
| 116455 | +** return a subtype. |
| 116456 | +** |
| 116457 | +** In all cases 1 through 5, the expression might also return a subtype |
| 116458 | +** if any operand can return a subtype. |
| 116223 | 116459 | */ |
| 116224 | 116460 | static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ |
| 116225 | 116461 | int n; |
| 116226 | 116462 | FuncDef *pDef; |
| 116227 | 116463 | sqlite3 *db; |
| 116464 | + if( pExpr->op==TK_CASE || pExpr->op==TK_UPLUS |
| 116465 | + || pExpr->op==TK_COLLATE || pExpr->op==TK_CAST |
| 116466 | + ){ |
| 116467 | + return WRC_Continue; |
| 116468 | + } |
| 116228 | 116469 | if( pExpr->op!=TK_FUNCTION ){ |
| 116229 | 116470 | return WRC_Prune; |
| 116230 | 116471 | } |
| 116231 | 116472 | assert( ExprUseXList(pExpr) ); |
| 116232 | 116473 | db = pWalker->pParse->db; |
| 116233 | 116474 | n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; |
| 116234 | 116475 | pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); |
| 116235 | 116476 | if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ |
| 116236 | 116477 | pWalker->eCode = 1; |
| 116237 | | - return WRC_Prune; |
| 116478 | + return WRC_Abort; |
| 116238 | 116479 | } |
| 116239 | 116480 | return WRC_Continue; |
| 116240 | 116481 | } |
| 116241 | 116482 | |
| 116242 | 116483 | /* |
| | @@ -122210,23 +122451,35 @@ |
| 122210 | 122451 | SQLITE_PRIVATE void sqlite3AlterAddConstraint( |
| 122211 | 122452 | Parse *pParse, /* Parse context */ |
| 122212 | 122453 | SrcList *pSrc, /* Table to add constraint to */ |
| 122213 | 122454 | Token *pFirst, /* First token of new constraint */ |
| 122214 | 122455 | Token *pName, /* Name of new constraint. NULL if name omitted. */ |
| 122215 | | - const char *pExpr, /* Text of CHECK expression */ |
| 122216 | | - int nExpr /* Size of pExpr in bytes */ |
| 122456 | + const char *zExpr, /* Text of CHECK expression */ |
| 122457 | + int nExpr, /* Size of pExpr in bytes */ |
| 122458 | + Expr *pExpr /* The parsed CHECK expression */ |
| 122217 | 122459 | ){ |
| 122218 | 122460 | Table *pTab = 0; /* Table identified by pSrc */ |
| 122219 | 122461 | int iDb = 0; /* Which schema does pTab live in */ |
| 122220 | 122462 | const char *zDb = 0; /* Name of the schema in which pTab lives */ |
| 122221 | 122463 | const char *pCons = 0; /* Text of the constraint */ |
| 122222 | 122464 | int nCons; /* Bytes of text to use from pCons[] */ |
| 122465 | + int rc; /* Result from error checking pExpr */ |
| 122223 | 122466 | |
| 122224 | 122467 | /* Look up the table being altered. */ |
| 122225 | 122468 | assert( pSrc->nSrc==1 ); |
| 122226 | 122469 | pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1); |
| 122227 | | - if( !pTab ) return; |
| 122470 | + if( !pTab ){ |
| 122471 | + sqlite3ExprDelete(pParse->db, pExpr); |
| 122472 | + return; |
| 122473 | + } |
| 122474 | + |
| 122475 | + /* Verify that the new CHECK constraint does not contain any |
| 122476 | + ** internal-use-only function. Forum post 2026-05-10T01:11:28Z |
| 122477 | + */ |
| 122478 | + rc = sqlite3ResolveSelfReference(pParse, pTab, NC_IsCheck, pExpr, 0); |
| 122479 | + sqlite3ExprDelete(pParse->db, pExpr); |
| 122480 | + if( rc ) return; |
| 122228 | 122481 | |
| 122229 | 122482 | /* If this new constraint has a name, check that it is not a duplicate of |
| 122230 | 122483 | ** an existing constraint. It is an error if it is. */ |
| 122231 | 122484 | if( pName ){ |
| 122232 | 122485 | char *zName = sqlite3NameFromToken(pParse->db, pName); |
| | @@ -122243,11 +122496,11 @@ |
| 122243 | 122496 | |
| 122244 | 122497 | /* Search for a constraint violation. Throw an exception if one is found. */ |
| 122245 | 122498 | sqlite3NestedParse(pParse, |
| 122246 | 122499 | "SELECT sqlite_fail('constraint failed', %d) " |
| 122247 | 122500 | "FROM %Q.%Q WHERE (%.*s) IS NOT TRUE", |
| 122248 | | - SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, pExpr |
| 122501 | + SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, zExpr |
| 122249 | 122502 | ); |
| 122250 | 122503 | |
| 122251 | 122504 | /* Edit the SQL for the named table. */ |
| 122252 | 122505 | pCons = pFirst->z; |
| 122253 | 122506 | nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); |
| | @@ -125929,10 +126182,23 @@ |
| 125929 | 126182 | if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; |
| 125930 | 126183 | if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0; |
| 125931 | 126184 | return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; |
| 125932 | 126185 | } |
| 125933 | 126186 | |
| 126187 | +/* |
| 126188 | +** Suppress false-positive warning message generated with -O3 in GCC |
| 126189 | +** on the second call to sqlite3Strlen30() in the sqlite3ColumnSetColl() |
| 126190 | +** function below. See the forum thread beginning on 2026-05-10T01:11:22Z. |
| 126191 | +** |
| 126192 | +** See also the "pop" pragma to undo this warning suppression immediately |
| 126193 | +** after the function. |
| 126194 | +*/ |
| 126195 | +#if defined(__GNUC__) && __GNUC__>=11 |
| 126196 | +# pragma GCC diagnostic push |
| 126197 | +# pragma GCC diagnostic ignored "-Wstringop-overread" |
| 126198 | +#endif |
| 126199 | + |
| 125934 | 126200 | /* |
| 125935 | 126201 | ** Set the collating sequence name for a column. |
| 125936 | 126202 | */ |
| 125937 | 126203 | SQLITE_PRIVATE void sqlite3ColumnSetColl( |
| 125938 | 126204 | sqlite3 *db, |
| | @@ -125953,10 +126219,15 @@ |
| 125953 | 126219 | pCol->zCnName = zNew; |
| 125954 | 126220 | memcpy(pCol->zCnName + n, zColl, nColl); |
| 125955 | 126221 | pCol->colFlags |= COLFLAG_HASCOLL; |
| 125956 | 126222 | } |
| 125957 | 126223 | } |
| 126224 | + |
| 126225 | +/* Undo the false-positive warning suppression above. */ |
| 126226 | +#if defined(__GNUC__) && __GNUC__>=11 |
| 126227 | +# pragma GCC diagnostic pop |
| 126228 | +#endif |
| 125958 | 126229 | |
| 125959 | 126230 | /* |
| 125960 | 126231 | ** Return the collating sequence name for a column |
| 125961 | 126232 | */ |
| 125962 | 126233 | SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ |
| | @@ -134599,15 +134870,20 @@ |
| 134599 | 134870 | ** to initialize it */ |
| 134600 | 134871 | if( ALWAYS(p) && type!=SQLITE_NULL ){ |
| 134601 | 134872 | assert( p->cnt>0 ); |
| 134602 | 134873 | p->cnt--; |
| 134603 | 134874 | if( !p->approx ){ |
| 134604 | | - if( sqlite3SubInt64(&p->iSum, sqlite3_value_int64(argv[0])) ){ |
| 134605 | | - p->ovrfl = 1; |
| 134606 | | - p->approx = 1; |
| 134875 | + i64 x = p->iSum; |
| 134876 | + if( sqlite3SubInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ |
| 134877 | + p->iSum = x; |
| 134878 | + return; |
| 134607 | 134879 | } |
| 134608 | | - }else if( type==SQLITE_INTEGER ){ |
| 134880 | + p->ovrfl = 1; |
| 134881 | + p->approx = 1; |
| 134882 | + kahanBabuskaNeumaierInit(p, p->iSum); |
| 134883 | + } |
| 134884 | + if( type==SQLITE_INTEGER ){ |
| 134609 | 134885 | i64 iVal = sqlite3_value_int64(argv[0]); |
| 134610 | 134886 | if( iVal!=SMALLEST_INT64 ){ |
| 134611 | 134887 | kahanBabuskaNeumaierStepInt64(p, -iVal); |
| 134612 | 134888 | }else{ |
| 134613 | 134889 | kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); |
| | @@ -140569,10 +140845,48 @@ |
| 140569 | 140845 | } |
| 140570 | 140846 | |
| 140571 | 140847 | /* If no test above fails then the indices must be compatible */ |
| 140572 | 140848 | return 1; |
| 140573 | 140849 | } |
| 140850 | + |
| 140851 | +/* |
| 140852 | +** Examine an expression node and abort if it references the ROWID. |
| 140853 | +** This is a Walker callback used by xferCompatibleCheck() |
| 140854 | +*/ |
| 140855 | +static int xferCheckRowid(Walker *pWalk, Expr *pExpr){ |
| 140856 | + if( pExpr->op==TK_COLUMN && pExpr->iColumn<0 ){ |
| 140857 | + pWalk->eCode = 1; |
| 140858 | + return WRC_Abort; |
| 140859 | + }else{ |
| 140860 | + return WRC_Continue; |
| 140861 | + } |
| 140862 | +} |
| 140863 | + |
| 140864 | +/* |
| 140865 | +** Analyze CHECK constraints on the source and destination tables and |
| 140866 | +** return true if those CHECK constraints are compatible with the |
| 140867 | +** xfer-optimization. |
| 140868 | +** |
| 140869 | +** * The pDest and pSrc tables must have identical CHECK constraints. |
| 140870 | +** |
| 140871 | +** * If the destination table, pDest, does not have an |
| 140872 | +** INTEGER PRIMARY KEY column, then no CHECK constraint may |
| 140873 | +** referenced the ROWID. (See forum post 2026-05-11T13:15:57Z) |
| 140874 | +*/ |
| 140875 | +static int xferCompatibleCheck(Table *pDest, Table *pSrc){ |
| 140876 | + if( sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ |
| 140877 | + return 0; |
| 140878 | + } |
| 140879 | + if( pDest->iPKey<0 ){ |
| 140880 | + Walker w; |
| 140881 | + memset(&w, 0, sizeof(w)); |
| 140882 | + w.xExprCallback = xferCheckRowid; |
| 140883 | + sqlite3WalkExprList(&w,pDest->pCheck); |
| 140884 | + if( w.eCode ) return 0; |
| 140885 | + } |
| 140886 | + return 1; |
| 140887 | +} |
| 140574 | 140888 | |
| 140575 | 140889 | /* |
| 140576 | 140890 | ** Attempt the transfer optimization on INSERTs of the form |
| 140577 | 140891 | ** |
| 140578 | 140892 | ** INSERT INTO tab1 SELECT * FROM tab2; |
| | @@ -140696,12 +141010,23 @@ |
| 140696 | 141010 | return 0; /* Number of columns must be the same in tab1 and tab2 */ |
| 140697 | 141011 | } |
| 140698 | 141012 | if( pDest->iPKey!=pSrc->iPKey ){ |
| 140699 | 141013 | return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ |
| 140700 | 141014 | } |
| 140701 | | - if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){ |
| 140702 | | - return 0; /* Cannot feed from a non-strict into a strict table */ |
| 141015 | + if( (pDest->tabFlags & TF_Strict)!=0 ){ |
| 141016 | + if( (pSrc->tabFlags & TF_Strict)==0 ){ |
| 141017 | + return 0; /* Cannot feed from a non-strict into a strict table */ |
| 141018 | + } |
| 141019 | + for(i=0; i<pDest->nCol; i++){ |
| 141020 | + unsigned eDestType = pDest->aCol[i].eCType; |
| 141021 | + unsigned eSrcType = pSrc->aCol[i].eCType; |
| 141022 | + if( eDestType==COLTYPE_ANY ) continue; |
| 141023 | + if( eDestType==eSrcType ) continue; |
| 141024 | + if( eDestType==COLTYPE_INT && eSrcType==COLTYPE_INTEGER ) continue; |
| 141025 | + if( eDestType==COLTYPE_INTEGER && eSrcType==COLTYPE_INT ) continue; |
| 141026 | + return 0; /* Incompatible types in source and destination */ |
| 141027 | + } |
| 140703 | 141028 | } |
| 140704 | 141029 | for(i=0; i<pDest->nCol; i++){ |
| 140705 | 141030 | Column *pDestCol = &pDest->aCol[i]; |
| 140706 | 141031 | Column *pSrcCol = &pSrc->aCol[i]; |
| 140707 | 141032 | #ifdef SQLITE_ENABLE_HIDDEN_COLUMNS |
| | @@ -140791,11 +141116,11 @@ |
| 140791 | 141116 | } |
| 140792 | 141117 | } |
| 140793 | 141118 | #ifndef SQLITE_OMIT_CHECK |
| 140794 | 141119 | if( pDest->pCheck |
| 140795 | 141120 | && (db->mDbFlags & DBFLAG_Vacuum)==0 |
| 140796 | | - && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) |
| 141121 | + && !xferCompatibleCheck(pDest,pSrc) |
| 140797 | 141122 | ){ |
| 140798 | 141123 | return 0; /* Tables have different CHECK constraints. Ticket #2252 */ |
| 140799 | 141124 | } |
| 140800 | 141125 | #endif |
| 140801 | 141126 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| | @@ -140812,10 +141137,22 @@ |
| 140812 | 141137 | } |
| 140813 | 141138 | #endif |
| 140814 | 141139 | if( (db->flags & SQLITE_CountRows)!=0 ){ |
| 140815 | 141140 | return 0; /* xfer opt does not play well with PRAGMA count_changes */ |
| 140816 | 141141 | } |
| 141142 | +#ifndef SQLITE_OMIT_AUTHORIZATION |
| 141143 | + if( db->xAuth ){ |
| 141144 | + int iDb = sqlite3SchemaToIndex(db, pSrc->pSchema); |
| 141145 | + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 0; |
| 141146 | + for(i=0; i<pSrc->nCol; i++){ |
| 141147 | + Column *pSrcCol = &pSrc->aCol[i]; |
| 141148 | + if( sqlite3AuthReadCol(pParse, pSrc->zName, pSrcCol->zCnName, iDb) ){ |
| 141149 | + return 0; |
| 141150 | + } |
| 141151 | + } |
| 141152 | + } |
| 141153 | +#endif |
| 140817 | 141154 | |
| 140818 | 141155 | /* If we get this far, it means that the xfer optimization is at |
| 140819 | 141156 | ** least a possibility, though it might only work if the destination |
| 140820 | 141157 | ** table (tab1) is initially empty. |
| 140821 | 141158 | */ |
| | @@ -146810,11 +147147,17 @@ |
| 146810 | 147147 | assert( iDb>=0 && iDb<db->nDb ); |
| 146811 | 147148 | assert( db->aDb[iDb].pSchema ); |
| 146812 | 147149 | assert( sqlite3_mutex_held(db->mutex) ); |
| 146813 | 147150 | assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); |
| 146814 | 147151 | |
| 146815 | | - db->init.busy = 1; |
| 147152 | + db->init.busy = 1 + ((mFlags & INITFLAG_AlterAdd)!=0); |
| 147153 | + /* ^--- Any non-zero value for init.busy means that we are scanning |
| 147154 | + ** the sqlite_schema table to build the internal schema representation, |
| 147155 | + ** rather than running actual CREATE statements. init.busy==2 has the |
| 147156 | + ** additional meaning that the scan is happening as part of |
| 147157 | + ** ALTER TABLE ADD COLUMN, which is stricter in its enforcement of |
| 147158 | + ** function name resolution. */ |
| 146816 | 147159 | |
| 146817 | 147160 | /* Construct the in-memory representation schema tables (sqlite_schema or |
| 146818 | 147161 | ** sqlite_temp_schema) by invoking the parser directly. The appropriate |
| 146819 | 147162 | ** table name will be inserted automatically by the parser so we can just |
| 146820 | 147163 | ** use the abbreviation "x" here. The parser will also automatically tag |
| | @@ -164903,11 +165246,11 @@ |
| 164903 | 165246 | |
| 164904 | 165247 | /* Set up a new SrcList in pOrTab containing the table being scanned |
| 164905 | 165248 | ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. |
| 164906 | 165249 | ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). |
| 164907 | 165250 | */ |
| 164908 | | - if( pWInfo->nLevel>1 ){ |
| 165251 | + if( pWInfo->nLevel>1 || pTabItem->fg.fromExists ){ |
| 164909 | 165252 | int nNotReady; /* The number of notReady tables */ |
| 164910 | 165253 | SrcItem *origSrc; /* Original list of tables */ |
| 164911 | 165254 | nNotReady = pWInfo->nLevel - iLevel - 1; |
| 164912 | 165255 | pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); |
| 164913 | 165256 | if( pOrTab==0 ) return notReady; |
| | @@ -164916,10 +165259,17 @@ |
| 164916 | 165259 | memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); |
| 164917 | 165260 | origSrc = pWInfo->pTabList->a; |
| 164918 | 165261 | for(k=1; k<=nNotReady; k++){ |
| 164919 | 165262 | memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); |
| 164920 | 165263 | } |
| 165264 | + |
| 165265 | + /* Clear the fromExists flag on the OR-optimized table entry so that |
| 165266 | + ** the calls to sqlite3WhereEnd() do not code early-exits after the |
| 165267 | + ** first row is visited. The early exit applies to this table's |
| 165268 | + ** overall loop - including the multiple OR branches and any WHERE |
| 165269 | + ** conditions not passed to the sub-loops - not to the sub-loops. */ |
| 165270 | + pOrTab->a[0].fg.fromExists = 0; |
| 164921 | 165271 | }else{ |
| 164922 | 165272 | pOrTab = pWInfo->pTabList; |
| 164923 | 165273 | } |
| 164924 | 165274 | |
| 164925 | 165275 | /* Initialize the rowset register to contain NULL. An SQL NULL is |
| | @@ -165159,11 +165509,11 @@ |
| 165159 | 165509 | ** indent everything in between the this point and the final OP_Return. |
| 165160 | 165510 | ** See tag-20220407a in vdbe.c and shell.c */ |
| 165161 | 165511 | assert( pLevel->op==OP_Return ); |
| 165162 | 165512 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 165163 | 165513 | |
| 165164 | | - if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } |
| 165514 | + if( pWInfo->pTabList!=pOrTab ){ sqlite3DbFreeNN(db, pOrTab); } |
| 165165 | 165515 | if( !untestedTerms ) disableTerm(pLevel, pTerm); |
| 165166 | 165516 | }else |
| 165167 | 165517 | #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ |
| 165168 | 165518 | |
| 165169 | 165519 | { |
| | @@ -166508,20 +166858,18 @@ |
| 166508 | 166858 | ** 1. The SQLITE_Transitive optimization must be enabled |
| 166509 | 166859 | ** 2. Must be either an == or an IS operator |
| 166510 | 166860 | ** 3. Not originating in the ON clause of an OUTER JOIN |
| 166511 | 166861 | ** 4. The operator is not IS or else the query does not contain RIGHT JOIN |
| 166512 | 166862 | ** 5. The affinities of A and B must be compatible |
| 166513 | | -** 6a. Both operands use the same collating sequence OR |
| 166514 | | -** 6b. The overall collating sequence is BINARY |
| 166863 | +** 6. Both operands use the same collating sequence |
| 166515 | 166864 | ** If this routine returns TRUE, that means that the RHS can be substituted |
| 166516 | 166865 | ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. |
| 166517 | 166866 | ** This is an optimization. No harm comes from returning 0. But if 1 is |
| 166518 | 166867 | ** returned when it should not be, then incorrect answers might result. |
| 166519 | 166868 | */ |
| 166520 | 166869 | static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ |
| 166521 | 166870 | char aff1, aff2; |
| 166522 | | - CollSeq *pColl; |
| 166523 | 166871 | if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ |
| 166524 | 166872 | if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ |
| 166525 | 166873 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ |
| 166526 | 166874 | assert( pSrc!=0 ); |
| 166527 | 166875 | if( pExpr->op==TK_IS |
| | @@ -166535,14 +166883,11 @@ |
| 166535 | 166883 | if( aff1!=aff2 |
| 166536 | 166884 | && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) |
| 166537 | 166885 | ){ |
| 166538 | 166886 | return 0; /* (5) */ |
| 166539 | 166887 | } |
| 166540 | | - pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); |
| 166541 | | - if( !sqlite3IsBinary(pColl) |
| 166542 | | - && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) |
| 166543 | | - ){ |
| 166888 | + if( !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) ){ |
| 166544 | 166889 | return 0; /* (6) */ |
| 166545 | 166890 | } |
| 166546 | 166891 | return 1; |
| 166547 | 166892 | } |
| 166548 | 166893 | |
| | @@ -166870,11 +167215,11 @@ |
| 166870 | 167215 | |
| 166871 | 167216 | #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) |
| 166872 | 167217 | /* Analyze a term that is composed of two or more subterms connected by |
| 166873 | 167218 | ** an OR operator. |
| 166874 | 167219 | */ |
| 166875 | | - else if( pExpr->op==TK_OR ){ |
| 167220 | + else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ |
| 166876 | 167221 | assert( pWC->op==TK_AND ); |
| 166877 | 167222 | exprAnalyzeOrTerm(pSrc, pWC, idxTerm); |
| 166878 | 167223 | pTerm = &pWC->a[idxTerm]; |
| 166879 | 167224 | } |
| 166880 | 167225 | #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ |
| | @@ -170589,13 +170934,14 @@ |
| 170589 | 170934 | pLoop->nOut--; |
| 170590 | 170935 | if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 |
| 170591 | 170936 | && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ |
| 170592 | 170937 | ){ |
| 170593 | 170938 | Expr *pRight = pOpExpr->pRight; |
| 170939 | + Parse *pParse = pWC->pWInfo->pParse; |
| 170594 | 170940 | int k = 0; |
| 170595 | 170941 | testcase( pOpExpr->op==TK_IS ); |
| 170596 | | - if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ |
| 170942 | + if( sqlite3ExprIsInteger(pRight, &k, pParse) && k>=(-1) && k<=1 ){ |
| 170597 | 170943 | k = 10; |
| 170598 | 170944 | }else{ |
| 170599 | 170945 | k = 20; |
| 170600 | 170946 | } |
| 170601 | 170947 | if( iReduce<k ){ |
| | @@ -170688,11 +171034,12 @@ |
| 170688 | 171034 | testcase( pLhs->iColumn==XN_ROWID ); |
| 170689 | 171035 | aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); |
| 170690 | 171036 | idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); |
| 170691 | 171037 | if( aff!=idxaff ) break; |
| 170692 | 171038 | |
| 170693 | | - pColl = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); |
| 171039 | + if( ExprHasProperty(pTerm->pExpr, EP_Commuted) ) SWAP(Expr*, pRhs, pLhs); |
| 171040 | + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); |
| 170694 | 171041 | if( pColl==0 ) break; |
| 170695 | 171042 | if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; |
| 170696 | 171043 | } |
| 170697 | 171044 | return i; |
| 170698 | 171045 | } |
| | @@ -183162,13 +183509,15 @@ |
| 183162 | 183509 | case 196: /* expr ::= LP nexprlist COMMA expr RP */ |
| 183163 | 183510 | { |
| 183164 | 183511 | ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); |
| 183165 | 183512 | yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); |
| 183166 | 183513 | if( yymsp[-4].minor.yy454 ){ |
| 183514 | + int i; |
| 183167 | 183515 | yymsp[-4].minor.yy454->x.pList = pList; |
| 183168 | | - if( ALWAYS(pList->nExpr) ){ |
| 183169 | | - yymsp[-4].minor.yy454->flags |= pList->a[0].pExpr->flags & EP_Propagate; |
| 183516 | + for(i=0; i<pList->nExpr; i++){ |
| 183517 | + assert( pList->a[i].pExpr!=0 ); |
| 183518 | + yymsp[-4].minor.yy454->flags |= pList->a[i].pExpr->flags & EP_Propagate; |
| 183170 | 183519 | } |
| 183171 | 183520 | }else{ |
| 183172 | 183521 | sqlite3ExprListDelete(pParse->db, pList); |
| 183173 | 183522 | } |
| 183174 | 183523 | } |
| | @@ -183632,19 +183981,17 @@ |
| 183632 | 183981 | sqlite3AlterSetNotNull(pParse, yymsp[-7].minor.yy203, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0); |
| 183633 | 183982 | } |
| 183634 | 183983 | break; |
| 183635 | 183984 | case 300: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ |
| 183636 | 183985 | { |
| 183637 | | - sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1)); |
| 183986 | + sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); |
| 183638 | 183987 | } |
| 183639 | | - yy_destructor(yypParser,219,&yymsp[-2].minor); |
| 183640 | 183988 | break; |
| 183641 | 183989 | case 301: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ |
| 183642 | 183990 | { |
| 183643 | | - sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1)); |
| 183991 | + sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); |
| 183644 | 183992 | } |
| 183645 | | - yy_destructor(yypParser,219,&yymsp[-2].minor); |
| 183646 | 183993 | break; |
| 183647 | 183994 | case 302: /* cmd ::= create_vtab */ |
| 183648 | 183995 | {sqlite3VtabFinishParse(pParse,0);} |
| 183649 | 183996 | break; |
| 183650 | 183997 | case 303: /* cmd ::= create_vtab LP vtabarglist RP */ |
| | @@ -199171,11 +199518,11 @@ |
| 199171 | 199518 | break; |
| 199172 | 199519 | |
| 199173 | 199520 | /* State 3. The integer just read is a column number. */ |
| 199174 | 199521 | default: assert( eState==3 ); |
| 199175 | 199522 | iCol = (int)v; |
| 199176 | | - if( iCol<1 ){ |
| 199523 | + if( iCol<1 || iCol>0x3fffffff ){ |
| 199177 | 199524 | rc = SQLITE_CORRUPT_VTAB; |
| 199178 | 199525 | break; |
| 199179 | 199526 | } |
| 199180 | 199527 | if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; |
| 199181 | 199528 | pCsr->aStat[iCol+1].nDoc++; |
| | @@ -199861,10 +200208,11 @@ |
| 199861 | 200208 | /* If this is a "NEAR" keyword, check for an explicit nearness. */ |
| 199862 | 200209 | if( pKey->eType==FTSQUERY_NEAR ){ |
| 199863 | 200210 | assert( nKey==4 ); |
| 199864 | 200211 | if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ |
| 199865 | 200212 | nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear); |
| 200213 | + if( nNear>=1000000000 ) nNear = 1000000000; |
| 199866 | 200214 | } |
| 199867 | 200215 | } |
| 199868 | 200216 | |
| 199869 | 200217 | /* At this point this is probably a keyword. But for that to be true, |
| 199870 | 200218 | ** the next byte must contain either whitespace, an open or close |
| | @@ -209724,11 +210072,11 @@ |
| 209724 | 210072 | int nHit = fts3ColumnlistCount(&pIter); |
| 209725 | 210073 | if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ |
| 209726 | 210074 | if( p->flag==FTS3_MATCHINFO_LHITS ){ |
| 209727 | 210075 | p->aMatchinfo[iStart + iCol] = (u32)nHit; |
| 209728 | 210076 | }else if( nHit ){ |
| 209729 | | - p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F)); |
| 210077 | + p->aMatchinfo[iStart + iCol/32] |= (1U << (iCol&0x1F)); |
| 209730 | 210078 | } |
| 209731 | 210079 | } |
| 209732 | 210080 | assert( *pIter==0x00 || *pIter==0x01 ); |
| 209733 | 210081 | if( *pIter!=0x01 ) break; |
| 209734 | 210082 | pIter++; |
| | @@ -213744,11 +214092,11 @@ |
| 213744 | 214092 | break; |
| 213745 | 214093 | case '\n': |
| 213746 | 214094 | break; |
| 213747 | 214095 | case 0xe2: |
| 213748 | 214096 | /* '\' followed by either U+2028 or U+2029 is ignored as |
| 213749 | | - ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. |
| 214097 | + ** whitespace. Note that in UTF8, U+2028 is 0xe2 0x80 0x29. |
| 213750 | 214098 | ** U+2029 is the same except for the last byte */ |
| 213751 | 214099 | if( sz2<4 |
| 213752 | 214100 | || 0x80!=(u8)zIn[2] |
| 213753 | 214101 | || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) |
| 213754 | 214102 | ){ |
| | @@ -216313,15 +216661,13 @@ |
| 216313 | 216661 | char c; |
| 216314 | 216662 | JsonString *pStr; |
| 216315 | 216663 | UNUSED_PARAMETER(argc); |
| 216316 | 216664 | UNUSED_PARAMETER(argv); |
| 216317 | 216665 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 216318 | | -#ifdef NEVER |
| 216319 | 216666 | /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will |
| 216320 | 216667 | ** always have been called to initialize it */ |
| 216321 | 216668 | if( NEVER(!pStr) ) return; |
| 216322 | | -#endif |
| 216323 | 216669 | z = pStr->zBuf; |
| 216324 | 216670 | for(i=1; i<pStr->nUsed && ((c = z[i])!=',' || inStr || nNest); i++){ |
| 216325 | 216671 | if( c=='"' ){ |
| 216326 | 216672 | inStr = !inStr; |
| 216327 | 216673 | }else if( c=='\\' ){ |
| | @@ -216346,10 +216692,17 @@ |
| 216346 | 216692 | |
| 216347 | 216693 | /* |
| 216348 | 216694 | ** json_group_obj(NAME,VALUE) |
| 216349 | 216695 | ** |
| 216350 | 216696 | ** Return a JSON object composed of all names and values in the aggregate. |
| 216697 | +** |
| 216698 | +** Rows for which NAME is NULL do not result in a new entry. However, we |
| 216699 | +** do initially insert a "@" entry into the growing string for each null entry |
| 216700 | +** and change the first character of the string to "@" to signal that the |
| 216701 | +** string contains null entries. The "@" markers are needed in order to |
| 216702 | +** correctly process xInverse() requests. The initial "@" is converted |
| 216703 | +** back into "{" and the "@" null values are removed by jsonObjectCompute(). |
| 216351 | 216704 | */ |
| 216352 | 216705 | static void jsonObjectStep( |
| 216353 | 216706 | sqlite3_context *ctx, |
| 216354 | 216707 | int argc, |
| 216355 | 216708 | sqlite3_value **argv |
| | @@ -216363,49 +216716,97 @@ |
| 216363 | 216716 | z = (const char*)sqlite3_value_text(argv[0]); |
| 216364 | 216717 | n = sqlite3Strlen30(z); |
| 216365 | 216718 | if( pStr->zBuf==0 ){ |
| 216366 | 216719 | jsonStringInit(pStr, ctx); |
| 216367 | 216720 | jsonAppendChar(pStr, '{'); |
| 216368 | | - }else if( pStr->nUsed>1 && z!=0 ){ |
| 216721 | + }else if( pStr->nUsed>1 ){ |
| 216369 | 216722 | jsonAppendChar(pStr, ','); |
| 216370 | 216723 | } |
| 216371 | 216724 | pStr->pCtx = ctx; |
| 216372 | 216725 | if( z!=0 ){ |
| 216373 | 216726 | jsonAppendString(pStr, z, n); |
| 216374 | 216727 | jsonAppendChar(pStr, ':'); |
| 216375 | 216728 | jsonAppendSqlValue(pStr, argv[1]); |
| 216729 | + }else{ |
| 216730 | + pStr->zBuf[0] = '@'; |
| 216731 | + jsonAppendRawNZ(pStr, "@", 1); |
| 216376 | 216732 | } |
| 216377 | 216733 | } |
| 216378 | 216734 | } |
| 216379 | 216735 | static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ |
| 216380 | 216736 | JsonString *pStr; |
| 216381 | 216737 | int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); |
| 216382 | 216738 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 216383 | 216739 | if( pStr ){ |
| 216384 | | - jsonAppendRawNZ(pStr, "}", 2); |
| 216385 | | - jsonStringTrimOneChar(pStr); |
| 216740 | + JsonString *pOgStr = pStr; |
| 216741 | + JsonString tmpStr; |
| 216742 | + jsonAppendRawNZ(pOgStr, "}", 2); /* Ensure it is zero-terminated */ |
| 216743 | + jsonStringTrimOneChar(pOgStr); /* Remove the zero terminator */ |
| 216386 | 216744 | pStr->pCtx = ctx; |
| 216387 | 216745 | if( pStr->eErr ){ |
| 216388 | 216746 | jsonReturnString(pStr, 0, 0); |
| 216389 | 216747 | return; |
| 216390 | | - }else if( flags & JSON_BLOB ){ |
| 216748 | + } |
| 216749 | + if( pStr->zBuf[0]!='{' ){ |
| 216750 | + /* The string contains null entries that need to be removed */ |
| 216751 | + u64 i, j; |
| 216752 | + int inStr = 0; |
| 216753 | + if( !isFinal ){ |
| 216754 | + /* Work with a temporary copy of the string if this is not the |
| 216755 | + ** final result */ |
| 216756 | + jsonStringInit(&tmpStr, ctx); |
| 216757 | + jsonAppendRawNZ(&tmpStr, pStr->zBuf, pStr->nUsed+1); |
| 216758 | + pStr = &tmpStr; |
| 216759 | + if( pStr->eErr ){ |
| 216760 | + jsonReturnString(pStr, 0, 0); |
| 216761 | + return; |
| 216762 | + } |
| 216763 | + jsonStringTrimOneChar(pStr); /* Remove zero terminator */ |
| 216764 | + } |
| 216765 | + /* Fix up the string by changing the initial "@" flag back to |
| 216766 | + ** to "{" and removing all subsequence "@" entries, with their |
| 216767 | + ** associated comma delimeters. */ |
| 216768 | + pStr->zBuf[0] = '{'; |
| 216769 | + for(i=j=1; i<pStr->nUsed; i++){ |
| 216770 | + char c = pStr->zBuf[i]; |
| 216771 | + if( c=='"' ){ |
| 216772 | + inStr = !inStr; |
| 216773 | + pStr->zBuf[j++] = '"'; |
| 216774 | + }else if( c=='\\' ){ |
| 216775 | + pStr->zBuf[j++] = '\\'; |
| 216776 | + pStr->zBuf[j++] = pStr->zBuf[++i]; |
| 216777 | + }else if( c=='@' && !inStr ){ |
| 216778 | + assert( i+1<pStr->nUsed ); |
| 216779 | + if( pStr->zBuf[i+1]==',' ){ |
| 216780 | + i++; |
| 216781 | + }else if( pStr->zBuf[j-1]==',' ){ |
| 216782 | + j--; |
| 216783 | + } |
| 216784 | + }else{ |
| 216785 | + pStr->zBuf[j++] = c; |
| 216786 | + } |
| 216787 | + } |
| 216788 | + pStr->zBuf[j] = 0; /* Restore zero terminator */ |
| 216789 | + pStr->nUsed = j; /* Truncate the string */ |
| 216790 | + } |
| 216791 | + if( flags & JSON_BLOB ){ |
| 216391 | 216792 | jsonReturnStringAsBlob(pStr); |
| 216392 | 216793 | if( isFinal ){ |
| 216393 | 216794 | if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); |
| 216394 | 216795 | }else{ |
| 216395 | | - jsonStringTrimOneChar(pStr); |
| 216796 | + jsonStringTrimOneChar(pOgStr); |
| 216396 | 216797 | } |
| 216397 | | - return; |
| 216398 | 216798 | }else if( isFinal ){ |
| 216399 | 216799 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, |
| 216400 | 216800 | pStr->bStatic ? SQLITE_TRANSIENT : |
| 216401 | 216801 | sqlite3RCStrUnref); |
| 216402 | 216802 | pStr->bStatic = 1; |
| 216403 | 216803 | }else{ |
| 216404 | 216804 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); |
| 216405 | | - jsonStringTrimOneChar(pStr); |
| 216805 | + jsonStringTrimOneChar(pOgStr); |
| 216406 | 216806 | } |
| 216807 | + if( pStr!=pOgStr ) jsonStringReset(pStr); |
| 216407 | 216808 | }else if( flags & JSON_BLOB ){ |
| 216408 | 216809 | static const unsigned char emptyObject = 0x0c; |
| 216409 | 216810 | sqlite3_result_blob(ctx, &emptyObject, 1, SQLITE_STATIC); |
| 216410 | 216811 | }else{ |
| 216411 | 216812 | sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); |
| | @@ -218751,11 +219152,14 @@ |
| 218751 | 219152 | while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ |
| 218752 | 219153 | u8 *pCellData; |
| 218753 | 219154 | pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); |
| 218754 | 219155 | if( rc ) return rc; |
| 218755 | 219156 | nCell = NCELL(pNode); |
| 218756 | | - assert( nCell<200 ); |
| 219157 | + if( nCell>RTREE_MAXCELLS ){ |
| 219158 | + RTREE_IS_CORRUPT(pRtree); |
| 219159 | + return SQLITE_CORRUPT_VTAB; |
| 219160 | + } |
| 218757 | 219161 | pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); |
| 218758 | 219162 | while( p->iCell<nCell ){ |
| 218759 | 219163 | sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1; |
| 218760 | 219164 | eWithin = FULLY_WITHIN; |
| 218761 | 219165 | for(ii=0; ii<nConstraint; ii++){ |
| | @@ -223781,11 +224185,11 @@ |
| 223781 | 224185 | */ |
| 223782 | 224186 | static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ |
| 223783 | 224187 | const UChar *zInput; /* Pointer to input string */ |
| 223784 | 224188 | UChar *zOutput = 0; /* Pointer to output buffer */ |
| 223785 | 224189 | int nInput; /* Size of utf-16 input string in bytes */ |
| 223786 | | - int nOut; /* Size of output buffer in bytes */ |
| 224190 | + sqlite3_int64 nOut; /* Size of output buffer in bytes */ |
| 223787 | 224191 | int cnt; |
| 223788 | 224192 | int bToUpper; /* True for toupper(), false for tolower() */ |
| 223789 | 224193 | UErrorCode status; |
| 223790 | 224194 | const char *zLocale = 0; |
| 223791 | 224195 | |
| | @@ -223804,22 +224208,22 @@ |
| 223804 | 224208 | sqlite3_result_text16(p, "", 0, SQLITE_STATIC); |
| 223805 | 224209 | return; |
| 223806 | 224210 | } |
| 223807 | 224211 | |
| 223808 | 224212 | for(cnt=0; cnt<2; cnt++){ |
| 223809 | | - UChar *zNew = sqlite3_realloc(zOutput, nOut); |
| 224213 | + UChar *zNew = sqlite3_realloc64(zOutput, nOut); |
| 223810 | 224214 | if( zNew==0 ){ |
| 223811 | 224215 | sqlite3_free(zOutput); |
| 223812 | 224216 | sqlite3_result_error_nomem(p); |
| 223813 | 224217 | return; |
| 223814 | 224218 | } |
| 223815 | 224219 | zOutput = zNew; |
| 223816 | 224220 | status = U_ZERO_ERROR; |
| 223817 | 224221 | if( bToUpper ){ |
| 223818 | | - nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); |
| 224222 | + nOut = 2LL*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); |
| 223819 | 224223 | }else{ |
| 223820 | | - nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); |
| 224224 | + nOut = 2LL*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); |
| 223821 | 224225 | } |
| 223822 | 224226 | |
| 223823 | 224227 | if( U_SUCCESS(status) ){ |
| 223824 | 224228 | sqlite3_result_text16(p, zOutput, nOut, xFree); |
| 223825 | 224229 | }else if( status==U_BUFFER_OVERFLOW_ERROR ){ |
| | @@ -231535,16 +231939,17 @@ |
| 231535 | 231939 | if( NEVER(pBt==0) ) return SQLITE_OK; |
| 231536 | 231940 | pCsr->pPager = sqlite3BtreePager(pBt); |
| 231537 | 231941 | pCsr->szPage = sqlite3BtreeGetPageSize(pBt); |
| 231538 | 231942 | pCsr->mxPgno = sqlite3BtreeLastPage(pBt); |
| 231539 | 231943 | if( idxNum & 1 ){ |
| 231944 | + i64 iPg = sqlite3_value_int64(argv[idxNum>>1]); |
| 231540 | 231945 | assert( argc>(idxNum>>1) ); |
| 231541 | | - pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); |
| 231542 | | - if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ |
| 231946 | + if( iPg<1 || iPg>pCsr->mxPgno ){ |
| 231543 | 231947 | pCsr->pgno = 1; |
| 231544 | 231948 | pCsr->mxPgno = 0; |
| 231545 | 231949 | }else{ |
| 231950 | + pCsr->pgno = (Pgno)iPg; |
| 231546 | 231951 | pCsr->mxPgno = pCsr->pgno; |
| 231547 | 231952 | } |
| 231548 | 231953 | }else{ |
| 231549 | 231954 | assert( pCsr->pgno==1 ); |
| 231550 | 231955 | } |
| | @@ -231620,10 +232025,11 @@ |
| 231620 | 232025 | sqlite3_value **argv, |
| 231621 | 232026 | sqlite_int64 *pRowid |
| 231622 | 232027 | ){ |
| 231623 | 232028 | DbpageTable *pTab = (DbpageTable *)pVtab; |
| 231624 | 232029 | Pgno pgno; |
| 232030 | + sqlite3_int64 pgno64; |
| 231625 | 232031 | DbPage *pDbPage = 0; |
| 231626 | 232032 | int rc = SQLITE_OK; |
| 231627 | 232033 | char *zErr = 0; |
| 231628 | 232034 | int iDb; |
| 231629 | 232035 | Btree *pBt; |
| | @@ -231639,15 +232045,15 @@ |
| 231639 | 232045 | if( argc==1 ){ |
| 231640 | 232046 | zErr = "cannot delete"; |
| 231641 | 232047 | goto update_fail; |
| 231642 | 232048 | } |
| 231643 | 232049 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ |
| 231644 | | - pgno = (Pgno)sqlite3_value_int64(argv[2]); |
| 232050 | + pgno64 = sqlite3_value_int64(argv[2]); |
| 231645 | 232051 | isInsert = 1; |
| 231646 | 232052 | }else{ |
| 231647 | | - pgno = (Pgno)sqlite3_value_int64(argv[0]); |
| 231648 | | - if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ |
| 232053 | + pgno64 = (Pgno)sqlite3_value_int64(argv[0]); |
| 232054 | + if( sqlite3_value_int64(argv[1])!=pgno64 ){ |
| 231649 | 232055 | zErr = "cannot insert"; |
| 231650 | 232056 | goto update_fail; |
| 231651 | 232057 | } |
| 231652 | 232058 | isInsert = 0; |
| 231653 | 232059 | } |
| | @@ -231660,14 +232066,15 @@ |
| 231660 | 232066 | zErr = "no such schema"; |
| 231661 | 232067 | goto update_fail; |
| 231662 | 232068 | } |
| 231663 | 232069 | } |
| 231664 | 232070 | pBt = pTab->db->aDb[iDb].pBt; |
| 231665 | | - if( pgno<1 || NEVER(pBt==0) ){ |
| 232071 | + if( pgno64<1 || pgno64>4294967294 || NEVER(pBt==0) ){ |
| 231666 | 232072 | zErr = "bad page number"; |
| 231667 | 232073 | goto update_fail; |
| 231668 | 232074 | } |
| 232075 | + pgno = (Pgno)pgno64; |
| 231669 | 232076 | szPage = sqlite3BtreeGetPageSize(pBt); |
| 231670 | 232077 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB |
| 231671 | 232078 | || sqlite3_value_bytes(argv[3])!=szPage |
| 231672 | 232079 | ){ |
| 231673 | 232080 | if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ |
| | @@ -232688,11 +233095,13 @@ |
| 232688 | 233095 | /* |
| 232689 | 233096 | ** Read a varint value from aBuf[] into *piVal. Return the number of |
| 232690 | 233097 | ** bytes read. |
| 232691 | 233098 | */ |
| 232692 | 233099 | static int sessionVarintGet(const u8 *aBuf, int *piVal){ |
| 232693 | | - return getVarint32(aBuf, *piVal); |
| 233100 | + int ret = getVarint32(aBuf, *piVal); |
| 233101 | + *piVal = (*piVal & 0x7FFFFFFF); |
| 233102 | + return ret; |
| 232694 | 233103 | } |
| 232695 | 233104 | |
| 232696 | 233105 | /* |
| 232697 | 233106 | ** Read a varint value from buffer aBuf[], size nBuf bytes, into *piVal. |
| 232698 | 233107 | ** Return the number of bytes read. |
| | @@ -232703,11 +233112,11 @@ |
| 232703 | 233112 | memset(aCopy, 0, sizeof(aCopy)); |
| 232704 | 233113 | if( nBuf<sizeof(aCopy) ){ |
| 232705 | 233114 | memcpy(aCopy, aBuf, nBuf); |
| 232706 | 233115 | aRead = aCopy; |
| 232707 | 233116 | } |
| 232708 | | - return getVarint32(aRead, *piVal); |
| 233117 | + return sessionVarintGet(aRead, piVal); |
| 232709 | 233118 | } |
| 232710 | 233119 | |
| 232711 | 233120 | /* Load an unaligned and unsigned 32-bit integer */ |
| 232712 | 233121 | #define SESSION_UINT32(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) |
| 232713 | 233122 | |
| | @@ -234479,11 +234888,11 @@ |
| 234479 | 234888 | |
| 234480 | 234889 | if( zStmt==0 ){ |
| 234481 | 234890 | rc = SQLITE_NOMEM; |
| 234482 | 234891 | }else{ |
| 234483 | 234892 | sqlite3_stmt *pStmt; |
| 234484 | | - rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); |
| 234893 | + rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); |
| 234485 | 234894 | if( rc==SQLITE_OK ){ |
| 234486 | 234895 | SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; |
| 234487 | 234896 | pDiffCtx->pStmt = pStmt; |
| 234488 | 234897 | pDiffCtx->nOldOff = 0; |
| 234489 | 234898 | pDiffCtx->bRowid = pTab->bRowid; |
| | @@ -234542,11 +234951,11 @@ |
| 234542 | 234951 | ); |
| 234543 | 234952 | if( zStmt==0 || z1==0 || z2==0 ){ |
| 234544 | 234953 | rc = SQLITE_NOMEM; |
| 234545 | 234954 | }else{ |
| 234546 | 234955 | sqlite3_stmt *pStmt; |
| 234547 | | - rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); |
| 234956 | + rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); |
| 234548 | 234957 | |
| 234549 | 234958 | if( rc==SQLITE_OK ){ |
| 234550 | 234959 | SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; |
| 234551 | 234960 | pDiffCtx->pStmt = pStmt; |
| 234552 | 234961 | pDiffCtx->nOldOff = pTab->nCol; |
| | @@ -236036,21 +236445,25 @@ |
| 236036 | 236445 | int i; |
| 236037 | 236446 | for(i=0; rc==SQLITE_OK && i<nCol; i++){ |
| 236038 | 236447 | int eType; |
| 236039 | 236448 | rc = sessionInputBuffer(pIn, nByte + 10); |
| 236040 | 236449 | if( rc==SQLITE_OK ){ |
| 236041 | | - eType = pIn->aData[pIn->iNext + nByte++]; |
| 236042 | | - if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ |
| 236043 | | - int n; |
| 236044 | | - int nRem = pIn->nData - (pIn->iNext + nByte); |
| 236045 | | - nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem, &n); |
| 236046 | | - nByte += n; |
| 236047 | | - rc = sessionInputBuffer(pIn, nByte); |
| 236048 | | - }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ |
| 236049 | | - nByte += 8; |
| 236050 | | - }else if( eType!=0 && eType!=SQLITE_NULL ){ |
| 236450 | + if( pIn->iNext+nByte>=pIn->nData ){ |
| 236051 | 236451 | rc = SQLITE_CORRUPT_BKPT; |
| 236452 | + }else{ |
| 236453 | + eType = pIn->aData[pIn->iNext + nByte++]; |
| 236454 | + if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ |
| 236455 | + int n; |
| 236456 | + int nRem = pIn->nData - (pIn->iNext + nByte); |
| 236457 | + nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem,&n); |
| 236458 | + nByte += n; |
| 236459 | + rc = sessionInputBuffer(pIn, nByte); |
| 236460 | + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ |
| 236461 | + nByte += 8; |
| 236462 | + }else if( eType!=0 && eType!=SQLITE_NULL ){ |
| 236463 | + rc = SQLITE_CORRUPT_BKPT; |
| 236464 | + } |
| 236052 | 236465 | } |
| 236053 | 236466 | } |
| 236054 | 236467 | if( rc==SQLITE_OK && (pIn->iNext+nByte)>pIn->nData ){ |
| 236055 | 236468 | rc = SQLITE_CORRUPT_BKPT; |
| 236056 | 236469 | } |
| | @@ -237386,11 +237799,11 @@ |
| 237386 | 237799 | |
| 237387 | 237800 | /* Bind values to the UPDATE statement. */ |
| 237388 | 237801 | for(i=0; rc==SQLITE_OK && i<nCol; i++){ |
| 237389 | 237802 | sqlite3_value *pOld = sessionChangesetOld(pIter, i); |
| 237390 | 237803 | sqlite3_value *pNew = sessionChangesetNew(pIter, i); |
| 237391 | | - if( p->abPK[i] || (bPatchset==0 && pOld) ){ |
| 237804 | + if( pOld && (p->abPK[i] || bPatchset==0) ){ |
| 237392 | 237805 | rc = sessionBindValue(pUp, i*2+2, pOld); |
| 237393 | 237806 | } |
| 237394 | 237807 | if( rc==SQLITE_OK && pNew ){ |
| 237395 | 237808 | rc = sessionBindValue(pUp, i*2+1, pNew); |
| 237396 | 237809 | } |
| | @@ -239447,10 +239860,11 @@ |
| 239447 | 239860 | sqlite3_changegroup *pGrp, |
| 239448 | 239861 | int bDiscard, |
| 239449 | 239862 | char **pzErr |
| 239450 | 239863 | ){ |
| 239451 | 239864 | int rc = SQLITE_OK; |
| 239865 | + char *zErr = 0; |
| 239452 | 239866 | if( pGrp->cd.pTab ){ |
| 239453 | 239867 | SessionBuffer *aBuf = pGrp->cd.aBuf; |
| 239454 | 239868 | int ii; |
| 239455 | 239869 | |
| 239456 | 239870 | if( bDiscard==0 ){ |
| | @@ -239458,26 +239872,26 @@ |
| 239458 | 239872 | u8 eUndef = SQLITE_NULL; |
| 239459 | 239873 | if( pGrp->cd.eOp==SQLITE_UPDATE ){ |
| 239460 | 239874 | for(ii=0; ii<nBuf; ii++){ |
| 239461 | 239875 | if( pGrp->cd.pTab->abPK[ii] ){ |
| 239462 | 239876 | if( aBuf[ii].nBuf<=1 ){ |
| 239463 | | - *pzErr = sqlite3_mprintf( |
| 239877 | + zErr = sqlite3_mprintf( |
| 239464 | 239878 | "invalid change: %s value in PK of old.* record", |
| 239465 | 239879 | aBuf[ii].nBuf==1 ? "null" : "undefined" |
| 239466 | 239880 | ); |
| 239467 | 239881 | rc = SQLITE_ERROR; |
| 239468 | 239882 | break; |
| 239469 | 239883 | }else if( aBuf[ii + nBuf].nBuf>0 ){ |
| 239470 | | - *pzErr = sqlite3_mprintf( |
| 239884 | + zErr = sqlite3_mprintf( |
| 239471 | 239885 | "invalid change: defined value in PK of new.* record" |
| 239472 | 239886 | ); |
| 239473 | 239887 | rc = SQLITE_ERROR; |
| 239474 | 239888 | break; |
| 239475 | 239889 | } |
| 239476 | 239890 | }else |
| 239477 | 239891 | if( pGrp->bPatch==0 && (aBuf[ii].nBuf>0)!=(aBuf[ii+nBuf].nBuf>0) ){ |
| 239478 | | - *pzErr = sqlite3_mprintf( |
| 239892 | + zErr = sqlite3_mprintf( |
| 239479 | 239893 | "invalid change: column %d " |
| 239480 | 239894 | "- old.* value is %sdefined but new.* is %sdefined", |
| 239481 | 239895 | ii, aBuf[ii].nBuf ? "" : "un", aBuf[ii+nBuf].nBuf ? "" : "un" |
| 239482 | 239896 | ); |
| 239483 | 239897 | rc = SQLITE_ERROR; |
| | @@ -239490,18 +239904,18 @@ |
| 239490 | 239904 | for(ii=0; ii<nBuf; ii++){ |
| 239491 | 239905 | int isPK = pGrp->cd.pTab->abPK[ii]; |
| 239492 | 239906 | if( (pGrp->cd.eOp==SQLITE_INSERT || pGrp->bPatch==0 || isPK) |
| 239493 | 239907 | && aBuf[ii].nBuf==0 |
| 239494 | 239908 | ){ |
| 239495 | | - *pzErr = sqlite3_mprintf( |
| 239909 | + zErr = sqlite3_mprintf( |
| 239496 | 239910 | "invalid change: column %d is undefined", ii |
| 239497 | 239911 | ); |
| 239498 | 239912 | rc = SQLITE_ERROR; |
| 239499 | 239913 | break; |
| 239500 | 239914 | } |
| 239501 | 239915 | if( aBuf[ii].nBuf==1 && isPK ){ |
| 239502 | | - *pzErr = sqlite3_mprintf( |
| 239916 | + zErr = sqlite3_mprintf( |
| 239503 | 239917 | "invalid change: null value in PK" |
| 239504 | 239918 | ); |
| 239505 | 239919 | rc = SQLITE_ERROR; |
| 239506 | 239920 | break; |
| 239507 | 239921 | } |
| | @@ -239547,10 +239961,15 @@ |
| 239547 | 239961 | } |
| 239548 | 239962 | } |
| 239549 | 239963 | pGrp->cd.pTab = 0; |
| 239550 | 239964 | } |
| 239551 | 239965 | |
| 239966 | + if( pzErr ){ |
| 239967 | + *pzErr = zErr; |
| 239968 | + }else{ |
| 239969 | + sqlite3_free(zErr); |
| 239970 | + } |
| 239552 | 239971 | return rc; |
| 239553 | 239972 | } |
| 239554 | 239973 | |
| 239555 | 239974 | #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ |
| 239556 | 239975 | |
| | @@ -250006,11 +250425,11 @@ |
| 250006 | 250425 | } |
| 250007 | 250426 | |
| 250008 | 250427 | static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ |
| 250009 | 250428 | Fts5Data *pRet = fts5DataRead(p, iRowid); |
| 250010 | 250429 | if( pRet ){ |
| 250011 | | - if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){ |
| 250430 | + if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){ |
| 250012 | 250431 | FTS5_CORRUPT_ROWID(p, iRowid); |
| 250013 | 250432 | fts5DataRelease(pRet); |
| 250014 | 250433 | pRet = 0; |
| 250015 | 250434 | } |
| 250016 | 250435 | } |
| | @@ -251660,10 +252079,14 @@ |
| 251660 | 252079 | /* Figure out how many new bytes are in this term */ |
| 251661 | 252080 | fts5FastGetVarint32(a, iOff, nNew); |
| 251662 | 252081 | if( nKeep<nMatch ){ |
| 251663 | 252082 | goto search_failed; |
| 251664 | 252083 | } |
| 252084 | + if( (iOff+nNew)>n ){ |
| 252085 | + FTS5_CORRUPT_ITER(p, pIter); |
| 252086 | + return; |
| 252087 | + } |
| 251665 | 252088 | |
| 251666 | 252089 | assert( nKeep>=nMatch ); |
| 251667 | 252090 | if( nKeep==nMatch ){ |
| 251668 | 252091 | u32 nCmp; |
| 251669 | 252092 | u32 i; |
| | @@ -252786,11 +253209,11 @@ |
| 252786 | 253209 | } |
| 252787 | 253210 | |
| 252788 | 253211 | /* Advance pointer p until it points to pEnd or an 0x01 byte that is |
| 252789 | 253212 | ** not part of a varint */ |
| 252790 | 253213 | while( p<pEnd && *p!=0x01 ){ |
| 252791 | | - while( *p++ & 0x80 ); |
| 253214 | + while( p<pEnd && (*p++ & 0x80) ); |
| 252792 | 253215 | } |
| 252793 | 253216 | |
| 252794 | 253217 | if( pColset->aiCol[i]==iCurrent ){ |
| 252795 | 253218 | if( pColset->nCol==1 ){ |
| 252796 | 253219 | pIter->base.pData = aCopy; |
| | @@ -262254,11 +262677,11 @@ |
| 262254 | 262677 | int nArg, /* Number of args */ |
| 262255 | 262678 | sqlite3_value **apUnused /* Function arguments */ |
| 262256 | 262679 | ){ |
| 262257 | 262680 | assert( nArg==0 ); |
| 262258 | 262681 | UNUSED_PARAM2(nArg, apUnused); |
| 262259 | | - sqlite3_result_text(pCtx, "fts5: 2026-05-04 10:14:13 7e4134e3ff1ca8712f5fc78fadae665549450988dc43af27c7fe0c77f10ce3fb", -1, SQLITE_TRANSIENT); |
| 262682 | + sqlite3_result_text(pCtx, "fts5: 2026-05-21 15:14:35 9ac4a33a2932d353c4871fd8e09c10addf827f1fc3fc9380037d738cf2cd0353", -1, SQLITE_TRANSIENT); |
| 262260 | 262683 | } |
| 262261 | 262684 | |
| 262262 | 262685 | /* |
| 262263 | 262686 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 262264 | 262687 | ** |
| | @@ -264648,12 +265071,18 @@ |
| 264648 | 265071 | PorterTokenizer *pRet; |
| 264649 | 265072 | void *pUserdata = 0; |
| 264650 | 265073 | const char *zBase = "unicode61"; |
| 264651 | 265074 | fts5_tokenizer_v2 *pV2 = 0; |
| 264652 | 265075 | |
| 264653 | | - if( nArg>0 ){ |
| 264654 | | - zBase = azArg[0]; |
| 265076 | + while( nArg>0 ){ |
| 265077 | + if( sqlite3_stricmp(azArg[0],"porter")==0 ){ |
| 265078 | + nArg--; |
| 265079 | + azArg++; |
| 265080 | + }else{ |
| 265081 | + zBase = azArg[0]; |
| 265082 | + break; |
| 265083 | + } |
| 264655 | 265084 | } |
| 264656 | 265085 | |
| 264657 | 265086 | pRet = (PorterTokenizer*)sqlite3_malloc64(sizeof(PorterTokenizer)); |
| 264658 | 265087 | if( pRet ){ |
| 264659 | 265088 | memset(pRet, 0, sizeof(PorterTokenizer)); |
| 264660 | 265089 | |