| | @@ -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 | | -** e6784af6d50f715338ae3218fc8ba1b89488 with changes in files: |
| 21 | +** 18bda13e197e4b4ec7464b3e70012f71edc0 with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -465,11 +465,11 @@ |
| 465 | 465 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 466 | 466 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 467 | 467 | */ |
| 468 | 468 | #define SQLITE_VERSION "3.50.0" |
| 469 | 469 | #define SQLITE_VERSION_NUMBER 3050000 |
| 470 | | -#define SQLITE_SOURCE_ID "2025-02-25 18:10:47 e6784af6d50f715338ae3218fc8ba1b894883c27d797f0b7fd2625cac17d9cd7" |
| 470 | +#define SQLITE_SOURCE_ID "2025-03-16 00:13:29 18bda13e197e4b4ec7464b3e70012f71edc05f73d8b14bb48bad452f81c7e185" |
| 471 | 471 | |
| 472 | 472 | /* |
| 473 | 473 | ** CAPI3REF: Run-Time Library Version Numbers |
| 474 | 474 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 475 | 475 | ** |
| | @@ -5492,11 +5492,11 @@ |
| 5492 | 5492 | ** For all versions of SQLite up to and including 3.6.23.1, a call to |
| 5493 | 5493 | ** [sqlite3_reset()] was required after sqlite3_step() returned anything |
| 5494 | 5494 | ** other than [SQLITE_ROW] before any subsequent invocation of |
| 5495 | 5495 | ** sqlite3_step(). Failure to reset the prepared statement using |
| 5496 | 5496 | ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from |
| 5497 | | -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], |
| 5497 | +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), |
| 5498 | 5498 | ** sqlite3_step() began |
| 5499 | 5499 | ** calling [sqlite3_reset()] automatically in this circumstance rather |
| 5500 | 5500 | ** than returning [SQLITE_MISUSE]. This is not considered a compatibility |
| 5501 | 5501 | ** break because any application that ever receives an SQLITE_MISUSE error |
| 5502 | 5502 | ** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option |
| | @@ -7388,10 +7388,12 @@ |
| 7388 | 7388 | ** ^Any callback set by a previous call to this function |
| 7389 | 7389 | ** for the same database connection is overridden. |
| 7390 | 7390 | ** |
| 7391 | 7391 | ** ^The second argument is a pointer to the function to invoke when a |
| 7392 | 7392 | ** row is updated, inserted or deleted in a rowid table. |
| 7393 | +** ^The update hook is disabled by invoking sqlite3_update_hook() |
| 7394 | +** with a NULL pointer as the second parameter. |
| 7393 | 7395 | ** ^The first argument to the callback is a copy of the third argument |
| 7394 | 7396 | ** to sqlite3_update_hook(). |
| 7395 | 7397 | ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], |
| 7396 | 7398 | ** or [SQLITE_UPDATE], depending on the operation that caused the callback |
| 7397 | 7399 | ** to be invoked. |
| | @@ -15170,11 +15172,21 @@ |
| 15170 | 15172 | /* |
| 15171 | 15173 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 15172 | 15174 | ** ourselves. |
| 15173 | 15175 | */ |
| 15174 | 15176 | #ifndef offsetof |
| 15175 | | -#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) |
| 15177 | +#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 15178 | +#endif |
| 15179 | + |
| 15180 | +/* |
| 15181 | +** Work around C99 "flex-array" syntax for pre-C99 compilers, so as |
| 15182 | +** to avoid complaints from -fsanitize=strict-bounds. |
| 15183 | +*/ |
| 15184 | +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 15185 | +# define FLEXARRAY |
| 15186 | +#else |
| 15187 | +# define FLEXARRAY 1 |
| 15176 | 15188 | #endif |
| 15177 | 15189 | |
| 15178 | 15190 | /* |
| 15179 | 15191 | ** Macros to compute minimum and maximum of two numbers. |
| 15180 | 15192 | */ |
| | @@ -17405,12 +17417,12 @@ |
| 17405 | 17417 | SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); |
| 17406 | 17418 | #ifdef SQLITE_ENABLE_BYTECODE_VTAB |
| 17407 | 17419 | SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); |
| 17408 | 17420 | #endif |
| 17409 | 17421 | |
| 17410 | | -/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on |
| 17411 | | -** each VDBE opcode. |
| 17422 | +/* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra |
| 17423 | +** comments on each VDBE opcode. |
| 17412 | 17424 | ** |
| 17413 | 17425 | ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op |
| 17414 | 17426 | ** comments in VDBE programs that show key decision points in the code |
| 17415 | 17427 | ** generator. |
| 17416 | 17428 | */ |
| | @@ -18945,12 +18957,16 @@ |
| 18945 | 18957 | u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ |
| 18946 | 18958 | Trigger *apTrigger[2];/* Triggers for aAction[] actions */ |
| 18947 | 18959 | struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ |
| 18948 | 18960 | int iFrom; /* Index of column in pFrom */ |
| 18949 | 18961 | char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ |
| 18950 | | - } aCol[1]; /* One entry for each of nCol columns */ |
| 18962 | + } aCol[FLEXARRAY]; /* One entry for each of nCol columns */ |
| 18951 | 18963 | }; |
| 18964 | + |
| 18965 | +/* The size (in bytes) of an FKey object holding N columns. The answer |
| 18966 | +** does NOT include space to hold the zTo name. */ |
| 18967 | +#define SZ_FKEY(N) (offsetof(FKey,aCol)+(N)*sizeof(struct sColMap)) |
| 18952 | 18968 | |
| 18953 | 18969 | /* |
| 18954 | 18970 | ** SQLite supports many different ways to resolve a constraint |
| 18955 | 18971 | ** error. ROLLBACK processing means that a constraint violation |
| 18956 | 18972 | ** causes the operation in process to fail and for the current transaction |
| | @@ -19009,13 +19025,16 @@ |
| 19009 | 19025 | u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ |
| 19010 | 19026 | u16 nKeyField; /* Number of key columns in the index */ |
| 19011 | 19027 | u16 nAllField; /* Total columns, including key plus others */ |
| 19012 | 19028 | sqlite3 *db; /* The database connection */ |
| 19013 | 19029 | u8 *aSortFlags; /* Sort order for each column. */ |
| 19014 | | - CollSeq *aColl[1]; /* Collating sequence for each term of the key */ |
| 19030 | + CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ |
| 19015 | 19031 | }; |
| 19016 | 19032 | |
| 19033 | +/* The size (in bytes) of a KeyInfo object with up to N fields */ |
| 19034 | +#define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) |
| 19035 | + |
| 19017 | 19036 | /* |
| 19018 | 19037 | ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. |
| 19019 | 19038 | */ |
| 19020 | 19039 | #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ |
| 19021 | 19040 | #define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */ |
| | @@ -19584,12 +19603,17 @@ |
| 19584 | 19603 | u16 iAlias; /* Index into Parse.aAlias[] for zName */ |
| 19585 | 19604 | } x; |
| 19586 | 19605 | int iConstExprReg; /* Register in which Expr value is cached. Used only |
| 19587 | 19606 | ** by Parse.pConstExpr */ |
| 19588 | 19607 | } u; |
| 19589 | | - } a[1]; /* One slot for each expression in the list */ |
| 19608 | + } a[FLEXARRAY]; /* One slot for each expression in the list */ |
| 19590 | 19609 | }; |
| 19610 | + |
| 19611 | +/* The size (in bytes) of an ExprList object that is big enough to hold |
| 19612 | +** as many as N expressions. */ |
| 19613 | +#define SZ_EXPRLIST(N) \ |
| 19614 | + (offsetof(ExprList,a) + (N)*sizeof(struct ExprList_item)) |
| 19591 | 19615 | |
| 19592 | 19616 | /* |
| 19593 | 19617 | ** Allowed values for Expr.a.eEName |
| 19594 | 19618 | */ |
| 19595 | 19619 | #define ENAME_NAME 0 /* The AS clause of a result set */ |
| | @@ -19614,13 +19638,16 @@ |
| 19614 | 19638 | */ |
| 19615 | 19639 | struct IdList { |
| 19616 | 19640 | int nId; /* Number of identifiers on the list */ |
| 19617 | 19641 | struct IdList_item { |
| 19618 | 19642 | char *zName; /* Name of the identifier */ |
| 19619 | | - } a[1]; |
| 19643 | + } a[FLEXARRAY]; |
| 19620 | 19644 | }; |
| 19621 | 19645 | |
| 19646 | +/* The size (in bytes) of an IdList object that can hold up to N IDs. */ |
| 19647 | +#define SZ_IDLIST(N) (offsetof(IdList,a)+(N)*sizeof(struct IdList_item)) |
| 19648 | + |
| 19622 | 19649 | /* |
| 19623 | 19650 | ** Allowed values for IdList.eType, which determines which value of the a.u4 |
| 19624 | 19651 | ** is valid. |
| 19625 | 19652 | */ |
| 19626 | 19653 | #define EU4_NONE 0 /* Does not use IdList.a.u4 */ |
| | @@ -19736,14 +19763,22 @@ |
| 19736 | 19763 | ** is used to hold the FROM clause of a SELECT statement. SrcList also |
| 19737 | 19764 | ** represents the target tables for DELETE, INSERT, and UPDATE statements. |
| 19738 | 19765 | ** |
| 19739 | 19766 | */ |
| 19740 | 19767 | struct SrcList { |
| 19741 | | - int nSrc; /* Number of tables or subqueries in the FROM clause */ |
| 19742 | | - u32 nAlloc; /* Number of entries allocated in a[] below */ |
| 19743 | | - SrcItem a[1]; /* One entry for each identifier on the list */ |
| 19768 | + int nSrc; /* Number of tables or subqueries in the FROM clause */ |
| 19769 | + u32 nAlloc; /* Number of entries allocated in a[] below */ |
| 19770 | + SrcItem a[FLEXARRAY]; /* One entry for each identifier on the list */ |
| 19744 | 19771 | }; |
| 19772 | + |
| 19773 | +/* Size (in bytes) of a SrcList object that can hold as many as N |
| 19774 | +** SrcItem objects. */ |
| 19775 | +#define SZ_SRCLIST(N) (offsetof(SrcList,a)+(N)*sizeof(SrcItem)) |
| 19776 | + |
| 19777 | +/* Size (in bytes( of a SrcList object that holds 1 SrcItem. This is a |
| 19778 | +** special case of SZ_SRCITEM(1) that comes up often. */ |
| 19779 | +#define SZ_SRCLIST_1 (offsetof(SrcList,a)+sizeof(SrcItem)) |
| 19745 | 19780 | |
| 19746 | 19781 | /* |
| 19747 | 19782 | ** Permitted values of the SrcList.a.jointype field |
| 19748 | 19783 | */ |
| 19749 | 19784 | #define JT_INNER 0x01 /* Any kind of inner or cross join */ |
| | @@ -20804,12 +20839,16 @@ |
| 20804 | 20839 | */ |
| 20805 | 20840 | struct With { |
| 20806 | 20841 | int nCte; /* Number of CTEs in the WITH clause */ |
| 20807 | 20842 | int bView; /* Belongs to the outermost Select of a view */ |
| 20808 | 20843 | With *pOuter; /* Containing WITH clause, or NULL */ |
| 20809 | | - Cte a[1]; /* For each CTE in the WITH clause.... */ |
| 20844 | + Cte a[FLEXARRAY]; /* For each CTE in the WITH clause.... */ |
| 20810 | 20845 | }; |
| 20846 | + |
| 20847 | +/* The size (in bytes) of a With object that can hold as many |
| 20848 | +** as N different CTEs. */ |
| 20849 | +#define SZ_WITH(N) (offsetof(With,a) + (N)*sizeof(Cte)) |
| 20811 | 20850 | |
| 20812 | 20851 | /* |
| 20813 | 20852 | ** The Cte object is not guaranteed to persist for the entire duration |
| 20814 | 20853 | ** of code generation. (The query flattener or other parser tree |
| 20815 | 20854 | ** edits might delete it.) The following object records information |
| | @@ -20835,12 +20874,16 @@ |
| 20835 | 20874 | */ |
| 20836 | 20875 | struct DbClientData { |
| 20837 | 20876 | DbClientData *pNext; /* Next in a linked list */ |
| 20838 | 20877 | void *pData; /* The data */ |
| 20839 | 20878 | void (*xDestructor)(void*); /* Destructor. Might be NULL */ |
| 20840 | | - char zName[1]; /* Name of this client data. MUST BE LAST */ |
| 20879 | + char zName[FLEXARRAY]; /* Name of this client data. MUST BE LAST */ |
| 20841 | 20880 | }; |
| 20881 | + |
| 20882 | +/* The size (in bytes) of a DbClientData object that can has a name |
| 20883 | +** that is N bytes long, including the zero-terminator. */ |
| 20884 | +#define SZ_DBCLIENTDATA(N) (offsetof(DbClientData,zName)+(N)) |
| 20842 | 20885 | |
| 20843 | 20886 | #ifdef SQLITE_DEBUG |
| 20844 | 20887 | /* |
| 20845 | 20888 | ** An instance of the TreeView object is used for printing the content of |
| 20846 | 20889 | ** data structures on sqlite3DebugPrintf() using a tree-like view. |
| | @@ -22673,10 +22716,13 @@ |
| 22673 | 22716 | "EXTRA_IFNULLROW", |
| 22674 | 22717 | #endif |
| 22675 | 22718 | #ifdef SQLITE_EXTRA_INIT |
| 22676 | 22719 | "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), |
| 22677 | 22720 | #endif |
| 22721 | +#ifdef SQLITE_EXTRA_INIT_MUTEXED |
| 22722 | + "EXTRA_INIT_MUTEXED=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT_MUTEXED), |
| 22723 | +#endif |
| 22678 | 22724 | #ifdef SQLITE_EXTRA_SHUTDOWN |
| 22679 | 22725 | "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), |
| 22680 | 22726 | #endif |
| 22681 | 22727 | #ifdef SQLITE_FTS3_MAX_EXPR_DEPTH |
| 22682 | 22728 | "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), |
| | @@ -23657,16 +23703,23 @@ |
| 23657 | 23703 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 23658 | 23704 | u64 maskUsed; /* Mask of columns used by this cursor */ |
| 23659 | 23705 | #endif |
| 23660 | 23706 | VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ |
| 23661 | 23707 | |
| 23662 | | - /* 2*nField extra array elements allocated for aType[], beyond the one |
| 23663 | | - ** static element declared in the structure. nField total array slots for |
| 23664 | | - ** aType[] and nField+1 array slots for aOffset[] */ |
| 23665 | | - u32 aType[1]; /* Type values record decode. MUST BE LAST */ |
| 23708 | + /* Space is allocated for aType to hold at least 2*nField+1 entries: |
| 23709 | + ** nField slots for aType[] and nField+1 array slots for aOffset[] */ |
| 23710 | + u32 aType[FLEXARRAY]; /* Type values record decode. MUST BE LAST */ |
| 23666 | 23711 | }; |
| 23667 | 23712 | |
| 23713 | +/* |
| 23714 | +** The size (in bytes) of a VdbeCursor object that has an nField value of N |
| 23715 | +** or less. The value of SZ_VDBECURSOR(n) is guaranteed to be a multiple |
| 23716 | +** of 8. |
| 23717 | +*/ |
| 23718 | +#define SZ_VDBECURSOR(N) \ |
| 23719 | + (ROUND8(offsetof(VdbeCursor,aType)) + ((N)+1)*sizeof(u64)) |
| 23720 | + |
| 23668 | 23721 | /* Return true if P is a null-only cursor |
| 23669 | 23722 | */ |
| 23670 | 23723 | #define IsNullCursor(P) \ |
| 23671 | 23724 | ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) |
| 23672 | 23725 | |
| | @@ -23919,13 +23972,20 @@ |
| 23919 | 23972 | int iOp; /* Instruction number of OP_Function */ |
| 23920 | 23973 | int isError; /* Error code returned by the function. */ |
| 23921 | 23974 | u8 enc; /* Encoding to use for results */ |
| 23922 | 23975 | u8 skipFlag; /* Skip accumulator loading if true */ |
| 23923 | 23976 | u16 argc; /* Number of arguments */ |
| 23924 | | - sqlite3_value *argv[1]; /* Argument set */ |
| 23977 | + sqlite3_value *argv[FLEXARRAY]; /* Argument set */ |
| 23925 | 23978 | }; |
| 23926 | 23979 | |
| 23980 | +/* |
| 23981 | +** The size (in bytes) of an sqlite3_context object that holds N |
| 23982 | +** argv[] arguments. |
| 23983 | +*/ |
| 23984 | +#define SZ_CONTEXT(N) \ |
| 23985 | + (offsetof(sqlite3_context,argv)+(N)*sizeof(sqlite3_value*)) |
| 23986 | + |
| 23927 | 23987 | |
| 23928 | 23988 | /* The ScanStatus object holds a single value for the |
| 23929 | 23989 | ** sqlite3_stmt_scanstatus() interface. |
| 23930 | 23990 | ** |
| 23931 | 23991 | ** aAddrRange[]: |
| | @@ -24055,11 +24115,11 @@ |
| 24055 | 24115 | struct PreUpdate { |
| 24056 | 24116 | Vdbe *v; |
| 24057 | 24117 | VdbeCursor *pCsr; /* Cursor to read old values from */ |
| 24058 | 24118 | int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ |
| 24059 | 24119 | u8 *aRecord; /* old.* database record */ |
| 24060 | | - KeyInfo keyinfo; |
| 24120 | + KeyInfo *pKeyinfo; /* Key information */ |
| 24061 | 24121 | UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ |
| 24062 | 24122 | UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ |
| 24063 | 24123 | int iNewReg; /* Register for new.* values */ |
| 24064 | 24124 | int iBlobWrite; /* Value returned by preupdate_blobwrite() */ |
| 24065 | 24125 | i64 iKey1; /* First key value passed to hook */ |
| | @@ -24067,10 +24127,11 @@ |
| 24067 | 24127 | Mem oldipk; /* Memory cell holding "old" IPK value */ |
| 24068 | 24128 | Mem *aNew; /* Array of new.* values */ |
| 24069 | 24129 | Table *pTab; /* Schema object being updated */ |
| 24070 | 24130 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 24071 | 24131 | sqlite3_value **apDflt; /* Array of default values, if required */ |
| 24132 | + u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ |
| 24072 | 24133 | }; |
| 24073 | 24134 | |
| 24074 | 24135 | /* |
| 24075 | 24136 | ** An instance of this object is used to pass an vector of values into |
| 24076 | 24137 | ** OP_VFilter, the xFilter method of a virtual table. The vector is the |
| | @@ -26000,11 +26061,11 @@ |
| 26000 | 26061 | ** Return the number of days after the most recent Sunday. |
| 26001 | 26062 | ** |
| 26002 | 26063 | ** In other words, return the day of the week according |
| 26003 | 26064 | ** to this code: |
| 26004 | 26065 | ** |
| 26005 | | -** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday |
| 26066 | +** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday |
| 26006 | 26067 | */ |
| 26007 | 26068 | static int daysAfterSunday(DateTime *pDate){ |
| 26008 | 26069 | assert( pDate->validJD ); |
| 26009 | 26070 | return (int)((pDate->iJD+129600000)/86400000) % 7; |
| 26010 | 26071 | } |
| | @@ -32378,11 +32439,11 @@ |
| 32378 | 32439 | u32 nBack = 0; |
| 32379 | 32440 | u32 nCtrl = 0; |
| 32380 | 32441 | for(k=0; k<i; k++){ |
| 32381 | 32442 | if( escarg[k]=='\\' ){ |
| 32382 | 32443 | nBack++; |
| 32383 | | - }else if( escarg[k]<=0x1f ){ |
| 32444 | + }else if( ((u8*)escarg)[k]<=0x1f ){ |
| 32384 | 32445 | nCtrl++; |
| 32385 | 32446 | } |
| 32386 | 32447 | } |
| 32387 | 32448 | if( nCtrl || xtype==etESCAPE_q ){ |
| 32388 | 32449 | n += nBack + 5*nCtrl; |
| | @@ -32416,11 +32477,11 @@ |
| 32416 | 32477 | bufpt[j++] = ch = escarg[i]; |
| 32417 | 32478 | if( ch==q ){ |
| 32418 | 32479 | bufpt[j++] = ch; |
| 32419 | 32480 | }else if( ch=='\\' ){ |
| 32420 | 32481 | bufpt[j++] = '\\'; |
| 32421 | | - }else if( ch<=0x1f ){ |
| 32482 | + }else if( ((unsigned char)ch)<=0x1f ){ |
| 32422 | 32483 | bufpt[j-1] = '\\'; |
| 32423 | 32484 | bufpt[j++] = 'u'; |
| 32424 | 32485 | bufpt[j++] = '0'; |
| 32425 | 32486 | bufpt[j++] = '0'; |
| 32426 | 32487 | bufpt[j++] = ch>=0x10 ? '1' : '0'; |
| | @@ -37067,11 +37128,11 @@ |
| 37067 | 37128 | return 0; |
| 37068 | 37129 | #endif |
| 37069 | 37130 | } |
| 37070 | 37131 | |
| 37071 | 37132 | /* |
| 37072 | | -** Compute the absolute value of a 32-bit signed integer, of possible. Or |
| 37133 | +** Compute the absolute value of a 32-bit signed integer, if possible. Or |
| 37073 | 37134 | ** if the integer has a value of -2147483648, return +2147483647 |
| 37074 | 37135 | */ |
| 37075 | 37136 | SQLITE_PRIVATE int sqlite3AbsInt32(int x){ |
| 37076 | 37137 | if( x>=0 ) return x; |
| 37077 | 37138 | if( x==(int)0x80000000 ) return 0x7fffffff; |
| | @@ -45614,11 +45675,11 @@ |
| 45614 | 45675 | sp.tv_sec = microseconds / 1000000; |
| 45615 | 45676 | sp.tv_nsec = (microseconds % 1000000) * 1000; |
| 45616 | 45677 | |
| 45617 | 45678 | /* Almost all modern unix systems support nanosleep(). But if you are |
| 45618 | 45679 | ** compiling for one of the rare exceptions, you can use |
| 45619 | | - ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if |
| 45680 | + ** -DHAVE_NANOSLEEP=0 (perhaps in conjunction with -DHAVE_USLEEP if |
| 45620 | 45681 | ** usleep() is available) in order to bypass the use of nanosleep() */ |
| 45621 | 45682 | nanosleep(&sp, NULL); |
| 45622 | 45683 | |
| 45623 | 45684 | UNUSED_PARAMETER(NotUsed); |
| 45624 | 45685 | return microseconds; |
| | @@ -56047,14 +56108,10 @@ |
| 56047 | 56108 | void *pStart, *pEnd; /* Bounds of global page cache memory */ |
| 56048 | 56109 | /* Above requires no mutex. Use mutex below for variable that follow. */ |
| 56049 | 56110 | sqlite3_mutex *mutex; /* Mutex for accessing the following: */ |
| 56050 | 56111 | PgFreeslot *pFree; /* Free page blocks */ |
| 56051 | 56112 | int nFreeSlot; /* Number of unused pcache slots */ |
| 56052 | | - /* The following value requires a mutex to change. We skip the mutex on |
| 56053 | | - ** reading because (1) most platforms read a 32-bit integer atomically and |
| 56054 | | - ** (2) even if an incorrect value is read, no great harm is done since this |
| 56055 | | - ** is really just an optimization. */ |
| 56056 | 56113 | int bUnderPressure; /* True if low on PAGECACHE memory */ |
| 56057 | 56114 | } pcache1_g; |
| 56058 | 56115 | |
| 56059 | 56116 | /* |
| 56060 | 56117 | ** All code in this file should access the global structure above via the |
| | @@ -56098,11 +56155,11 @@ |
| 56098 | 56155 | pcache1.szSlot = sz; |
| 56099 | 56156 | pcache1.nSlot = pcache1.nFreeSlot = n; |
| 56100 | 56157 | pcache1.nReserve = n>90 ? 10 : (n/10 + 1); |
| 56101 | 56158 | pcache1.pStart = pBuf; |
| 56102 | 56159 | pcache1.pFree = 0; |
| 56103 | | - pcache1.bUnderPressure = 0; |
| 56160 | + AtomicStore(&pcache1.bUnderPressure,0); |
| 56104 | 56161 | while( n-- ){ |
| 56105 | 56162 | p = (PgFreeslot*)pBuf; |
| 56106 | 56163 | p->pNext = pcache1.pFree; |
| 56107 | 56164 | pcache1.pFree = p; |
| 56108 | 56165 | pBuf = (void*)&((char*)pBuf)[sz]; |
| | @@ -56166,11 +56223,11 @@ |
| 56166 | 56223 | sqlite3_mutex_enter(pcache1.mutex); |
| 56167 | 56224 | p = (PgHdr1 *)pcache1.pFree; |
| 56168 | 56225 | if( p ){ |
| 56169 | 56226 | pcache1.pFree = pcache1.pFree->pNext; |
| 56170 | 56227 | pcache1.nFreeSlot--; |
| 56171 | | - pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; |
| 56228 | + AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve); |
| 56172 | 56229 | assert( pcache1.nFreeSlot>=0 ); |
| 56173 | 56230 | sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); |
| 56174 | 56231 | sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); |
| 56175 | 56232 | } |
| 56176 | 56233 | sqlite3_mutex_leave(pcache1.mutex); |
| | @@ -56205,11 +56262,11 @@ |
| 56205 | 56262 | sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); |
| 56206 | 56263 | pSlot = (PgFreeslot*)p; |
| 56207 | 56264 | pSlot->pNext = pcache1.pFree; |
| 56208 | 56265 | pcache1.pFree = pSlot; |
| 56209 | 56266 | pcache1.nFreeSlot++; |
| 56210 | | - pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve; |
| 56267 | + AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve); |
| 56211 | 56268 | assert( pcache1.nFreeSlot<=pcache1.nSlot ); |
| 56212 | 56269 | sqlite3_mutex_leave(pcache1.mutex); |
| 56213 | 56270 | }else{ |
| 56214 | 56271 | assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); |
| 56215 | 56272 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| | @@ -56336,11 +56393,11 @@ |
| 56336 | 56393 | ** allocating a new page cache entry in order to avoid stressing |
| 56337 | 56394 | ** the heap even further. |
| 56338 | 56395 | */ |
| 56339 | 56396 | static int pcache1UnderMemoryPressure(PCache1 *pCache){ |
| 56340 | 56397 | if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ |
| 56341 | | - return pcache1.bUnderPressure; |
| 56398 | + return AtomicLoad(&pcache1.bUnderPressure); |
| 56342 | 56399 | }else{ |
| 56343 | 56400 | return sqlite3HeapNearlyFull(); |
| 56344 | 56401 | } |
| 56345 | 56402 | } |
| 56346 | 56403 | |
| | @@ -66177,12 +66234,16 @@ |
| 66177 | 66234 | int iNext; /* Next slot in aIndex[] not yet returned */ |
| 66178 | 66235 | ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ |
| 66179 | 66236 | u32 *aPgno; /* Array of page numbers. */ |
| 66180 | 66237 | int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ |
| 66181 | 66238 | int iZero; /* Frame number associated with aPgno[0] */ |
| 66182 | | - } aSegment[1]; /* One for every 32KB page in the wal-index */ |
| 66239 | + } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */ |
| 66183 | 66240 | }; |
| 66241 | + |
| 66242 | +/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ |
| 66243 | +#define SZ_WALITERATOR(N) \ |
| 66244 | + (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment)) |
| 66184 | 66245 | |
| 66185 | 66246 | /* |
| 66186 | 66247 | ** Define the parameters of the hash tables in the wal-index file. There |
| 66187 | 66248 | ** is a hash-table following every HASHTABLE_NPAGE page numbers in the |
| 66188 | 66249 | ** wal-index. |
| | @@ -67540,12 +67601,11 @@ |
| 67540 | 67601 | assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); |
| 67541 | 67602 | iLast = pWal->hdr.mxFrame; |
| 67542 | 67603 | |
| 67543 | 67604 | /* Allocate space for the WalIterator object. */ |
| 67544 | 67605 | nSegment = walFramePage(iLast) + 1; |
| 67545 | | - nByte = sizeof(WalIterator) |
| 67546 | | - + (nSegment-1)*sizeof(struct WalSegment) |
| 67606 | + nByte = SZ_WALITERATOR(nSegment) |
| 67547 | 67607 | + iLast*sizeof(ht_slot); |
| 67548 | 67608 | p = (WalIterator *)sqlite3_malloc64(nByte |
| 67549 | 67609 | + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) |
| 67550 | 67610 | ); |
| 67551 | 67611 | if( !p ){ |
| | @@ -86029,16 +86089,14 @@ |
| 86029 | 86089 | int nArg, /* Number of argument */ |
| 86030 | 86090 | const FuncDef *pFunc, /* The function to be invoked */ |
| 86031 | 86091 | int eCallCtx /* Calling context */ |
| 86032 | 86092 | ){ |
| 86033 | 86093 | Vdbe *v = pParse->pVdbe; |
| 86034 | | - int nByte; |
| 86035 | 86094 | int addr; |
| 86036 | 86095 | sqlite3_context *pCtx; |
| 86037 | 86096 | assert( v ); |
| 86038 | | - nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); |
| 86039 | | - pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); |
| 86097 | + pCtx = sqlite3DbMallocRawNN(pParse->db, SZ_CONTEXT(nArg)); |
| 86040 | 86098 | if( pCtx==0 ){ |
| 86041 | 86099 | assert( pParse->db->mallocFailed ); |
| 86042 | 86100 | freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); |
| 86043 | 86101 | return 0; |
| 86044 | 86102 | } |
| | @@ -91110,25 +91168,26 @@ |
| 91110 | 91168 | |
| 91111 | 91169 | preupdate.v = v; |
| 91112 | 91170 | preupdate.pCsr = pCsr; |
| 91113 | 91171 | preupdate.op = op; |
| 91114 | 91172 | preupdate.iNewReg = iReg; |
| 91115 | | - preupdate.keyinfo.db = db; |
| 91116 | | - preupdate.keyinfo.enc = ENC(db); |
| 91117 | | - preupdate.keyinfo.nKeyField = pTab->nCol; |
| 91118 | | - preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder; |
| 91173 | + preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; |
| 91174 | + preupdate.pKeyinfo->db = db; |
| 91175 | + preupdate.pKeyinfo->enc = ENC(db); |
| 91176 | + preupdate.pKeyinfo->nKeyField = pTab->nCol; |
| 91177 | + preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; |
| 91119 | 91178 | preupdate.iKey1 = iKey1; |
| 91120 | 91179 | preupdate.iKey2 = iKey2; |
| 91121 | 91180 | preupdate.pTab = pTab; |
| 91122 | 91181 | preupdate.iBlobWrite = iBlobWrite; |
| 91123 | 91182 | |
| 91124 | 91183 | db->pPreUpdate = &preupdate; |
| 91125 | 91184 | db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); |
| 91126 | 91185 | db->pPreUpdate = 0; |
| 91127 | 91186 | sqlite3DbFree(db, preupdate.aRecord); |
| 91128 | | - vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); |
| 91129 | | - vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); |
| 91187 | + vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pUnpacked); |
| 91188 | + vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pNewUnpacked); |
| 91130 | 91189 | sqlite3VdbeMemRelease(&preupdate.oldipk); |
| 91131 | 91190 | if( preupdate.aNew ){ |
| 91132 | 91191 | int i; |
| 91133 | 91192 | for(i=0; i<pCsr->nField; i++){ |
| 91134 | 91193 | sqlite3VdbeMemRelease(&preupdate.aNew[i]); |
| | @@ -93363,11 +93422,11 @@ |
| 93363 | 93422 | nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); |
| 93364 | 93423 | aRec = sqlite3DbMallocRaw(db, nRec); |
| 93365 | 93424 | if( !aRec ) goto preupdate_old_out; |
| 93366 | 93425 | rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); |
| 93367 | 93426 | if( rc==SQLITE_OK ){ |
| 93368 | | - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); |
| 93427 | + p->pUnpacked = vdbeUnpackRecord(p->pKeyinfo, nRec, aRec); |
| 93369 | 93428 | if( !p->pUnpacked ) rc = SQLITE_NOMEM; |
| 93370 | 93429 | } |
| 93371 | 93430 | if( rc!=SQLITE_OK ){ |
| 93372 | 93431 | sqlite3DbFree(db, aRec); |
| 93373 | 93432 | goto preupdate_old_out; |
| | @@ -93428,11 +93487,11 @@ |
| 93428 | 93487 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 93429 | 93488 | p = db!=0 ? db->pPreUpdate : 0; |
| 93430 | 93489 | #else |
| 93431 | 93490 | p = db->pPreUpdate; |
| 93432 | 93491 | #endif |
| 93433 | | - return (p ? p->keyinfo.nKeyField : 0); |
| 93492 | + return (p ? p->pKeyinfo->nKeyField : 0); |
| 93434 | 93493 | } |
| 93435 | 93494 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ |
| 93436 | 93495 | |
| 93437 | 93496 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 93438 | 93497 | /* |
| | @@ -93511,11 +93570,11 @@ |
| 93511 | 93570 | UnpackedRecord *pUnpack = p->pNewUnpacked; |
| 93512 | 93571 | if( !pUnpack ){ |
| 93513 | 93572 | Mem *pData = &p->v->aMem[p->iNewReg]; |
| 93514 | 93573 | rc = ExpandBlob(pData); |
| 93515 | 93574 | if( rc!=SQLITE_OK ) goto preupdate_new_out; |
| 93516 | | - pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); |
| 93575 | + pUnpack = vdbeUnpackRecord(p->pKeyinfo, pData->n, pData->z); |
| 93517 | 93576 | if( !pUnpack ){ |
| 93518 | 93577 | rc = SQLITE_NOMEM; |
| 93519 | 93578 | goto preupdate_new_out; |
| 93520 | 93579 | } |
| 93521 | 93580 | p->pNewUnpacked = pUnpack; |
| | @@ -94305,13 +94364,13 @@ |
| 94305 | 94364 | */ |
| 94306 | 94365 | Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; |
| 94307 | 94366 | |
| 94308 | 94367 | i64 nByte; |
| 94309 | 94368 | VdbeCursor *pCx = 0; |
| 94310 | | - nByte = |
| 94311 | | - ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + |
| 94312 | | - (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); |
| 94369 | + nByte = SZ_VDBECURSOR(nField); |
| 94370 | + assert( ROUND8(nByte)==nByte ); |
| 94371 | + if( eCurType==CURTYPE_BTREE ) nByte += sqlite3BtreeCursorSize(); |
| 94313 | 94372 | |
| 94314 | 94373 | assert( iCur>=0 && iCur<p->nCursor ); |
| 94315 | 94374 | if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ |
| 94316 | 94375 | sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); |
| 94317 | 94376 | p->apCsr[iCur] = 0; |
| | @@ -94340,12 +94399,12 @@ |
| 94340 | 94399 | memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); |
| 94341 | 94400 | pCx->eCurType = eCurType; |
| 94342 | 94401 | pCx->nField = nField; |
| 94343 | 94402 | pCx->aOffset = &pCx->aType[nField]; |
| 94344 | 94403 | if( eCurType==CURTYPE_BTREE ){ |
| 94345 | | - pCx->uc.pCursor = (BtCursor*) |
| 94346 | | - &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| 94404 | + assert( ROUND8(SZ_VDBECURSOR(nField))==SZ_VDBECURSOR(nField) ); |
| 94405 | + pCx->uc.pCursor = (BtCursor*)&pMem->z[SZ_VDBECURSOR(nField)]; |
| 94347 | 94406 | sqlite3BtreeCursorZero(pCx->uc.pCursor); |
| 94348 | 94407 | } |
| 94349 | 94408 | return pCx; |
| 94350 | 94409 | } |
| 94351 | 94410 | |
| | @@ -100083,11 +100142,11 @@ |
| 100083 | 100142 | pCrsr = pC->uc.pCursor; |
| 100084 | 100143 | |
| 100085 | 100144 | /* The OP_RowData opcodes always follow OP_NotExists or |
| 100086 | 100145 | ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions |
| 100087 | 100146 | ** that might invalidate the cursor. |
| 100088 | | - ** If this where not the case, on of the following assert()s |
| 100147 | + ** If this were not the case, one of the following assert()s |
| 100089 | 100148 | ** would fail. Should this ever change (because of changes in the code |
| 100090 | 100149 | ** generator) then the fix would be to insert a call to |
| 100091 | 100150 | ** sqlite3VdbeCursorMoveto(). |
| 100092 | 100151 | */ |
| 100093 | 100152 | assert( pC->deferredMoveto==0 ); |
| | @@ -101732,11 +101791,11 @@ |
| 101732 | 101791 | ** cell in which to store the accumulation. Be careful that the memory |
| 101733 | 101792 | ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. |
| 101734 | 101793 | ** |
| 101735 | 101794 | ** Note: We could avoid this by using a regular memory cell from aMem[] for |
| 101736 | 101795 | ** the accumulator, instead of allocating one here. */ |
| 101737 | | - nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); |
| 101796 | + nAlloc = ROUND8P( SZ_CONTEXT(n) ); |
| 101738 | 101797 | pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); |
| 101739 | 101798 | if( pCtx==0 ) goto no_mem; |
| 101740 | 101799 | pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); |
| 101741 | 101800 | assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); |
| 101742 | 101801 | |
| | @@ -103390,10 +103449,11 @@ |
| 103390 | 103449 | int iCol; /* Index of zColumn in row-record */ |
| 103391 | 103450 | int rc = SQLITE_OK; |
| 103392 | 103451 | char *zErr = 0; |
| 103393 | 103452 | Table *pTab; |
| 103394 | 103453 | Incrblob *pBlob = 0; |
| 103454 | + int iDb; |
| 103395 | 103455 | Parse sParse; |
| 103396 | 103456 | |
| 103397 | 103457 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 103398 | 103458 | if( ppBlob==0 ){ |
| 103399 | 103459 | return SQLITE_MISUSE_BKPT; |
| | @@ -103435,11 +103495,14 @@ |
| 103435 | 103495 | if( pTab && IsView(pTab) ){ |
| 103436 | 103496 | pTab = 0; |
| 103437 | 103497 | sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); |
| 103438 | 103498 | } |
| 103439 | 103499 | #endif |
| 103440 | | - if( !pTab ){ |
| 103500 | + if( pTab==0 |
| 103501 | + || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 && |
| 103502 | + sqlite3OpenTempDatabase(&sParse)) |
| 103503 | + ){ |
| 103441 | 103504 | if( sParse.zErrMsg ){ |
| 103442 | 103505 | sqlite3DbFree(db, zErr); |
| 103443 | 103506 | zErr = sParse.zErrMsg; |
| 103444 | 103507 | sParse.zErrMsg = 0; |
| 103445 | 103508 | } |
| | @@ -103446,11 +103509,11 @@ |
| 103446 | 103509 | rc = SQLITE_ERROR; |
| 103447 | 103510 | sqlite3BtreeLeaveAll(db); |
| 103448 | 103511 | goto blob_open_out; |
| 103449 | 103512 | } |
| 103450 | 103513 | pBlob->pTab = pTab; |
| 103451 | | - pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; |
| 103514 | + pBlob->zDb = db->aDb[iDb].zDbSName; |
| 103452 | 103515 | |
| 103453 | 103516 | /* Now search pTab for the exact column. */ |
| 103454 | 103517 | iCol = sqlite3ColumnIndex(pTab, zColumn); |
| 103455 | 103518 | if( iCol<0 ){ |
| 103456 | 103519 | sqlite3DbFree(db, zErr); |
| | @@ -103530,11 +103593,10 @@ |
| 103530 | 103593 | {OP_Column, 0, 0, 1}, /* 3 */ |
| 103531 | 103594 | {OP_ResultRow, 1, 0, 0}, /* 4 */ |
| 103532 | 103595 | {OP_Halt, 0, 0, 0}, /* 5 */ |
| 103533 | 103596 | }; |
| 103534 | 103597 | Vdbe *v = (Vdbe *)pBlob->pStmt; |
| 103535 | | - int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 103536 | 103598 | VdbeOp *aOp; |
| 103537 | 103599 | |
| 103538 | 103600 | sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, |
| 103539 | 103601 | pTab->pSchema->schema_cookie, |
| 103540 | 103602 | pTab->pSchema->iGeneration); |
| | @@ -104108,12 +104170,15 @@ |
| 104108 | 104170 | u8 bUsePMA; /* True if one or more PMAs created */ |
| 104109 | 104171 | u8 bUseThreads; /* True to use background threads */ |
| 104110 | 104172 | u8 iPrev; /* Previous thread used to flush PMA */ |
| 104111 | 104173 | u8 nTask; /* Size of aTask[] array */ |
| 104112 | 104174 | u8 typeMask; |
| 104113 | | - SortSubtask aTask[1]; /* One or more subtasks */ |
| 104175 | + SortSubtask aTask[FLEXARRAY]; /* One or more subtasks */ |
| 104114 | 104176 | }; |
| 104177 | + |
| 104178 | +/* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */ |
| 104179 | +#define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask)) |
| 104115 | 104180 | |
| 104116 | 104181 | #define SORTER_TYPE_INTEGER 0x01 |
| 104117 | 104182 | #define SORTER_TYPE_TEXT 0x02 |
| 104118 | 104183 | |
| 104119 | 104184 | /* |
| | @@ -104742,12 +104807,12 @@ |
| 104742 | 104807 | assert( pCsr->pKeyInfo ); |
| 104743 | 104808 | assert( !pCsr->isEphemeral ); |
| 104744 | 104809 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 104745 | 104810 | assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) |
| 104746 | 104811 | < 0x7fffffff ); |
| 104747 | | - szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); |
| 104748 | | - sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); |
| 104812 | + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); |
| 104813 | + sz = SZ_VDBESORTER(nWorker+1); |
| 104749 | 104814 | |
| 104750 | 104815 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| 104751 | 104816 | pCsr->uc.pSorter = pSorter; |
| 104752 | 104817 | if( pSorter==0 ){ |
| 104753 | 104818 | rc = SQLITE_NOMEM_BKPT; |
| | @@ -105207,10 +105272,14 @@ |
| 105207 | 105272 | } |
| 105208 | 105273 | |
| 105209 | 105274 | p->u.pNext = 0; |
| 105210 | 105275 | for(i=0; aSlot[i]; i++){ |
| 105211 | 105276 | p = vdbeSorterMerge(pTask, p, aSlot[i]); |
| 105277 | + /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use |
| 105278 | + ** | up all 64 aSlots[] with only a 64-bit address space. |
| 105279 | + ** v */ |
| 105280 | + assert( i<ArraySize(aSlot) ); |
| 105212 | 105281 | aSlot[i] = 0; |
| 105213 | 105282 | } |
| 105214 | 105283 | aSlot[i] = p; |
| 105215 | 105284 | p = pNext; |
| 105216 | 105285 | } |
| | @@ -109981,32 +110050,34 @@ |
| 109981 | 110050 | Table *pTab, /* The table being referenced, or NULL */ |
| 109982 | 110051 | int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ |
| 109983 | 110052 | Expr *pExpr, /* Expression to resolve. May be NULL. */ |
| 109984 | 110053 | ExprList *pList /* Expression list to resolve. May be NULL. */ |
| 109985 | 110054 | ){ |
| 109986 | | - SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ |
| 110055 | + SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */ |
| 109987 | 110056 | NameContext sNC; /* Name context for pParse->pNewTable */ |
| 109988 | 110057 | int rc; |
| 110058 | + u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */ |
| 109989 | 110059 | |
| 109990 | 110060 | assert( type==0 || pTab!=0 ); |
| 109991 | 110061 | assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr |
| 109992 | 110062 | || type==NC_GenCol || pTab==0 ); |
| 109993 | 110063 | memset(&sNC, 0, sizeof(sNC)); |
| 109994 | | - memset(&sSrc, 0, sizeof(sSrc)); |
| 110064 | + pSrc = (SrcList*)srcSpace; |
| 110065 | + memset(pSrc, 0, SZ_SRCLIST_1); |
| 109995 | 110066 | if( pTab ){ |
| 109996 | | - sSrc.nSrc = 1; |
| 109997 | | - sSrc.a[0].zName = pTab->zName; |
| 109998 | | - sSrc.a[0].pSTab = pTab; |
| 109999 | | - sSrc.a[0].iCursor = -1; |
| 110067 | + pSrc->nSrc = 1; |
| 110068 | + pSrc->a[0].zName = pTab->zName; |
| 110069 | + pSrc->a[0].pSTab = pTab; |
| 110070 | + pSrc->a[0].iCursor = -1; |
| 110000 | 110071 | if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ |
| 110001 | 110072 | /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP |
| 110002 | 110073 | ** schema elements */ |
| 110003 | 110074 | type |= NC_FromDDL; |
| 110004 | 110075 | } |
| 110005 | 110076 | } |
| 110006 | 110077 | sNC.pParse = pParse; |
| 110007 | | - sNC.pSrcList = &sSrc; |
| 110078 | + sNC.pSrcList = pSrc; |
| 110008 | 110079 | sNC.ncFlags = type | NC_IsDDL; |
| 110009 | 110080 | if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; |
| 110010 | 110081 | if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); |
| 110011 | 110082 | return rc; |
| 110012 | 110083 | } |
| | @@ -111751,11 +111822,11 @@ |
| 111751 | 111822 | */ |
| 111752 | 111823 | #ifndef SQLITE_OMIT_CTE |
| 111753 | 111824 | SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ |
| 111754 | 111825 | With *pRet = 0; |
| 111755 | 111826 | if( p ){ |
| 111756 | | - sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); |
| 111827 | + sqlite3_int64 nByte = SZ_WITH(p->nCte); |
| 111757 | 111828 | pRet = sqlite3DbMallocZero(db, nByte); |
| 111758 | 111829 | if( pRet ){ |
| 111759 | 111830 | int i; |
| 111760 | 111831 | pRet->nCte = p->nCte; |
| 111761 | 111832 | for(i=0; i<p->nCte; i++){ |
| | @@ -111878,15 +111949,13 @@ |
| 111878 | 111949 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ |
| 111879 | 111950 | || !defined(SQLITE_OMIT_SUBQUERY) |
| 111880 | 111951 | SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ |
| 111881 | 111952 | SrcList *pNew; |
| 111882 | 111953 | int i; |
| 111883 | | - int nByte; |
| 111884 | 111954 | assert( db!=0 ); |
| 111885 | 111955 | if( p==0 ) return 0; |
| 111886 | | - nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); |
| 111887 | | - pNew = sqlite3DbMallocRawNN(db, nByte ); |
| 111956 | + pNew = sqlite3DbMallocRawNN(db, SZ_SRCLIST(p->nSrc) ); |
| 111888 | 111957 | if( pNew==0 ) return 0; |
| 111889 | 111958 | pNew->nSrc = pNew->nAlloc = p->nSrc; |
| 111890 | 111959 | for(i=0; i<p->nSrc; i++){ |
| 111891 | 111960 | SrcItem *pNewItem = &pNew->a[i]; |
| 111892 | 111961 | const SrcItem *pOldItem = &p->a[i]; |
| | @@ -111944,11 +112013,11 @@ |
| 111944 | 112013 | SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ |
| 111945 | 112014 | IdList *pNew; |
| 111946 | 112015 | int i; |
| 111947 | 112016 | assert( db!=0 ); |
| 111948 | 112017 | if( p==0 ) return 0; |
| 111949 | | - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); |
| 112018 | + pNew = sqlite3DbMallocRawNN(db, SZ_IDLIST(p->nId)); |
| 111950 | 112019 | if( pNew==0 ) return 0; |
| 111951 | 112020 | pNew->nId = p->nId; |
| 111952 | 112021 | for(i=0; i<p->nId; i++){ |
| 111953 | 112022 | struct IdList_item *pNewItem = &pNew->a[i]; |
| 111954 | 112023 | const struct IdList_item *pOldItem = &p->a[i]; |
| | @@ -112028,11 +112097,11 @@ |
| 112028 | 112097 | Expr *pExpr /* Expression to be appended. Might be NULL */ |
| 112029 | 112098 | ){ |
| 112030 | 112099 | struct ExprList_item *pItem; |
| 112031 | 112100 | ExprList *pList; |
| 112032 | 112101 | |
| 112033 | | - pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); |
| 112102 | + pList = sqlite3DbMallocRawNN(db, SZ_EXPRLIST(4)); |
| 112034 | 112103 | if( pList==0 ){ |
| 112035 | 112104 | sqlite3ExprDelete(db, pExpr); |
| 112036 | 112105 | return 0; |
| 112037 | 112106 | } |
| 112038 | 112107 | pList->nAlloc = 4; |
| | @@ -112048,12 +112117,11 @@ |
| 112048 | 112117 | Expr *pExpr /* Expression to be appended. Might be NULL */ |
| 112049 | 112118 | ){ |
| 112050 | 112119 | struct ExprList_item *pItem; |
| 112051 | 112120 | ExprList *pNew; |
| 112052 | 112121 | pList->nAlloc *= 2; |
| 112053 | | - pNew = sqlite3DbRealloc(db, pList, |
| 112054 | | - sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); |
| 112122 | + pNew = sqlite3DbRealloc(db, pList, SZ_EXPRLIST(pList->nAlloc)); |
| 112055 | 112123 | if( pNew==0 ){ |
| 112056 | 112124 | sqlite3ExprListDelete(db, pList); |
| 112057 | 112125 | sqlite3ExprDelete(db, pExpr); |
| 112058 | 112126 | return 0; |
| 112059 | 112127 | }else{ |
| | @@ -114685,11 +114753,11 @@ |
| 114685 | 114753 | return -1; /* Not found */ |
| 114686 | 114754 | } |
| 114687 | 114755 | |
| 114688 | 114756 | |
| 114689 | 114757 | /* |
| 114690 | | -** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This |
| 114758 | +** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This |
| 114691 | 114759 | ** function checks the Parse.pIdxPartExpr list to see if this column |
| 114692 | 114760 | ** can be replaced with a constant value. If so, it generates code to |
| 114693 | 114761 | ** put the constant value in a register (ideally, but not necessarily, |
| 114694 | 114762 | ** register iTarget) and returns the register number. |
| 114695 | 114763 | ** |
| | @@ -118531,10 +118599,11 @@ |
| 118531 | 118599 | sqlite3 *db, /* Database handle */ |
| 118532 | 118600 | const char *zSql, /* SQL to parse */ |
| 118533 | 118601 | int bTemp /* True if SQL is from temp schema */ |
| 118534 | 118602 | ){ |
| 118535 | 118603 | int rc; |
| 118604 | + u64 flags; |
| 118536 | 118605 | |
| 118537 | 118606 | sqlite3ParseObjectInit(p, db); |
| 118538 | 118607 | if( zSql==0 ){ |
| 118539 | 118608 | return SQLITE_NOMEM; |
| 118540 | 118609 | } |
| | @@ -118549,11 +118618,15 @@ |
| 118549 | 118618 | db->init.iDb = (u8)iDb; |
| 118550 | 118619 | } |
| 118551 | 118620 | p->eParseMode = PARSE_MODE_RENAME; |
| 118552 | 118621 | p->db = db; |
| 118553 | 118622 | p->nQueryLoop = 1; |
| 118623 | + flags = db->flags; |
| 118624 | + testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 ); |
| 118625 | + db->flags |= SQLITE_Comments; |
| 118554 | 118626 | rc = sqlite3RunParser(p, zSql); |
| 118627 | + db->flags = flags; |
| 118555 | 118628 | if( db->mallocFailed ) rc = SQLITE_NOMEM; |
| 118556 | 118629 | if( rc==SQLITE_OK |
| 118557 | 118630 | && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) |
| 118558 | 118631 | ){ |
| 118559 | 118632 | rc = SQLITE_CORRUPT_BKPT; |
| | @@ -119445,11 +119518,11 @@ |
| 119445 | 119518 | int rc; |
| 119446 | 119519 | Parse sParse; |
| 119447 | 119520 | u64 flags = db->flags; |
| 119448 | 119521 | if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); |
| 119449 | 119522 | rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); |
| 119450 | | - db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); |
| 119523 | + db->flags = flags; |
| 119451 | 119524 | if( rc==SQLITE_OK ){ |
| 119452 | 119525 | if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ |
| 119453 | 119526 | NameContext sNC; |
| 119454 | 119527 | memset(&sNC, 0, sizeof(sNC)); |
| 119455 | 119528 | sNC.pParse = &sParse; |
| | @@ -126268,11 +126341,11 @@ |
| 126268 | 126341 | "columns in the referenced table"); |
| 126269 | 126342 | goto fk_end; |
| 126270 | 126343 | }else{ |
| 126271 | 126344 | nCol = pFromCol->nExpr; |
| 126272 | 126345 | } |
| 126273 | | - nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; |
| 126346 | + nByte = SZ_FKEY(nCol) + pTo->n + 1; |
| 126274 | 126347 | if( pToCol ){ |
| 126275 | 126348 | for(i=0; i<pToCol->nExpr; i++){ |
| 126276 | 126349 | nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; |
| 126277 | 126350 | } |
| 126278 | 126351 | } |
| | @@ -127327,16 +127400,15 @@ |
| 127327 | 127400 | */ |
| 127328 | 127401 | SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ |
| 127329 | 127402 | sqlite3 *db = pParse->db; |
| 127330 | 127403 | int i; |
| 127331 | 127404 | if( pList==0 ){ |
| 127332 | | - pList = sqlite3DbMallocZero(db, sizeof(IdList) ); |
| 127405 | + pList = sqlite3DbMallocZero(db, SZ_IDLIST(1)); |
| 127333 | 127406 | if( pList==0 ) return 0; |
| 127334 | 127407 | }else{ |
| 127335 | 127408 | IdList *pNew; |
| 127336 | | - pNew = sqlite3DbRealloc(db, pList, |
| 127337 | | - sizeof(IdList) + pList->nId*sizeof(pList->a)); |
| 127409 | + pNew = sqlite3DbRealloc(db, pList, SZ_IDLIST(pList->nId+1)); |
| 127338 | 127410 | if( pNew==0 ){ |
| 127339 | 127411 | sqlite3IdListDelete(db, pList); |
| 127340 | 127412 | return 0; |
| 127341 | 127413 | } |
| 127342 | 127414 | pList = pNew; |
| | @@ -127431,12 +127503,11 @@ |
| 127431 | 127503 | sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", |
| 127432 | 127504 | SQLITE_MAX_SRCLIST); |
| 127433 | 127505 | return 0; |
| 127434 | 127506 | } |
| 127435 | 127507 | if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; |
| 127436 | | - pNew = sqlite3DbRealloc(db, pSrc, |
| 127437 | | - sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); |
| 127508 | + pNew = sqlite3DbRealloc(db, pSrc, SZ_SRCLIST(nAlloc)); |
| 127438 | 127509 | if( pNew==0 ){ |
| 127439 | 127510 | assert( db->mallocFailed ); |
| 127440 | 127511 | return 0; |
| 127441 | 127512 | } |
| 127442 | 127513 | pSrc = pNew; |
| | @@ -127507,11 +127578,11 @@ |
| 127507 | 127578 | assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ |
| 127508 | 127579 | assert( pParse!=0 ); |
| 127509 | 127580 | assert( pParse->db!=0 ); |
| 127510 | 127581 | db = pParse->db; |
| 127511 | 127582 | if( pList==0 ){ |
| 127512 | | - pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); |
| 127583 | + pList = sqlite3DbMallocRawNN(pParse->db, SZ_SRCLIST(1)); |
| 127513 | 127584 | if( pList==0 ) return 0; |
| 127514 | 127585 | pList->nAlloc = 1; |
| 127515 | 127586 | pList->nSrc = 1; |
| 127516 | 127587 | memset(&pList->a[0], 0, sizeof(pList->a[0])); |
| 127517 | 127588 | pList->a[0].iCursor = -1; |
| | @@ -128393,14 +128464,13 @@ |
| 128393 | 128464 | } |
| 128394 | 128465 | } |
| 128395 | 128466 | } |
| 128396 | 128467 | |
| 128397 | 128468 | if( pWith ){ |
| 128398 | | - sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); |
| 128399 | | - pNew = sqlite3DbRealloc(db, pWith, nByte); |
| 128469 | + pNew = sqlite3DbRealloc(db, pWith, SZ_WITH(pWith->nCte+1)); |
| 128400 | 128470 | }else{ |
| 128401 | | - pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); |
| 128471 | + pNew = sqlite3DbMallocZero(db, SZ_WITH(1)); |
| 128402 | 128472 | } |
| 128403 | 128473 | assert( (pNew!=0 && zName!=0) || db->mallocFailed ); |
| 128404 | 128474 | |
| 128405 | 128475 | if( db->mallocFailed ){ |
| 128406 | 128476 | sqlite3CteDelete(db, pCte); |
| | @@ -131933,11 +132003,11 @@ |
| 131933 | 132003 | ** |
| 131934 | 132004 | ** The SUM() function follows the (broken) SQL standard which means |
| 131935 | 132005 | ** that it returns NULL if it sums over no inputs. TOTAL returns |
| 131936 | 132006 | ** 0.0 in that case. In addition, TOTAL always returns a float where |
| 131937 | 132007 | ** SUM might return an integer if it never encounters a floating point |
| 131938 | | -** value. TOTAL never fails, but SUM might through an exception if |
| 132008 | +** value. TOTAL never fails, but SUM might throw an exception if |
| 131939 | 132009 | ** it overflows an integer. |
| 131940 | 132010 | */ |
| 131941 | 132011 | static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ |
| 131942 | 132012 | SumCtx *p; |
| 131943 | 132013 | int type; |
| | @@ -139748,52 +139818,52 @@ |
| 139748 | 139818 | /* 11 */ "notnull", |
| 139749 | 139819 | /* 12 */ "dflt_value", |
| 139750 | 139820 | /* 13 */ "pk", |
| 139751 | 139821 | /* 14 */ "hidden", |
| 139752 | 139822 | /* table_info reuses 8 */ |
| 139753 | | - /* 15 */ "schema", /* Used by: table_list */ |
| 139754 | | - /* 16 */ "name", |
| 139823 | + /* 15 */ "name", /* Used by: function_list */ |
| 139824 | + /* 16 */ "builtin", |
| 139755 | 139825 | /* 17 */ "type", |
| 139756 | | - /* 18 */ "ncol", |
| 139757 | | - /* 19 */ "wr", |
| 139758 | | - /* 20 */ "strict", |
| 139759 | | - /* 21 */ "seqno", /* Used by: index_xinfo */ |
| 139760 | | - /* 22 */ "cid", |
| 139761 | | - /* 23 */ "name", |
| 139762 | | - /* 24 */ "desc", |
| 139763 | | - /* 25 */ "coll", |
| 139764 | | - /* 26 */ "key", |
| 139765 | | - /* 27 */ "name", /* Used by: function_list */ |
| 139766 | | - /* 28 */ "builtin", |
| 139767 | | - /* 29 */ "type", |
| 139768 | | - /* 30 */ "enc", |
| 139769 | | - /* 31 */ "narg", |
| 139770 | | - /* 32 */ "flags", |
| 139771 | | - /* 33 */ "tbl", /* Used by: stats */ |
| 139772 | | - /* 34 */ "idx", |
| 139773 | | - /* 35 */ "wdth", |
| 139774 | | - /* 36 */ "hght", |
| 139775 | | - /* 37 */ "flgs", |
| 139776 | | - /* 38 */ "seq", /* Used by: index_list */ |
| 139777 | | - /* 39 */ "name", |
| 139778 | | - /* 40 */ "unique", |
| 139779 | | - /* 41 */ "origin", |
| 139780 | | - /* 42 */ "partial", |
| 139826 | + /* 18 */ "enc", |
| 139827 | + /* 19 */ "narg", |
| 139828 | + /* 20 */ "flags", |
| 139829 | + /* 21 */ "schema", /* Used by: table_list */ |
| 139830 | + /* 22 */ "name", |
| 139831 | + /* 23 */ "type", |
| 139832 | + /* 24 */ "ncol", |
| 139833 | + /* 25 */ "wr", |
| 139834 | + /* 26 */ "strict", |
| 139835 | + /* 27 */ "seqno", /* Used by: index_xinfo */ |
| 139836 | + /* 28 */ "cid", |
| 139837 | + /* 29 */ "name", |
| 139838 | + /* 30 */ "desc", |
| 139839 | + /* 31 */ "coll", |
| 139840 | + /* 32 */ "key", |
| 139841 | + /* 33 */ "seq", /* Used by: index_list */ |
| 139842 | + /* 34 */ "name", |
| 139843 | + /* 35 */ "unique", |
| 139844 | + /* 36 */ "origin", |
| 139845 | + /* 37 */ "partial", |
| 139846 | + /* 38 */ "tbl", /* Used by: stats */ |
| 139847 | + /* 39 */ "idx", |
| 139848 | + /* 40 */ "wdth", |
| 139849 | + /* 41 */ "hght", |
| 139850 | + /* 42 */ "flgs", |
| 139781 | 139851 | /* 43 */ "table", /* Used by: foreign_key_check */ |
| 139782 | 139852 | /* 44 */ "rowid", |
| 139783 | 139853 | /* 45 */ "parent", |
| 139784 | 139854 | /* 46 */ "fkid", |
| 139785 | | - /* index_info reuses 21 */ |
| 139786 | | - /* 47 */ "seq", /* Used by: database_list */ |
| 139787 | | - /* 48 */ "name", |
| 139788 | | - /* 49 */ "file", |
| 139789 | | - /* 50 */ "busy", /* Used by: wal_checkpoint */ |
| 139790 | | - /* 51 */ "log", |
| 139791 | | - /* 52 */ "checkpointed", |
| 139792 | | - /* collation_list reuses 38 */ |
| 139855 | + /* 47 */ "busy", /* Used by: wal_checkpoint */ |
| 139856 | + /* 48 */ "log", |
| 139857 | + /* 49 */ "checkpointed", |
| 139858 | + /* 50 */ "seq", /* Used by: database_list */ |
| 139859 | + /* 51 */ "name", |
| 139860 | + /* 52 */ "file", |
| 139861 | + /* index_info reuses 27 */ |
| 139793 | 139862 | /* 53 */ "database", /* Used by: lock_status */ |
| 139794 | 139863 | /* 54 */ "status", |
| 139864 | + /* collation_list reuses 33 */ |
| 139795 | 139865 | /* 55 */ "cache_size", /* Used by: default_cache_size */ |
| 139796 | 139866 | /* module_list pragma_list reuses 9 */ |
| 139797 | 139867 | /* 56 */ "timeout", /* Used by: busy_timeout */ |
| 139798 | 139868 | }; |
| 139799 | 139869 | |
| | @@ -139882,11 +139952,11 @@ |
| 139882 | 139952 | #endif |
| 139883 | 139953 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 139884 | 139954 | {/* zName: */ "collation_list", |
| 139885 | 139955 | /* ePragTyp: */ PragTyp_COLLATION_LIST, |
| 139886 | 139956 | /* ePragFlg: */ PragFlg_Result0, |
| 139887 | | - /* ColNames: */ 38, 2, |
| 139957 | + /* ColNames: */ 33, 2, |
| 139888 | 139958 | /* iArg: */ 0 }, |
| 139889 | 139959 | #endif |
| 139890 | 139960 | #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 139891 | 139961 | {/* zName: */ "compile_options", |
| 139892 | 139962 | /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, |
| | @@ -139917,11 +139987,11 @@ |
| 139917 | 139987 | #endif |
| 139918 | 139988 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 139919 | 139989 | {/* zName: */ "database_list", |
| 139920 | 139990 | /* ePragTyp: */ PragTyp_DATABASE_LIST, |
| 139921 | 139991 | /* ePragFlg: */ PragFlg_Result0, |
| 139922 | | - /* ColNames: */ 47, 3, |
| 139992 | + /* ColNames: */ 50, 3, |
| 139923 | 139993 | /* iArg: */ 0 }, |
| 139924 | 139994 | #endif |
| 139925 | 139995 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 139926 | 139996 | {/* zName: */ "default_cache_size", |
| 139927 | 139997 | /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, |
| | @@ -139997,11 +140067,11 @@ |
| 139997 | 140067 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 139998 | 140068 | #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) |
| 139999 | 140069 | {/* zName: */ "function_list", |
| 140000 | 140070 | /* ePragTyp: */ PragTyp_FUNCTION_LIST, |
| 140001 | 140071 | /* ePragFlg: */ PragFlg_Result0, |
| 140002 | | - /* ColNames: */ 27, 6, |
| 140072 | + /* ColNames: */ 15, 6, |
| 140003 | 140073 | /* iArg: */ 0 }, |
| 140004 | 140074 | #endif |
| 140005 | 140075 | #endif |
| 140006 | 140076 | {/* zName: */ "hard_heap_limit", |
| 140007 | 140077 | /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, |
| | @@ -140026,21 +140096,21 @@ |
| 140026 | 140096 | #endif |
| 140027 | 140097 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 140028 | 140098 | {/* zName: */ "index_info", |
| 140029 | 140099 | /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 140030 | 140100 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 140031 | | - /* ColNames: */ 21, 3, |
| 140101 | + /* ColNames: */ 27, 3, |
| 140032 | 140102 | /* iArg: */ 0 }, |
| 140033 | 140103 | {/* zName: */ "index_list", |
| 140034 | 140104 | /* ePragTyp: */ PragTyp_INDEX_LIST, |
| 140035 | 140105 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 140036 | | - /* ColNames: */ 38, 5, |
| 140106 | + /* ColNames: */ 33, 5, |
| 140037 | 140107 | /* iArg: */ 0 }, |
| 140038 | 140108 | {/* zName: */ "index_xinfo", |
| 140039 | 140109 | /* ePragTyp: */ PragTyp_INDEX_INFO, |
| 140040 | 140110 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 140041 | | - /* ColNames: */ 21, 6, |
| 140111 | + /* ColNames: */ 27, 6, |
| 140042 | 140112 | /* iArg: */ 1 }, |
| 140043 | 140113 | #endif |
| 140044 | 140114 | #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 140045 | 140115 | {/* zName: */ "integrity_check", |
| 140046 | 140116 | /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, |
| | @@ -140215,11 +140285,11 @@ |
| 140215 | 140285 | #endif |
| 140216 | 140286 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) |
| 140217 | 140287 | {/* zName: */ "stats", |
| 140218 | 140288 | /* ePragTyp: */ PragTyp_STATS, |
| 140219 | 140289 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, |
| 140220 | | - /* ColNames: */ 33, 5, |
| 140290 | + /* ColNames: */ 38, 5, |
| 140221 | 140291 | /* iArg: */ 0 }, |
| 140222 | 140292 | #endif |
| 140223 | 140293 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 140224 | 140294 | {/* zName: */ "synchronous", |
| 140225 | 140295 | /* ePragTyp: */ PragTyp_SYNCHRONOUS, |
| | @@ -140234,11 +140304,11 @@ |
| 140234 | 140304 | /* ColNames: */ 8, 6, |
| 140235 | 140305 | /* iArg: */ 0 }, |
| 140236 | 140306 | {/* zName: */ "table_list", |
| 140237 | 140307 | /* ePragTyp: */ PragTyp_TABLE_LIST, |
| 140238 | 140308 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, |
| 140239 | | - /* ColNames: */ 15, 6, |
| 140309 | + /* ColNames: */ 21, 6, |
| 140240 | 140310 | /* iArg: */ 0 }, |
| 140241 | 140311 | {/* zName: */ "table_xinfo", |
| 140242 | 140312 | /* ePragTyp: */ PragTyp_TABLE_INFO, |
| 140243 | 140313 | /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, |
| 140244 | 140314 | /* ColNames: */ 8, 7, |
| | @@ -140311,11 +140381,11 @@ |
| 140311 | 140381 | /* ColNames: */ 0, 0, |
| 140312 | 140382 | /* iArg: */ 0 }, |
| 140313 | 140383 | {/* zName: */ "wal_checkpoint", |
| 140314 | 140384 | /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, |
| 140315 | 140385 | /* ePragFlg: */ PragFlg_NeedSchema, |
| 140316 | | - /* ColNames: */ 50, 3, |
| 140386 | + /* ColNames: */ 47, 3, |
| 140317 | 140387 | /* iArg: */ 0 }, |
| 140318 | 140388 | #endif |
| 140319 | 140389 | #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) |
| 140320 | 140390 | {/* zName: */ "writable_schema", |
| 140321 | 140391 | /* ePragTyp: */ PragTyp_FLAG, |
| | @@ -140333,11 +140403,11 @@ |
| 140333 | 140403 | ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands |
| 140334 | 140404 | ** will be run with an analysis_limit set to the lessor of the value of |
| 140335 | 140405 | ** the following macro or to the actual analysis_limit if it is non-zero, |
| 140336 | 140406 | ** in order to prevent PRAGMA optimize from running for too long. |
| 140337 | 140407 | ** |
| 140338 | | -** The value of 2000 is chosen emperically so that the worst-case run-time |
| 140408 | +** The value of 2000 is chosen empirically so that the worst-case run-time |
| 140339 | 140409 | ** for PRAGMA optimize does not exceed 100 milliseconds against a variety |
| 140340 | 140410 | ** of test databases on a RaspberryPI-4 compiled using -Os and without |
| 140341 | 140411 | ** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of |
| 140342 | 140412 | ** this paragraph, "worst-case" means that ANALYZE ends up being |
| 140343 | 140413 | ** run on every table in the database. The worst case typically only |
| | @@ -144622,11 +144692,11 @@ |
| 144622 | 144692 | pNew->iOffset = 0; |
| 144623 | 144693 | pNew->selId = ++pParse->nSelect; |
| 144624 | 144694 | pNew->addrOpenEphm[0] = -1; |
| 144625 | 144695 | pNew->addrOpenEphm[1] = -1; |
| 144626 | 144696 | pNew->nSelectRow = 0; |
| 144627 | | - if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); |
| 144697 | + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); |
| 144628 | 144698 | pNew->pSrc = pSrc; |
| 144629 | 144699 | pNew->pWhere = pWhere; |
| 144630 | 144700 | pNew->pGroupBy = pGroupBy; |
| 144631 | 144701 | pNew->pHaving = pHaving; |
| 144632 | 144702 | pNew->pOrderBy = pOrderBy; |
| | @@ -146005,20 +146075,20 @@ |
| 146005 | 146075 | /* |
| 146006 | 146076 | ** Allocate a KeyInfo object sufficient for an index of N key columns and |
| 146007 | 146077 | ** X extra columns. |
| 146008 | 146078 | */ |
| 146009 | 146079 | SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ |
| 146010 | | - int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); |
| 146011 | | - KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); |
| 146080 | + int nExtra = (N+X)*(sizeof(CollSeq*)+1); |
| 146081 | + KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra); |
| 146012 | 146082 | if( p ){ |
| 146013 | 146083 | p->aSortFlags = (u8*)&p->aColl[N+X]; |
| 146014 | 146084 | p->nKeyField = (u16)N; |
| 146015 | 146085 | p->nAllField = (u16)(N+X); |
| 146016 | 146086 | p->enc = ENC(db); |
| 146017 | 146087 | p->db = db; |
| 146018 | 146088 | p->nRef = 1; |
| 146019 | | - memset(&p[1], 0, nExtra); |
| 146089 | + memset(p->aColl, 0, nExtra); |
| 146020 | 146090 | }else{ |
| 146021 | 146091 | return (KeyInfo*)sqlite3OomFault(db); |
| 146022 | 146092 | } |
| 146023 | 146093 | return p; |
| 146024 | 146094 | } |
| | @@ -150530,11 +150600,11 @@ |
| 150530 | 150600 | } |
| 150531 | 150601 | pTabList = p->pSrc; |
| 150532 | 150602 | pEList = p->pEList; |
| 150533 | 150603 | if( pParse->pWith && (p->selFlags & SF_View) ){ |
| 150534 | 150604 | if( p->pWith==0 ){ |
| 150535 | | - p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With)); |
| 150605 | + p->pWith = (With*)sqlite3DbMallocZero(db, SZ_WITH(1) ); |
| 150536 | 150606 | if( p->pWith==0 ){ |
| 150537 | 150607 | return WRC_Abort; |
| 150538 | 150608 | } |
| 150539 | 150609 | } |
| 150540 | 150610 | p->pWith->bView = 1; |
| | @@ -151669,10 +151739,11 @@ |
| 151669 | 151739 | ** * The subquery is a UNION ALL of two or more terms |
| 151670 | 151740 | ** * The subquery does not have a LIMIT clause |
| 151671 | 151741 | ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries |
| 151672 | 151742 | ** * The outer query is a simple count(*) with no WHERE clause or other |
| 151673 | 151743 | ** extraneous syntax. |
| 151744 | +** * None of the subqueries are DISTINCT (forumpost/a860f5fb2e 2025-03-10) |
| 151674 | 151745 | ** |
| 151675 | 151746 | ** Return TRUE if the optimization is undertaken. |
| 151676 | 151747 | */ |
| 151677 | 151748 | static int countOfViewOptimization(Parse *pParse, Select *p){ |
| 151678 | 151749 | Select *pSub, *pPrior; |
| | @@ -151701,11 +151772,15 @@ |
| 151701 | 151772 | if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ |
| 151702 | 151773 | do{ |
| 151703 | 151774 | if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ |
| 151704 | 151775 | if( pSub->pWhere ) return 0; /* No WHERE clause */ |
| 151705 | 151776 | if( pSub->pLimit ) return 0; /* No LIMIT clause */ |
| 151706 | | - if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ |
| 151777 | + if( pSub->selFlags & (SF_Aggregate|SF_Distinct) ){ |
| 151778 | + testcase( pSub->selFlags & SF_Aggregate ); |
| 151779 | + testcase( pSub->selFlags & SF_Distinct ); |
| 151780 | + return 0; /* Not an aggregate nor DISTINCT */ |
| 151781 | + } |
| 151707 | 151782 | assert( pSub->pHaving==0 ); /* Due to the previous */ |
| 151708 | 151783 | pSub = pSub->pPrior; /* Repeat over compound */ |
| 151709 | 151784 | }while( pSub ); |
| 151710 | 151785 | |
| 151711 | 151786 | /* If we reach this point then it is OK to perform the transformation */ |
| | @@ -151713,11 +151788,11 @@ |
| 151713 | 151788 | db = pParse->db; |
| 151714 | 151789 | pCount = pExpr; |
| 151715 | 151790 | pExpr = 0; |
| 151716 | 151791 | pSub = sqlite3SubqueryDetach(db, pFrom); |
| 151717 | 151792 | sqlite3SrcListDelete(db, p->pSrc); |
| 151718 | | - p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); |
| 151793 | + p->pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); |
| 151719 | 151794 | while( pSub ){ |
| 151720 | 151795 | Expr *pTerm; |
| 151721 | 151796 | pPrior = pSub->pPrior; |
| 151722 | 151797 | pSub->pPrior = 0; |
| 151723 | 151798 | pSub->pNext = 0; |
| | @@ -154504,11 +154579,12 @@ |
| 154504 | 154579 | Vdbe *v = pParse->pVdbe; |
| 154505 | 154580 | sqlite3 *db = pParse->db; |
| 154506 | 154581 | ExprList *pNew; |
| 154507 | 154582 | Returning *pReturning; |
| 154508 | 154583 | Select sSelect; |
| 154509 | | - SrcList sFrom; |
| 154584 | + SrcList *pFrom; |
| 154585 | + u8 fromSpace[SZ_SRCLIST_1]; |
| 154510 | 154586 | |
| 154511 | 154587 | assert( v!=0 ); |
| 154512 | 154588 | if( !pParse->bReturning ){ |
| 154513 | 154589 | /* This RETURNING trigger must be for a different statement as |
| 154514 | 154590 | ** this statement lacks a RETURNING clause. */ |
| | @@ -154520,17 +154596,18 @@ |
| 154520 | 154596 | if( pTrigger != &(pReturning->retTrig) ){ |
| 154521 | 154597 | /* This RETURNING trigger is for a different statement */ |
| 154522 | 154598 | return; |
| 154523 | 154599 | } |
| 154524 | 154600 | memset(&sSelect, 0, sizeof(sSelect)); |
| 154525 | | - memset(&sFrom, 0, sizeof(sFrom)); |
| 154601 | + pFrom = (SrcList*)fromSpace; |
| 154602 | + memset(pFrom, 0, SZ_SRCLIST_1); |
| 154526 | 154603 | sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); |
| 154527 | | - sSelect.pSrc = &sFrom; |
| 154528 | | - sFrom.nSrc = 1; |
| 154529 | | - sFrom.a[0].pSTab = pTab; |
| 154530 | | - sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ |
| 154531 | | - sFrom.a[0].iCursor = -1; |
| 154604 | + sSelect.pSrc = pFrom; |
| 154605 | + pFrom->nSrc = 1; |
| 154606 | + pFrom->a[0].pSTab = pTab; |
| 154607 | + pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */ |
| 154608 | + pFrom->a[0].iCursor = -1; |
| 154532 | 154609 | sqlite3SelectPrep(pParse, &sSelect, 0); |
| 154533 | 154610 | if( pParse->nErr==0 ){ |
| 154534 | 154611 | assert( db->mallocFailed==0 ); |
| 154535 | 154612 | sqlite3GenerateColumnNames(pParse, &sSelect); |
| 154536 | 154613 | } |
| | @@ -156927,11 +157004,11 @@ |
| 156927 | 157004 | saved_flags = db->flags; |
| 156928 | 157005 | saved_mDbFlags = db->mDbFlags; |
| 156929 | 157006 | saved_nChange = db->nChange; |
| 156930 | 157007 | saved_nTotalChange = db->nTotalChange; |
| 156931 | 157008 | saved_mTrace = db->mTrace; |
| 156932 | | - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; |
| 157009 | + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; |
| 156933 | 157010 | db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; |
| 156934 | 157011 | db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder |
| 156935 | 157012 | | SQLITE_Defensive | SQLITE_CountRows); |
| 156936 | 157013 | db->mTrace = 0; |
| 156937 | 157014 | |
| | @@ -159056,13 +159133,18 @@ |
| 159056 | 159133 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 159057 | 159134 | WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ |
| 159058 | 159135 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 159059 | 159136 | WhereClause sWC; /* Decomposition of the WHERE clause */ |
| 159060 | 159137 | WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ |
| 159061 | | - WhereLevel a[1]; /* Information about each nest loop in WHERE */ |
| 159138 | + WhereLevel a[FLEXARRAY]; /* Information about each nest loop in WHERE */ |
| 159062 | 159139 | }; |
| 159063 | 159140 | |
| 159141 | +/* |
| 159142 | +** The size (in bytes) of a WhereInfo object that holds N WhereLevels. |
| 159143 | +*/ |
| 159144 | +#define SZ_WHEREINFO(N) ROUND8(offsetof(WhereInfo,a)+(N)*sizeof(WhereLevel)) |
| 159145 | + |
| 159064 | 159146 | /* |
| 159065 | 159147 | ** Private interfaces - callable only by other where.c routines. |
| 159066 | 159148 | ** |
| 159067 | 159149 | ** where.c: |
| 159068 | 159150 | */ |
| | @@ -161509,12 +161591,11 @@ |
| 161509 | 161591 | */ |
| 161510 | 161592 | if( pWInfo->nLevel>1 ){ |
| 161511 | 161593 | int nNotReady; /* The number of notReady tables */ |
| 161512 | 161594 | SrcItem *origSrc; /* Original list of tables */ |
| 161513 | 161595 | nNotReady = pWInfo->nLevel - iLevel - 1; |
| 161514 | | - pOrTab = sqlite3DbMallocRawNN(db, |
| 161515 | | - sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); |
| 161596 | + pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); |
| 161516 | 161597 | if( pOrTab==0 ) return notReady; |
| 161517 | 161598 | pOrTab->nAlloc = (u8)(nNotReady + 1); |
| 161518 | 161599 | pOrTab->nSrc = pOrTab->nAlloc; |
| 161519 | 161600 | memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); |
| 161520 | 161601 | origSrc = pWInfo->pTabList->a; |
| | @@ -162053,11 +162134,12 @@ |
| 162053 | 162134 | Expr *pSubWhere = 0; |
| 162054 | 162135 | WhereClause *pWC = &pWInfo->sWC; |
| 162055 | 162136 | WhereInfo *pSubWInfo; |
| 162056 | 162137 | WhereLoop *pLoop = pLevel->pWLoop; |
| 162057 | 162138 | SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; |
| 162058 | | - SrcList sFrom; |
| 162139 | + SrcList *pFrom; |
| 162140 | + u8 fromSpace[SZ_SRCLIST_1]; |
| 162059 | 162141 | Bitmask mAll = 0; |
| 162060 | 162142 | int k; |
| 162061 | 162143 | |
| 162062 | 162144 | ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); |
| 162063 | 162145 | sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, |
| | @@ -162097,17 +162179,18 @@ |
| 162097 | 162179 | if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; |
| 162098 | 162180 | pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, |
| 162099 | 162181 | sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); |
| 162100 | 162182 | } |
| 162101 | 162183 | } |
| 162102 | | - sFrom.nSrc = 1; |
| 162103 | | - sFrom.nAlloc = 1; |
| 162104 | | - memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); |
| 162105 | | - sFrom.a[0].fg.jointype = 0; |
| 162184 | + pFrom = (SrcList*)fromSpace; |
| 162185 | + pFrom->nSrc = 1; |
| 162186 | + pFrom->nAlloc = 1; |
| 162187 | + memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); |
| 162188 | + pFrom->a[0].fg.jointype = 0; |
| 162106 | 162189 | assert( pParse->withinRJSubrtn < 100 ); |
| 162107 | 162190 | pParse->withinRJSubrtn++; |
| 162108 | | - pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, |
| 162191 | + pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, |
| 162109 | 162192 | WHERE_RIGHT_JOIN, 0); |
| 162110 | 162193 | if( pSubWInfo ){ |
| 162111 | 162194 | int iCur = pLevel->iTabCur; |
| 162112 | 162195 | int r = ++pParse->nMem; |
| 162113 | 162196 | int nPk; |
| | @@ -164091,15 +164174,20 @@ |
| 164091 | 164174 | WhereClause *pWC; /* The Where clause being analyzed */ |
| 164092 | 164175 | Parse *pParse; /* The parsing context */ |
| 164093 | 164176 | int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ |
| 164094 | 164177 | u32 mIn; /* Mask of terms that are <col> IN (...) */ |
| 164095 | 164178 | u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */ |
| 164096 | | - sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST |
| 164097 | | - ** because extra space is allocated to hold up |
| 164098 | | - ** to nTerm such values */ |
| 164179 | + sqlite3_value *aRhs[FLEXARRAY]; /* RHS values for constraints. MUST BE LAST |
| 164180 | + ** Extra space is allocated to hold up |
| 164181 | + ** to nTerm such values */ |
| 164099 | 164182 | }; |
| 164100 | 164183 | |
| 164184 | +/* Size (in bytes) of a HiddenIndeInfo object sufficient to hold as |
| 164185 | +** many as N constraints */ |
| 164186 | +#define SZ_HIDDENINDEXINFO(N) \ |
| 164187 | + (offsetof(HiddenIndexInfo,aRhs) + (N)*sizeof(sqlite3_value*)) |
| 164188 | + |
| 164101 | 164189 | /* Forward declaration of methods */ |
| 164102 | 164190 | static int whereLoopResize(sqlite3*, WhereLoop*, int); |
| 164103 | 164191 | |
| 164104 | 164192 | /* |
| 164105 | 164193 | ** Return the estimated number of output rows from a WHERE clause |
| | @@ -165573,12 +165661,12 @@ |
| 165573 | 165661 | |
| 165574 | 165662 | /* Allocate the sqlite3_index_info structure |
| 165575 | 165663 | */ |
| 165576 | 165664 | pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) |
| 165577 | 165665 | + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm |
| 165578 | | - + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) |
| 165579 | | - + sizeof(sqlite3_value*)*nTerm ); |
| 165666 | + + sizeof(*pIdxOrderBy)*nOrderBy |
| 165667 | + + SZ_HIDDENINDEXINFO(nTerm) ); |
| 165580 | 165668 | if( pIdxInfo==0 ){ |
| 165581 | 165669 | sqlite3ErrorMsg(pParse, "out of memory"); |
| 165582 | 165670 | return 0; |
| 165583 | 165671 | } |
| 165584 | 165672 | pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; |
| | @@ -170768,14 +170856,11 @@ |
| 170768 | 170856 | ** struct, the contents of WhereInfo.a[], the WhereClause structure |
| 170769 | 170857 | ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte |
| 170770 | 170858 | ** field (type Bitmask) it must be aligned on an 8-byte boundary on |
| 170771 | 170859 | ** some architectures. Hence the ROUND8() below. |
| 170772 | 170860 | */ |
| 170773 | | - nByteWInfo = ROUND8P(sizeof(WhereInfo)); |
| 170774 | | - if( nTabList>1 ){ |
| 170775 | | - nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); |
| 170776 | | - } |
| 170861 | + nByteWInfo = SZ_WHEREINFO(nTabList); |
| 170777 | 170862 | pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); |
| 170778 | 170863 | if( db->mallocFailed ){ |
| 170779 | 170864 | sqlite3DbFree(db, pWInfo); |
| 170780 | 170865 | pWInfo = 0; |
| 170781 | 170866 | goto whereBeginError; |
| | @@ -181607,11 +181692,15 @@ |
| 181607 | 181692 | tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); |
| 181608 | 181693 | }else if( tokenType==TK_FILTER ){ |
| 181609 | 181694 | assert( n==6 ); |
| 181610 | 181695 | tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); |
| 181611 | 181696 | #endif /* SQLITE_OMIT_WINDOWFUNC */ |
| 181612 | | - }else if( tokenType==TK_COMMENT && (db->flags & SQLITE_Comments)!=0 ){ |
| 181697 | + }else if( tokenType==TK_COMMENT |
| 181698 | + && (db->init.busy || (db->flags & SQLITE_Comments)!=0) |
| 181699 | + ){ |
| 181700 | + /* Ignore SQL comments if either (1) we are reparsing the schema or |
| 181701 | + ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */ |
| 181613 | 181702 | zSql += n; |
| 181614 | 181703 | continue; |
| 181615 | 181704 | }else if( tokenType!=TK_QNUMBER ){ |
| 181616 | 181705 | Token x; |
| 181617 | 181706 | x.z = zSql; |
| | @@ -182502,10 +182591,18 @@ |
| 182502 | 182591 | } |
| 182503 | 182592 | #endif |
| 182504 | 182593 | if( rc==SQLITE_OK ){ |
| 182505 | 182594 | sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, |
| 182506 | 182595 | sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); |
| 182596 | +#ifdef SQLITE_EXTRA_INIT_MUTEXED |
| 182597 | + { |
| 182598 | + int SQLITE_EXTRA_INIT_MUTEXED(const char*); |
| 182599 | + rc = SQLITE_EXTRA_INIT_MUTEXED(0); |
| 182600 | + } |
| 182601 | +#endif |
| 182602 | + } |
| 182603 | + if( rc==SQLITE_OK ){ |
| 182507 | 182604 | sqlite3MemoryBarrier(); |
| 182508 | 182605 | sqlite3GlobalConfig.isInit = 1; |
| 182509 | 182606 | #ifdef SQLITE_EXTRA_INIT |
| 182510 | 182607 | bRunExtraInit = 1; |
| 182511 | 182608 | #endif |
| | @@ -184063,10 +184160,14 @@ |
| 184063 | 184160 | sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); |
| 184064 | 184161 | sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); |
| 184065 | 184162 | } |
| 184066 | 184163 | } |
| 184067 | 184164 | sqlite3BtreeLeaveAll(db); |
| 184165 | +#endif |
| 184166 | +#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) |
| 184167 | + UNUSED_PARAMETER(db); |
| 184168 | + UNUSED_PARAMETER(flags); |
| 184068 | 184169 | #endif |
| 184069 | 184170 | return SQLITE_OK; |
| 184070 | 184171 | } |
| 184071 | 184172 | |
| 184072 | 184173 | /* |
| | @@ -186032,11 +186133,11 @@ |
| 186032 | 186133 | }else if( pData==0 ){ |
| 186033 | 186134 | sqlite3_mutex_leave(db->mutex); |
| 186034 | 186135 | return SQLITE_OK; |
| 186035 | 186136 | }else{ |
| 186036 | 186137 | size_t n = strlen(zName); |
| 186037 | | - p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); |
| 186138 | + p = sqlite3_malloc64( SZ_DBCLIENTDATA(n+1) ); |
| 186038 | 186139 | if( p==0 ){ |
| 186039 | 186140 | if( xDestructor ) xDestructor(pData); |
| 186040 | 186141 | sqlite3_mutex_leave(db->mutex); |
| 186041 | 186142 | return SQLITE_NOMEM; |
| 186042 | 186143 | } |
| | @@ -186398,12 +186499,12 @@ |
| 186398 | 186499 | #endif |
| 186399 | 186500 | |
| 186400 | 186501 | /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); |
| 186401 | 186502 | ** |
| 186402 | 186503 | ** If b is true, then activate the SQLITE_FkNoAction setting. If b is |
| 186403 | | - ** false then clearn that setting. If the SQLITE_FkNoAction setting is |
| 186404 | | - ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if |
| 186504 | + ** false then clear that setting. If the SQLITE_FkNoAction setting is |
| 186505 | + ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if |
| 186405 | 186506 | ** they were NO ACTION, regardless of how they are defined. |
| 186406 | 186507 | ** |
| 186407 | 186508 | ** NB: One must usually run "PRAGMA writable_schema=RESET" after |
| 186408 | 186509 | ** using this test-control, before it will take full effect. failing |
| 186409 | 186510 | ** to reset the schema can result in some unexpected behavior. |
| | @@ -187746,11 +187847,11 @@ |
| 187746 | 187847 | ** } |
| 187747 | 187848 | ** |
| 187748 | 187849 | ** Here, array { X } means zero or more occurrences of X, adjacent in |
| 187749 | 187850 | ** memory. A "position" is an index of a token in the token stream |
| 187750 | 187851 | ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur |
| 187751 | | -** in the same logical place as the position element, and act as sentinals |
| 187852 | +** in the same logical place as the position element, and act as sentinels |
| 187752 | 187853 | ** ending a position list array. POS_END is 0. POS_COLUMN is 1. |
| 187753 | 187854 | ** The positions numbers are not stored literally but rather as two more |
| 187754 | 187855 | ** than the difference from the prior position, or the just the position plus |
| 187755 | 187856 | ** 2 for the first position. Example: |
| 187756 | 187857 | ** |
| | @@ -188433,10 +188534,23 @@ |
| 188433 | 188534 | |
| 188434 | 188535 | #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) |
| 188435 | 188536 | #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) |
| 188436 | 188537 | |
| 188437 | 188538 | #define deliberate_fall_through |
| 188539 | + |
| 188540 | +/* |
| 188541 | +** Macros needed to provide flexible arrays in a portable way |
| 188542 | +*/ |
| 188543 | +#ifndef offsetof |
| 188544 | +# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 188545 | +#endif |
| 188546 | +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 188547 | +# define FLEXARRAY |
| 188548 | +#else |
| 188549 | +# define FLEXARRAY 1 |
| 188550 | +#endif |
| 188551 | + |
| 188438 | 188552 | |
| 188439 | 188553 | #endif /* SQLITE_AMALGAMATION */ |
| 188440 | 188554 | |
| 188441 | 188555 | #ifdef SQLITE_DEBUG |
| 188442 | 188556 | SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); |
| | @@ -188538,11 +188652,11 @@ |
| 188538 | 188652 | int inTransaction; /* True after xBegin but before xCommit/xRollback */ |
| 188539 | 188653 | int mxSavepoint; /* Largest valid xSavepoint integer */ |
| 188540 | 188654 | #endif |
| 188541 | 188655 | |
| 188542 | 188656 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 188543 | | - /* True to disable the incremental doclist optimization. This is controled |
| 188657 | + /* True to disable the incremental doclist optimization. This is controlled |
| 188544 | 188658 | ** by special insert command 'test-no-incr-doclist'. */ |
| 188545 | 188659 | int bNoIncrDoclist; |
| 188546 | 188660 | |
| 188547 | 188661 | /* Number of segments in a level */ |
| 188548 | 188662 | int nMergeCount; |
| | @@ -188590,11 +188704,11 @@ |
| 188590 | 188704 | #define FTS3_EVAL_NEXT 1 |
| 188591 | 188705 | #define FTS3_EVAL_MATCHINFO 2 |
| 188592 | 188706 | |
| 188593 | 188707 | /* |
| 188594 | 188708 | ** The Fts3Cursor.eSearch member is always set to one of the following. |
| 188595 | | -** Actualy, Fts3Cursor.eSearch can be greater than or equal to |
| 188709 | +** Actually, Fts3Cursor.eSearch can be greater than or equal to |
| 188596 | 188710 | ** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index |
| 188597 | 188711 | ** of the column to be searched. For example, in |
| 188598 | 188712 | ** |
| 188599 | 188713 | ** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); |
| 188600 | 188714 | ** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; |
| | @@ -188663,12 +188777,16 @@ |
| 188663 | 188777 | /* Variables below this point are populated by fts3_expr.c when parsing |
| 188664 | 188778 | ** a MATCH expression. Everything above is part of the evaluation phase. |
| 188665 | 188779 | */ |
| 188666 | 188780 | int nToken; /* Number of tokens in the phrase */ |
| 188667 | 188781 | int iColumn; /* Index of column this phrase must match */ |
| 188668 | | - Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ |
| 188782 | + Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */ |
| 188669 | 188783 | }; |
| 188784 | + |
| 188785 | +/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */ |
| 188786 | +#define SZ_FTS3PHRASE(N) \ |
| 188787 | + (offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken)) |
| 188670 | 188788 | |
| 188671 | 188789 | /* |
| 188672 | 188790 | ** A tree of these objects forms the RHS of a MATCH operator. |
| 188673 | 188791 | ** |
| 188674 | 188792 | ** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist |
| | @@ -191243,11 +191361,11 @@ |
| 191243 | 191361 | ** |
| 191244 | 191362 | ** The space required to store the output is therefore the sum of the |
| 191245 | 191363 | ** sizes of the two inputs, plus enough space for exactly one of the input |
| 191246 | 191364 | ** docids to grow. |
| 191247 | 191365 | ** |
| 191248 | | - ** A symetric argument may be made if the doclists are in descending |
| 191366 | + ** A symmetric argument may be made if the doclists are in descending |
| 191249 | 191367 | ** order. |
| 191250 | 191368 | */ |
| 191251 | 191369 | aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); |
| 191252 | 191370 | if( !aOut ) return SQLITE_NOMEM; |
| 191253 | 191371 | |
| | @@ -193341,11 +193459,11 @@ |
| 193341 | 193459 | ** |
| 193342 | 193460 | ** * features at least one token that uses an incremental doclist, and |
| 193343 | 193461 | ** |
| 193344 | 193462 | ** * does not contain any deferred tokens. |
| 193345 | 193463 | ** |
| 193346 | | -** Advance it to the next matching documnent in the database and populate |
| 193464 | +** Advance it to the next matching document in the database and populate |
| 193347 | 193465 | ** the Fts3Doclist.pList and nList fields. |
| 193348 | 193466 | ** |
| 193349 | 193467 | ** If there is no "next" entry and no error occurs, then *pbEof is set to |
| 193350 | 193468 | ** 1 before returning. Otherwise, if no error occurs and the iterator is |
| 193351 | 193469 | ** successfully advanced, *pbEof is set to 0. |
| | @@ -194348,11 +194466,11 @@ |
| 194348 | 194466 | |
| 194349 | 194467 | return rc; |
| 194350 | 194468 | } |
| 194351 | 194469 | |
| 194352 | 194470 | /* |
| 194353 | | -** Restart interation for expression pExpr so that the next call to |
| 194471 | +** Restart iteration for expression pExpr so that the next call to |
| 194354 | 194472 | ** fts3EvalNext() visits the first row. Do not allow incremental |
| 194355 | 194473 | ** loading or merging of phrase doclists for this iteration. |
| 194356 | 194474 | ** |
| 194357 | 194475 | ** If *pRc is other than SQLITE_OK when this function is called, it is |
| 194358 | 194476 | ** a no-op. If an error occurs within this function, *pRc is set to an |
| | @@ -195539,10 +195657,27 @@ |
| 195539 | 195657 | /* |
| 195540 | 195658 | ** Function getNextNode(), which is called by fts3ExprParse(), may itself |
| 195541 | 195659 | ** call fts3ExprParse(). So this forward declaration is required. |
| 195542 | 195660 | */ |
| 195543 | 195661 | static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); |
| 195662 | + |
| 195663 | +/* |
| 195664 | +** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis |
| 195665 | +** is defined, search for '(' and ')' as well. Return the index of the first |
| 195666 | +** such character in the buffer. If there is no such character, return -1. |
| 195667 | +*/ |
| 195668 | +static int findBarredChar(const char *z, int n){ |
| 195669 | + int ii; |
| 195670 | + for(ii=0; ii<n; ii++){ |
| 195671 | + if( (z[ii]=='"') |
| 195672 | + || (sqlite3_fts3_enable_parentheses && (z[ii]=='(' || z[ii]==')')) |
| 195673 | + ){ |
| 195674 | + return ii; |
| 195675 | + } |
| 195676 | + } |
| 195677 | + return -1; |
| 195678 | +} |
| 195544 | 195679 | |
| 195545 | 195680 | /* |
| 195546 | 195681 | ** Extract the next token from buffer z (length n) using the tokenizer |
| 195547 | 195682 | ** and other information (column names etc.) in pParse. Create an Fts3Expr |
| 195548 | 195683 | ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this |
| | @@ -195564,38 +195699,42 @@ |
| 195564 | 195699 | sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; |
| 195565 | 195700 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; |
| 195566 | 195701 | int rc; |
| 195567 | 195702 | sqlite3_tokenizer_cursor *pCursor; |
| 195568 | 195703 | Fts3Expr *pRet = 0; |
| 195569 | | - int i = 0; |
| 195570 | | - |
| 195571 | | - /* Set variable i to the maximum number of bytes of input to tokenize. */ |
| 195572 | | - for(i=0; i<n; i++){ |
| 195573 | | - if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break; |
| 195574 | | - if( z[i]=='"' ) break; |
| 195575 | | - } |
| 195576 | | - |
| 195577 | | - *pnConsumed = i; |
| 195578 | | - rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); |
| 195704 | + |
| 195705 | + *pnConsumed = n; |
| 195706 | + rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); |
| 195579 | 195707 | if( rc==SQLITE_OK ){ |
| 195580 | 195708 | const char *zToken; |
| 195581 | 195709 | int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; |
| 195582 | 195710 | sqlite3_int64 nByte; /* total space to allocate */ |
| 195583 | 195711 | |
| 195584 | 195712 | rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); |
| 195585 | 195713 | if( rc==SQLITE_OK ){ |
| 195586 | | - nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; |
| 195714 | + /* Check that this tokenization did not gobble up any " characters. Or, |
| 195715 | + ** if enable_parenthesis is true, that it did not gobble up any |
| 195716 | + ** open or close parenthesis characters either. If it did, call |
| 195717 | + ** getNextToken() again, but pass only that part of the input buffer |
| 195718 | + ** up to the first such character. */ |
| 195719 | + int iBarred = findBarredChar(z, iEnd); |
| 195720 | + if( iBarred>=0 ){ |
| 195721 | + pModule->xClose(pCursor); |
| 195722 | + return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed); |
| 195723 | + } |
| 195724 | + |
| 195725 | + nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken; |
| 195587 | 195726 | pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); |
| 195588 | 195727 | if( !pRet ){ |
| 195589 | 195728 | rc = SQLITE_NOMEM; |
| 195590 | 195729 | }else{ |
| 195591 | 195730 | pRet->eType = FTSQUERY_PHRASE; |
| 195592 | 195731 | pRet->pPhrase = (Fts3Phrase *)&pRet[1]; |
| 195593 | 195732 | pRet->pPhrase->nToken = 1; |
| 195594 | 195733 | pRet->pPhrase->iColumn = iCol; |
| 195595 | 195734 | pRet->pPhrase->aToken[0].n = nToken; |
| 195596 | | - pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; |
| 195735 | + pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1]; |
| 195597 | 195736 | memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); |
| 195598 | 195737 | |
| 195599 | 195738 | if( iEnd<n && z[iEnd]=='*' ){ |
| 195600 | 195739 | pRet->pPhrase->aToken[0].isPrefix = 1; |
| 195601 | 195740 | iEnd++; |
| | @@ -195615,11 +195754,15 @@ |
| 195615 | 195754 | } |
| 195616 | 195755 | } |
| 195617 | 195756 | |
| 195618 | 195757 | } |
| 195619 | 195758 | *pnConsumed = iEnd; |
| 195620 | | - }else if( i && rc==SQLITE_DONE ){ |
| 195759 | + }else if( n && rc==SQLITE_DONE ){ |
| 195760 | + int iBarred = findBarredChar(z, n); |
| 195761 | + if( iBarred>=0 ){ |
| 195762 | + *pnConsumed = iBarred; |
| 195763 | + } |
| 195621 | 195764 | rc = SQLITE_OK; |
| 195622 | 195765 | } |
| 195623 | 195766 | |
| 195624 | 195767 | pModule->xClose(pCursor); |
| 195625 | 195768 | } |
| | @@ -195664,11 +195807,11 @@ |
| 195664 | 195807 | Fts3Expr *p = 0; |
| 195665 | 195808 | sqlite3_tokenizer_cursor *pCursor = 0; |
| 195666 | 195809 | char *zTemp = 0; |
| 195667 | 195810 | i64 nTemp = 0; |
| 195668 | 195811 | |
| 195669 | | - const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); |
| 195812 | + const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1); |
| 195670 | 195813 | int nToken = 0; |
| 195671 | 195814 | |
| 195672 | 195815 | /* The final Fts3Expr data structure, including the Fts3Phrase, |
| 195673 | 195816 | ** Fts3PhraseToken structures token buffers are all stored as a single |
| 195674 | 195817 | ** allocation so that the expression can be freed with a single call to |
| | @@ -196036,11 +196179,11 @@ |
| 196036 | 196179 | int eType = p->eType; |
| 196037 | 196180 | isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); |
| 196038 | 196181 | |
| 196039 | 196182 | /* The isRequirePhrase variable is set to true if a phrase or |
| 196040 | 196183 | ** an expression contained in parenthesis is required. If a |
| 196041 | | - ** binary operator (AND, OR, NOT or NEAR) is encounted when |
| 196184 | + ** binary operator (AND, OR, NOT or NEAR) is encountered when |
| 196042 | 196185 | ** isRequirePhrase is set, this is a syntax error. |
| 196043 | 196186 | */ |
| 196044 | 196187 | if( !isPhrase && isRequirePhrase ){ |
| 196045 | 196188 | sqlite3Fts3ExprFree(p); |
| 196046 | 196189 | rc = SQLITE_ERROR; |
| | @@ -196618,11 +196761,10 @@ |
| 196618 | 196761 | pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr |
| 196619 | 196762 | ); |
| 196620 | 196763 | } |
| 196621 | 196764 | |
| 196622 | 196765 | if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ |
| 196623 | | - sqlite3Fts3ExprFree(pExpr); |
| 196624 | 196766 | sqlite3_result_error(context, "Error parsing expression", -1); |
| 196625 | 196767 | }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ |
| 196626 | 196768 | sqlite3_result_error_nomem(context); |
| 196627 | 196769 | }else{ |
| 196628 | 196770 | sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); |
| | @@ -196861,11 +197003,11 @@ |
| 196861 | 197003 | pEntry->count++; |
| 196862 | 197004 | pEntry->chain = pNew; |
| 196863 | 197005 | } |
| 196864 | 197006 | |
| 196865 | 197007 | |
| 196866 | | -/* Resize the hash table so that it cantains "new_size" buckets. |
| 197008 | +/* Resize the hash table so that it contains "new_size" buckets. |
| 196867 | 197009 | ** "new_size" must be a power of 2. The hash table might fail |
| 196868 | 197010 | ** to resize if sqliteMalloc() fails. |
| 196869 | 197011 | ** |
| 196870 | 197012 | ** Return non-zero if a memory allocation error occurs. |
| 196871 | 197013 | */ |
| | @@ -197316,11 +197458,11 @@ |
| 197316 | 197458 | isConsonant(z+2); |
| 197317 | 197459 | } |
| 197318 | 197460 | |
| 197319 | 197461 | /* |
| 197320 | 197462 | ** If the word ends with zFrom and xCond() is true for the stem |
| 197321 | | -** of the word that preceeds the zFrom ending, then change the |
| 197463 | +** of the word that precedes the zFrom ending, then change the |
| 197322 | 197464 | ** ending to zTo. |
| 197323 | 197465 | ** |
| 197324 | 197466 | ** The input word *pz and zFrom are both in reverse order. zTo |
| 197325 | 197467 | ** is in normal order. |
| 197326 | 197468 | ** |
| | @@ -202899,11 +203041,11 @@ |
| 202899 | 203041 | ** previous term. Before this function returns, it is updated to contain a |
| 202900 | 203042 | ** copy of zTerm/nTerm. |
| 202901 | 203043 | ** |
| 202902 | 203044 | ** It is assumed that the buffer associated with pNode is already large |
| 202903 | 203045 | ** enough to accommodate the new entry. The buffer associated with pPrev |
| 202904 | | -** is extended by this function if requrired. |
| 203046 | +** is extended by this function if required. |
| 202905 | 203047 | ** |
| 202906 | 203048 | ** If an error (i.e. OOM condition) occurs, an SQLite error code is |
| 202907 | 203049 | ** returned. Otherwise, SQLITE_OK. |
| 202908 | 203050 | */ |
| 202909 | 203051 | static int fts3AppendToNode( |
| | @@ -204562,11 +204704,11 @@ |
| 204562 | 204704 | #endif |
| 204563 | 204705 | |
| 204564 | 204706 | /* |
| 204565 | 204707 | ** SQLite value pRowid contains the rowid of a row that may or may not be |
| 204566 | 204708 | ** present in the FTS3 table. If it is, delete it and adjust the contents |
| 204567 | | -** of subsiduary data structures accordingly. |
| 204709 | +** of subsidiary data structures accordingly. |
| 204568 | 204710 | */ |
| 204569 | 204711 | static int fts3DeleteByRowid( |
| 204570 | 204712 | Fts3Table *p, |
| 204571 | 204713 | sqlite3_value *pRowid, |
| 204572 | 204714 | int *pnChng, /* IN/OUT: Decrement if row is deleted */ |
| | @@ -204888,12 +205030,16 @@ |
| 204888 | 205030 | struct MatchinfoBuffer { |
| 204889 | 205031 | u8 aRef[3]; |
| 204890 | 205032 | int nElem; |
| 204891 | 205033 | int bGlobal; /* Set if global data is loaded */ |
| 204892 | 205034 | char *zMatchinfo; |
| 204893 | | - u32 aMatchinfo[1]; |
| 205035 | + u32 aMI[FLEXARRAY]; |
| 204894 | 205036 | }; |
| 205037 | + |
| 205038 | +/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */ |
| 205039 | +#define SZ_MATCHINFOBUFFER(N) \ |
| 205040 | + (offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64)) |
| 204895 | 205041 | |
| 204896 | 205042 | |
| 204897 | 205043 | /* |
| 204898 | 205044 | ** The snippet() and offsets() functions both return text values. An instance |
| 204899 | 205045 | ** of the following structure is used to accumulate those values while the |
| | @@ -204915,17 +205061,17 @@ |
| 204915 | 205061 | ** Allocate a two-slot MatchinfoBuffer object. |
| 204916 | 205062 | */ |
| 204917 | 205063 | static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ |
| 204918 | 205064 | MatchinfoBuffer *pRet; |
| 204919 | 205065 | sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) |
| 204920 | | - + sizeof(MatchinfoBuffer); |
| 205066 | + + SZ_MATCHINFOBUFFER(1); |
| 204921 | 205067 | sqlite3_int64 nStr = strlen(zMatchinfo); |
| 204922 | 205068 | |
| 204923 | 205069 | pRet = sqlite3Fts3MallocZero(nByte + nStr+1); |
| 204924 | 205070 | if( pRet ){ |
| 204925 | | - pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; |
| 204926 | | - pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] |
| 205071 | + pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; |
| 205072 | + pRet->aMI[1+nElem] = pRet->aMI[0] |
| 204927 | 205073 | + sizeof(u32)*((int)nElem+1); |
| 204928 | 205074 | pRet->nElem = (int)nElem; |
| 204929 | 205075 | pRet->zMatchinfo = ((char*)pRet) + nByte; |
| 204930 | 205076 | memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1); |
| 204931 | 205077 | pRet->aRef[0] = 1; |
| | @@ -204935,14 +205081,14 @@ |
| 204935 | 205081 | } |
| 204936 | 205082 | |
| 204937 | 205083 | static void fts3MIBufferFree(void *p){ |
| 204938 | 205084 | MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); |
| 204939 | 205085 | |
| 204940 | | - assert( (u32*)p==&pBuf->aMatchinfo[1] |
| 204941 | | - || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] |
| 205086 | + assert( (u32*)p==&pBuf->aMI[1] |
| 205087 | + || (u32*)p==&pBuf->aMI[pBuf->nElem+2] |
| 204942 | 205088 | ); |
| 204943 | | - if( (u32*)p==&pBuf->aMatchinfo[1] ){ |
| 205089 | + if( (u32*)p==&pBuf->aMI[1] ){ |
| 204944 | 205090 | pBuf->aRef[1] = 0; |
| 204945 | 205091 | }else{ |
| 204946 | 205092 | pBuf->aRef[2] = 0; |
| 204947 | 205093 | } |
| 204948 | 205094 | |
| | @@ -204955,32 +205101,32 @@ |
| 204955 | 205101 | void (*xRet)(void*) = 0; |
| 204956 | 205102 | u32 *aOut = 0; |
| 204957 | 205103 | |
| 204958 | 205104 | if( p->aRef[1]==0 ){ |
| 204959 | 205105 | p->aRef[1] = 1; |
| 204960 | | - aOut = &p->aMatchinfo[1]; |
| 205106 | + aOut = &p->aMI[1]; |
| 204961 | 205107 | xRet = fts3MIBufferFree; |
| 204962 | 205108 | } |
| 204963 | 205109 | else if( p->aRef[2]==0 ){ |
| 204964 | 205110 | p->aRef[2] = 1; |
| 204965 | | - aOut = &p->aMatchinfo[p->nElem+2]; |
| 205111 | + aOut = &p->aMI[p->nElem+2]; |
| 204966 | 205112 | xRet = fts3MIBufferFree; |
| 204967 | 205113 | }else{ |
| 204968 | 205114 | aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); |
| 204969 | 205115 | if( aOut ){ |
| 204970 | 205116 | xRet = sqlite3_free; |
| 204971 | | - if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); |
| 205117 | + if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32)); |
| 204972 | 205118 | } |
| 204973 | 205119 | } |
| 204974 | 205120 | |
| 204975 | 205121 | *paOut = aOut; |
| 204976 | 205122 | return xRet; |
| 204977 | 205123 | } |
| 204978 | 205124 | |
| 204979 | 205125 | static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ |
| 204980 | 205126 | p->bGlobal = 1; |
| 204981 | | - memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32)); |
| 205127 | + memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32)); |
| 204982 | 205128 | } |
| 204983 | 205129 | |
| 204984 | 205130 | /* |
| 204985 | 205131 | ** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() |
| 204986 | 205132 | */ |
| | @@ -205391,11 +205537,11 @@ |
| 205391 | 205537 | if( nAppend<0 ){ |
| 205392 | 205538 | nAppend = (int)strlen(zAppend); |
| 205393 | 205539 | } |
| 205394 | 205540 | |
| 205395 | 205541 | /* If there is insufficient space allocated at StrBuffer.z, use realloc() |
| 205396 | | - ** to grow the buffer until so that it is big enough to accomadate the |
| 205542 | + ** to grow the buffer until so that it is big enough to accommodate the |
| 205397 | 205543 | ** appended data. |
| 205398 | 205544 | */ |
| 205399 | 205545 | if( pStr->n+nAppend+1>=pStr->nAlloc ){ |
| 205400 | 205546 | sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; |
| 205401 | 205547 | char *zNew = sqlite3_realloc64(pStr->z, nAlloc); |
| | @@ -207766,11 +207912,11 @@ |
| 207766 | 207912 | ** |
| 207767 | 207913 | ** When a match if found, the matching entry is moved to become the |
| 207768 | 207914 | ** most-recently used entry if it isn't so already. |
| 207769 | 207915 | ** |
| 207770 | 207916 | ** The JsonParse object returned still belongs to the Cache and might |
| 207771 | | -** be deleted at any moment. If the caller whants the JsonParse to |
| 207917 | +** be deleted at any moment. If the caller wants the JsonParse to |
| 207772 | 207918 | ** linger, it needs to increment the nPJRef reference counter. |
| 207773 | 207919 | */ |
| 207774 | 207920 | static JsonParse *jsonCacheSearch( |
| 207775 | 207921 | sqlite3_context *ctx, /* The SQL statement context holding the cache */ |
| 207776 | 207922 | sqlite3_value *pArg /* Function argument containing SQL text */ |
| | @@ -210811,11 +210957,11 @@ |
| 210811 | 210957 | ** |
| 210812 | 210958 | ** This goes against all historical documentation about how the SQLite |
| 210813 | 210959 | ** JSON functions were suppose to work. From the beginning, blob was |
| 210814 | 210960 | ** reserved for expansion and a blob value should have raised an error. |
| 210815 | 210961 | ** But it did not, due to a bug. And many applications came to depend |
| 210816 | | - ** upon this buggy behavior, espeically when using the CLI and reading |
| 210962 | + ** upon this buggy behavior, especially when using the CLI and reading |
| 210817 | 210963 | ** JSON text using readfile(), which returns a blob. For this reason |
| 210818 | 210964 | ** we will continue to support the bug moving forward. |
| 210819 | 210965 | ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d |
| 210820 | 210966 | */ |
| 210821 | 210967 | } |
| | @@ -212911,10 +213057,18 @@ |
| 212911 | 213057 | # define NEVER(X) ((X)?(assert(0),1):0) |
| 212912 | 213058 | #else |
| 212913 | 213059 | # define ALWAYS(X) (X) |
| 212914 | 213060 | # define NEVER(X) (X) |
| 212915 | 213061 | #endif |
| 213062 | +#ifndef offsetof |
| 213063 | +#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 213064 | +#endif |
| 213065 | +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 213066 | +# define FLEXARRAY |
| 213067 | +#else |
| 213068 | +# define FLEXARRAY 1 |
| 213069 | +#endif |
| 212916 | 213070 | #endif /* !defined(SQLITE_AMALGAMATION) */ |
| 212917 | 213071 | |
| 212918 | 213072 | /* Macro to check for 4-byte alignment. Only used inside of assert() */ |
| 212919 | 213073 | #ifdef SQLITE_DEBUG |
| 212920 | 213074 | # define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) |
| | @@ -213231,13 +213385,17 @@ |
| 213231 | 213385 | struct RtreeMatchArg { |
| 213232 | 213386 | u32 iSize; /* Size of this object */ |
| 213233 | 213387 | RtreeGeomCallback cb; /* Info about the callback functions */ |
| 213234 | 213388 | int nParam; /* Number of parameters to the SQL function */ |
| 213235 | 213389 | sqlite3_value **apSqlParam; /* Original SQL parameter values */ |
| 213236 | | - RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ |
| 213390 | + RtreeDValue aParam[FLEXARRAY]; /* Values for parameters to the SQL function */ |
| 213237 | 213391 | }; |
| 213238 | 213392 | |
| 213393 | +/* Size of an RtreeMatchArg object with N parameters */ |
| 213394 | +#define SZ_RTREEMATCHARG(N) \ |
| 213395 | + (offsetof(RtreeMatchArg,aParam)+(N)*sizeof(RtreeDValue)) |
| 213396 | + |
| 213239 | 213397 | #ifndef MAX |
| 213240 | 213398 | # define MAX(x,y) ((x) < (y) ? (y) : (x)) |
| 213241 | 213399 | #endif |
| 213242 | 213400 | #ifndef MIN |
| 213243 | 213401 | # define MIN(x,y) ((x) > (y) ? (y) : (x)) |
| | @@ -214922,11 +215080,11 @@ |
| 214922 | 215080 | |
| 214923 | 215081 | return rc; |
| 214924 | 215082 | } |
| 214925 | 215083 | |
| 214926 | 215084 | /* |
| 214927 | | -** Return the N-dimensional volumn of the cell stored in *p. |
| 215085 | +** Return the N-dimensional volume of the cell stored in *p. |
| 214928 | 215086 | */ |
| 214929 | 215087 | static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ |
| 214930 | 215088 | RtreeDValue area = (RtreeDValue)1; |
| 214931 | 215089 | assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); |
| 214932 | 215090 | #ifndef SQLITE_RTREE_INT_ONLY |
| | @@ -216688,11 +216846,11 @@ |
| 216688 | 216846 | } |
| 216689 | 216847 | |
| 216690 | 216848 | /* |
| 216691 | 216849 | ** The second and subsequent arguments to this function are a printf() |
| 216692 | 216850 | ** style format string and arguments. This function formats the string and |
| 216693 | | -** appends it to the report being accumuated in pCheck. |
| 216851 | +** appends it to the report being accumulated in pCheck. |
| 216694 | 216852 | */ |
| 216695 | 216853 | static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ |
| 216696 | 216854 | va_list ap; |
| 216697 | 216855 | va_start(ap, zFmt); |
| 216698 | 216856 | if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){ |
| | @@ -217876,11 +218034,11 @@ |
| 217876 | 218034 | |
| 217877 | 218035 | /* |
| 217878 | 218036 | ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). |
| 217879 | 218037 | ** Returns: |
| 217880 | 218038 | ** |
| 217881 | | -** +2 x0,y0 is on the line segement |
| 218039 | +** +2 x0,y0 is on the line segment |
| 217882 | 218040 | ** |
| 217883 | 218041 | ** +1 x0,y0 is beneath line segment |
| 217884 | 218042 | ** |
| 217885 | 218043 | ** 0 x0,y0 is not on or beneath the line segment or the line segment |
| 217886 | 218044 | ** is vertical and x0,y0 is not on the line segment |
| | @@ -217982,11 +218140,11 @@ |
| 217982 | 218140 | } |
| 217983 | 218141 | sqlite3_free(p1); |
| 217984 | 218142 | sqlite3_free(p2); |
| 217985 | 218143 | } |
| 217986 | 218144 | |
| 217987 | | -/* Objects used by the overlap algorihm. */ |
| 218145 | +/* Objects used by the overlap algorithm. */ |
| 217988 | 218146 | typedef struct GeoEvent GeoEvent; |
| 217989 | 218147 | typedef struct GeoSegment GeoSegment; |
| 217990 | 218148 | typedef struct GeoOverlap GeoOverlap; |
| 217991 | 218149 | struct GeoEvent { |
| 217992 | 218150 | double x; /* X coordinate at which event occurs */ |
| | @@ -219029,12 +219187,11 @@ |
| 219029 | 219187 | RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); |
| 219030 | 219188 | RtreeMatchArg *pBlob; |
| 219031 | 219189 | sqlite3_int64 nBlob; |
| 219032 | 219190 | int memErr = 0; |
| 219033 | 219191 | |
| 219034 | | - nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) |
| 219035 | | - + nArg*sizeof(sqlite3_value*); |
| 219192 | + nBlob = SZ_RTREEMATCHARG(nArg) + nArg*sizeof(sqlite3_value*); |
| 219036 | 219193 | pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); |
| 219037 | 219194 | if( !pBlob ){ |
| 219038 | 219195 | sqlite3_result_error_nomem(ctx); |
| 219039 | 219196 | }else{ |
| 219040 | 219197 | int i; |
| | @@ -220125,11 +220282,11 @@ |
| 220125 | 220282 | ** to read from the original database snapshot. In other words, partially |
| 220126 | 220283 | ** applied transactions are not visible to other clients. |
| 220127 | 220284 | ** |
| 220128 | 220285 | ** "RBU" stands for "Resumable Bulk Update". As in a large database update |
| 220129 | 220286 | ** transmitted via a wireless network to a mobile device. A transaction |
| 220130 | | -** applied using this extension is hence refered to as an "RBU update". |
| 220287 | +** applied using this extension is hence referred to as an "RBU update". |
| 220131 | 220288 | ** |
| 220132 | 220289 | ** |
| 220133 | 220290 | ** LIMITATIONS |
| 220134 | 220291 | ** |
| 220135 | 220292 | ** An "RBU update" transaction is subject to the following limitations: |
| | @@ -220422,11 +220579,11 @@ |
| 220422 | 220579 | ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents |
| 220423 | 220580 | ** of the state tables within the state database are zeroed. This way, |
| 220424 | 220581 | ** the next call to sqlite3rbu_vacuum() opens a handle that starts a |
| 220425 | 220582 | ** new RBU vacuum operation. |
| 220426 | 220583 | ** |
| 220427 | | -** As with sqlite3rbu_open(), Zipvfs users should rever to the comment |
| 220584 | +** As with sqlite3rbu_open(), Zipvfs users should refer to the comment |
| 220428 | 220585 | ** describing the sqlite3rbu_create_vfs() API function below for |
| 220429 | 220586 | ** a description of the complications associated with using RBU with |
| 220430 | 220587 | ** zipvfs databases. |
| 220431 | 220588 | */ |
| 220432 | 220589 | SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( |
| | @@ -220518,11 +220675,11 @@ |
| 220518 | 220675 | /* |
| 220519 | 220676 | ** Close an RBU handle. |
| 220520 | 220677 | ** |
| 220521 | 220678 | ** If the RBU update has been completely applied, mark the RBU database |
| 220522 | 220679 | ** as fully applied. Otherwise, assuming no error has occurred, save the |
| 220523 | | -** current state of the RBU update appliation to the RBU database. |
| 220680 | +** current state of the RBU update application to the RBU database. |
| 220524 | 220681 | ** |
| 220525 | 220682 | ** If an error has already occurred as part of an sqlite3rbu_step() |
| 220526 | 220683 | ** or sqlite3rbu_open() call, or if one occurs within this function, an |
| 220527 | 220684 | ** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, |
| 220528 | 220685 | ** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted |
| | @@ -225444,11 +225601,11 @@ |
| 225444 | 225601 | int rc; |
| 225445 | 225602 | rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); |
| 225446 | 225603 | |
| 225447 | 225604 | /* If this is an RBU vacuum operation and this is the target database, |
| 225448 | 225605 | ** pretend that it has at least one page. Otherwise, SQLite will not |
| 225449 | | - ** check for the existance of a *-wal file. rbuVfsRead() contains |
| 225606 | + ** check for the existence of a *-wal file. rbuVfsRead() contains |
| 225450 | 225607 | ** similar logic. */ |
| 225451 | 225608 | if( rc==SQLITE_OK && *pSize==0 |
| 225452 | 225609 | && p->pRbu && rbuIsVacuum(p->pRbu) |
| 225453 | 225610 | && (p->openFlags & SQLITE_OPEN_MAIN_DB) |
| 225454 | 225611 | ){ |
| | @@ -228674,11 +228831,11 @@ |
| 228674 | 228831 | } |
| 228675 | 228832 | |
| 228676 | 228833 | /* |
| 228677 | 228834 | ** This function is called to initialize the SessionTable.nCol, azCol[] |
| 228678 | 228835 | ** abPK[] and azDflt[] members of SessionTable object pTab. If these |
| 228679 | | -** fields are already initilialized, this function is a no-op. |
| 228836 | +** fields are already initialized, this function is a no-op. |
| 228680 | 228837 | ** |
| 228681 | 228838 | ** If an error occurs, an error code is stored in sqlite3_session.rc and |
| 228682 | 228839 | ** non-zero returned. Or, if no error occurs but the table has no primary |
| 228683 | 228840 | ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to |
| 228684 | 228841 | ** indicate that updates on this table should be ignored. SessionTable.abPK |
| | @@ -230497,11 +230654,11 @@ |
| 230497 | 230654 | int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ |
| 230498 | 230655 | void **ppChangeset /* OUT: Buffer containing changeset */ |
| 230499 | 230656 | ){ |
| 230500 | 230657 | sqlite3 *db = pSession->db; /* Source database handle */ |
| 230501 | 230658 | SessionTable *pTab; /* Used to iterate through attached tables */ |
| 230502 | | - SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ |
| 230659 | + SessionBuffer buf = {0,0,0}; /* Buffer in which to accumulate changeset */ |
| 230503 | 230660 | int rc; /* Return code */ |
| 230504 | 230661 | |
| 230505 | 230662 | assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) ); |
| 230506 | 230663 | assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) ); |
| 230507 | 230664 | |
| | @@ -234931,10 +235088,22 @@ |
| 234931 | 235088 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) |
| 234932 | 235089 | #else |
| 234933 | 235090 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) |
| 234934 | 235091 | #endif |
| 234935 | 235092 | |
| 235093 | +/* |
| 235094 | +** Macros needed to provide flexible arrays in a portable way |
| 235095 | +*/ |
| 235096 | +#ifndef offsetof |
| 235097 | +# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) |
| 235098 | +#endif |
| 235099 | +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
| 235100 | +# define FLEXARRAY |
| 235101 | +#else |
| 235102 | +# define FLEXARRAY 1 |
| 235103 | +#endif |
| 235104 | + |
| 234936 | 235105 | #endif |
| 234937 | 235106 | |
| 234938 | 235107 | /* Truncate very long tokens to this many bytes. Hard limit is |
| 234939 | 235108 | ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset |
| 234940 | 235109 | ** field that occurs at the start of each leaf page (see fts5_index.c). */ |
| | @@ -235003,14 +235172,15 @@ |
| 235003 | 235172 | ** |
| 235004 | 235173 | ** This object is used by fts5_expr.c and fts5_index.c. |
| 235005 | 235174 | */ |
| 235006 | 235175 | struct Fts5Colset { |
| 235007 | 235176 | int nCol; |
| 235008 | | - int aiCol[1]; |
| 235177 | + int aiCol[FLEXARRAY]; |
| 235009 | 235178 | }; |
| 235010 | 235179 | |
| 235011 | | - |
| 235180 | +/* Size (int bytes) of a complete Fts5Colset object with N columns. */ |
| 235181 | +#define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2)) |
| 235012 | 235182 | |
| 235013 | 235183 | /************************************************************************** |
| 235014 | 235184 | ** Interface to code in fts5_config.c. fts5_config.c contains contains code |
| 235015 | 235185 | ** to parse the arguments passed to the CREATE VIRTUAL TABLE statement. |
| 235016 | 235186 | */ |
| | @@ -235835,11 +236005,11 @@ |
| 235835 | 236005 | ************************************************************************* |
| 235836 | 236006 | ** Driver template for the LEMON parser generator. |
| 235837 | 236007 | ** |
| 235838 | 236008 | ** The "lemon" program processes an LALR(1) input grammar file, then uses |
| 235839 | 236009 | ** this template to construct a parser. The "lemon" program inserts text |
| 235840 | | -** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the |
| 236010 | +** at each "%%" line. Also, any "P-a-r-s-e" identifier prefix (without the |
| 235841 | 236011 | ** interstitial "-" characters) contained in this template is changed into |
| 235842 | 236012 | ** the value of the %name directive from the grammar. Otherwise, the content |
| 235843 | 236013 | ** of this template is copied straight through into the generate parser |
| 235844 | 236014 | ** source file. |
| 235845 | 236015 | ** |
| | @@ -237989,11 +238159,11 @@ |
| 237989 | 238159 | ** where "N" is the total number of documents in the set and nHit |
| 237990 | 238160 | ** is the number that contain at least one instance of the phrase |
| 237991 | 238161 | ** under consideration. |
| 237992 | 238162 | ** |
| 237993 | 238163 | ** The problem with this is that if (N < 2*nHit), the IDF is |
| 237994 | | - ** negative. Which is undesirable. So the mimimum allowable IDF is |
| 238164 | + ** negative. Which is undesirable. So the minimum allowable IDF is |
| 237995 | 238165 | ** (1e-6) - roughly the same as a term that appears in just over |
| 237996 | 238166 | ** half of set of 5,000,000 documents. */ |
| 237997 | 238167 | double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) ); |
| 237998 | 238168 | if( idf<=0.0 ) idf = 1e-6; |
| 237999 | 238169 | p->aIDF[i] = idf; |
| | @@ -238452,11 +238622,11 @@ |
| 238452 | 238622 | ** |
| 238453 | 238623 | ** * All non-ASCII characters, |
| 238454 | 238624 | ** * The 52 upper and lower case ASCII characters, and |
| 238455 | 238625 | ** * The 10 integer ASCII characters. |
| 238456 | 238626 | ** * The underscore character "_" (0x5F). |
| 238457 | | -** * The unicode "subsitute" character (0x1A). |
| 238627 | +** * The unicode "substitute" character (0x1A). |
| 238458 | 238628 | */ |
| 238459 | 238629 | static int sqlite3Fts5IsBareword(char t){ |
| 238460 | 238630 | u8 aBareword[128] = { |
| 238461 | 238631 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */ |
| 238462 | 238632 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */ |
| | @@ -239770,12 +239940,16 @@ |
| 239770 | 239940 | Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ |
| 239771 | 239941 | |
| 239772 | 239942 | /* Child nodes. For a NOT node, this array always contains 2 entries. For |
| 239773 | 239943 | ** AND or OR nodes, it contains 2 or more entries. */ |
| 239774 | 239944 | int nChild; /* Number of child nodes */ |
| 239775 | | - Fts5ExprNode *apChild[1]; /* Array of child nodes */ |
| 239945 | + Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */ |
| 239776 | 239946 | }; |
| 239947 | + |
| 239948 | +/* Size (in bytes) of an Fts5ExprNode object that holds up to N children */ |
| 239949 | +#define SZ_FTS5EXPRNODE(N) \ |
| 239950 | + (offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*)) |
| 239777 | 239951 | |
| 239778 | 239952 | #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) |
| 239779 | 239953 | |
| 239780 | 239954 | /* |
| 239781 | 239955 | ** Invoke the xNext method of an Fts5ExprNode object. This macro should be |
| | @@ -239803,24 +239977,31 @@ |
| 239803 | 239977 | */ |
| 239804 | 239978 | struct Fts5ExprPhrase { |
| 239805 | 239979 | Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */ |
| 239806 | 239980 | Fts5Buffer poslist; /* Current position list */ |
| 239807 | 239981 | int nTerm; /* Number of entries in aTerm[] */ |
| 239808 | | - Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */ |
| 239982 | + Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */ |
| 239809 | 239983 | }; |
| 239984 | + |
| 239985 | +/* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */ |
| 239986 | +#define SZ_FTS5EXPRPHRASE(N) \ |
| 239987 | + (offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm)) |
| 239810 | 239988 | |
| 239811 | 239989 | /* |
| 239812 | 239990 | ** One or more phrases that must appear within a certain token distance of |
| 239813 | 239991 | ** each other within each matching document. |
| 239814 | 239992 | */ |
| 239815 | 239993 | struct Fts5ExprNearset { |
| 239816 | 239994 | int nNear; /* NEAR parameter */ |
| 239817 | 239995 | Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */ |
| 239818 | 239996 | int nPhrase; /* Number of entries in aPhrase[] array */ |
| 239819 | | - Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */ |
| 239997 | + Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */ |
| 239820 | 239998 | }; |
| 239821 | 239999 | |
| 240000 | +/* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */ |
| 240001 | +#define SZ_FTS5EXPRNEARSET(N) \ |
| 240002 | + (offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*)) |
| 239822 | 240003 | |
| 239823 | 240004 | /* |
| 239824 | 240005 | ** Parse context. |
| 239825 | 240006 | */ |
| 239826 | 240007 | struct Fts5Parse { |
| | @@ -239976,11 +240157,11 @@ |
| 239976 | 240157 | assert_expr_depth_ok(sParse.rc, sParse.pExpr); |
| 239977 | 240158 | |
| 239978 | 240159 | /* If the LHS of the MATCH expression was a user column, apply the |
| 239979 | 240160 | ** implicit column-filter. */ |
| 239980 | 240161 | if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ |
| 239981 | | - int n = sizeof(Fts5Colset); |
| 240162 | + int n = SZ_FTS5COLSET(1); |
| 239982 | 240163 | Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); |
| 239983 | 240164 | if( pColset ){ |
| 239984 | 240165 | pColset->nCol = 1; |
| 239985 | 240166 | pColset->aiCol[0] = iCol; |
| 239986 | 240167 | sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); |
| | @@ -241334,11 +241515,11 @@ |
| 241334 | 241515 | Fts5ExprNearset *pRet = 0; |
| 241335 | 241516 | |
| 241336 | 241517 | if( pParse->rc==SQLITE_OK ){ |
| 241337 | 241518 | if( pNear==0 ){ |
| 241338 | 241519 | sqlite3_int64 nByte; |
| 241339 | | - nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); |
| 241520 | + nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1); |
| 241340 | 241521 | pRet = sqlite3_malloc64(nByte); |
| 241341 | 241522 | if( pRet==0 ){ |
| 241342 | 241523 | pParse->rc = SQLITE_NOMEM; |
| 241343 | 241524 | }else{ |
| 241344 | 241525 | memset(pRet, 0, (size_t)nByte); |
| | @@ -241345,11 +241526,11 @@ |
| 241345 | 241526 | } |
| 241346 | 241527 | }else if( (pNear->nPhrase % SZALLOC)==0 ){ |
| 241347 | 241528 | int nNew = pNear->nPhrase + SZALLOC; |
| 241348 | 241529 | sqlite3_int64 nByte; |
| 241349 | 241530 | |
| 241350 | | - nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); |
| 241531 | + nByte = SZ_FTS5EXPRNEARSET(nNew+1); |
| 241351 | 241532 | pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); |
| 241352 | 241533 | if( pRet==0 ){ |
| 241353 | 241534 | pParse->rc = SQLITE_NOMEM; |
| 241354 | 241535 | } |
| 241355 | 241536 | }else{ |
| | @@ -241436,16 +241617,16 @@ |
| 241436 | 241617 | if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){ |
| 241437 | 241618 | Fts5ExprPhrase *pNew; |
| 241438 | 241619 | int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); |
| 241439 | 241620 | |
| 241440 | 241621 | pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, |
| 241441 | | - sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew |
| 241622 | + SZ_FTS5EXPRPHRASE(nNew+1) |
| 241442 | 241623 | ); |
| 241443 | 241624 | if( pNew==0 ){ |
| 241444 | 241625 | rc = SQLITE_NOMEM; |
| 241445 | 241626 | }else{ |
| 241446 | | - if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase)); |
| 241627 | + if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1)); |
| 241447 | 241628 | pCtx->pPhrase = pPhrase = pNew; |
| 241448 | 241629 | pNew->nTerm = nNew - SZALLOC; |
| 241449 | 241630 | } |
| 241450 | 241631 | } |
| 241451 | 241632 | |
| | @@ -241549,11 +241730,11 @@ |
| 241549 | 241730 | } |
| 241550 | 241731 | |
| 241551 | 241732 | if( sCtx.pPhrase==0 ){ |
| 241552 | 241733 | /* This happens when parsing a token or quoted phrase that contains |
| 241553 | 241734 | ** no token characters at all. (e.g ... MATCH '""'). */ |
| 241554 | | - sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); |
| 241735 | + sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1)); |
| 241555 | 241736 | }else if( sCtx.pPhrase->nTerm ){ |
| 241556 | 241737 | sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; |
| 241557 | 241738 | } |
| 241558 | 241739 | assert( pParse->apPhrase!=0 ); |
| 241559 | 241740 | pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; |
| | @@ -241584,23 +241765,22 @@ |
| 241584 | 241765 | if( rc==SQLITE_OK ){ |
| 241585 | 241766 | pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, |
| 241586 | 241767 | sizeof(Fts5ExprPhrase*)); |
| 241587 | 241768 | } |
| 241588 | 241769 | if( rc==SQLITE_OK ){ |
| 241589 | | - pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, |
| 241590 | | - sizeof(Fts5ExprNode)); |
| 241770 | + pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1)); |
| 241591 | 241771 | } |
| 241592 | 241772 | if( rc==SQLITE_OK ){ |
| 241593 | 241773 | pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, |
| 241594 | | - sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); |
| 241774 | + SZ_FTS5EXPRNEARSET(2)); |
| 241595 | 241775 | } |
| 241596 | 241776 | if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ |
| 241597 | 241777 | Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; |
| 241598 | 241778 | if( pColsetOrig ){ |
| 241599 | 241779 | sqlite3_int64 nByte; |
| 241600 | 241780 | Fts5Colset *pColset; |
| 241601 | | - nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); |
| 241781 | + nByte = SZ_FTS5COLSET(pColsetOrig->nCol); |
| 241602 | 241782 | pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); |
| 241603 | 241783 | if( pColset ){ |
| 241604 | 241784 | memcpy(pColset, pColsetOrig, (size_t)nByte); |
| 241605 | 241785 | } |
| 241606 | 241786 | pNew->pRoot->pNear->pColset = pColset; |
| | @@ -241624,11 +241804,11 @@ |
| 241624 | 241804 | } |
| 241625 | 241805 | } |
| 241626 | 241806 | }else{ |
| 241627 | 241807 | /* This happens when parsing a token or quoted phrase that contains |
| 241628 | 241808 | ** no token characters at all. (e.g ... MATCH '""'). */ |
| 241629 | | - sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); |
| 241809 | + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1)); |
| 241630 | 241810 | } |
| 241631 | 241811 | } |
| 241632 | 241812 | |
| 241633 | 241813 | if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ |
| 241634 | 241814 | /* All the allocations succeeded. Put the expression object together. */ |
| | @@ -241718,11 +241898,11 @@ |
| 241718 | 241898 | Fts5Colset *pNew; /* New colset object to return */ |
| 241719 | 241899 | |
| 241720 | 241900 | assert( pParse->rc==SQLITE_OK ); |
| 241721 | 241901 | assert( iCol>=0 && iCol<pParse->pConfig->nCol ); |
| 241722 | 241902 | |
| 241723 | | - pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); |
| 241903 | + pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1)); |
| 241724 | 241904 | if( pNew==0 ){ |
| 241725 | 241905 | pParse->rc = SQLITE_NOMEM; |
| 241726 | 241906 | }else{ |
| 241727 | 241907 | int *aiCol = pNew->aiCol; |
| 241728 | 241908 | int i, j; |
| | @@ -241753,11 +241933,11 @@ |
| 241753 | 241933 | static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ |
| 241754 | 241934 | Fts5Colset *pRet; |
| 241755 | 241935 | int nCol = pParse->pConfig->nCol; |
| 241756 | 241936 | |
| 241757 | 241937 | pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, |
| 241758 | | - sizeof(Fts5Colset) + sizeof(int)*nCol |
| 241938 | + SZ_FTS5COLSET(nCol+1) |
| 241759 | 241939 | ); |
| 241760 | 241940 | if( pRet ){ |
| 241761 | 241941 | int i; |
| 241762 | 241942 | int iOld = 0; |
| 241763 | 241943 | for(i=0; i<nCol; i++){ |
| | @@ -241814,11 +241994,11 @@ |
| 241814 | 241994 | ** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. |
| 241815 | 241995 | */ |
| 241816 | 241996 | static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ |
| 241817 | 241997 | Fts5Colset *pRet; |
| 241818 | 241998 | if( pOrig ){ |
| 241819 | | - sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); |
| 241999 | + sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol); |
| 241820 | 242000 | pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); |
| 241821 | 242001 | if( pRet ){ |
| 241822 | 242002 | memcpy(pRet, pOrig, (size_t)nByte); |
| 241823 | 242003 | } |
| 241824 | 242004 | }else{ |
| | @@ -241982,21 +242162,21 @@ |
| 241982 | 242162 | Fts5ExprNode *pRet; |
| 241983 | 242163 | |
| 241984 | 242164 | assert( pNear->nPhrase==1 ); |
| 241985 | 242165 | assert( pParse->bPhraseToAnd ); |
| 241986 | 242166 | |
| 241987 | | - nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); |
| 242167 | + nByte = SZ_FTS5EXPRNODE(nTerm+1); |
| 241988 | 242168 | pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); |
| 241989 | 242169 | if( pRet ){ |
| 241990 | 242170 | pRet->eType = FTS5_AND; |
| 241991 | 242171 | pRet->nChild = nTerm; |
| 241992 | 242172 | pRet->iHeight = 1; |
| 241993 | 242173 | fts5ExprAssignXNext(pRet); |
| 241994 | 242174 | pParse->nPhrase--; |
| 241995 | 242175 | for(ii=0; ii<nTerm; ii++){ |
| 241996 | 242176 | Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero( |
| 241997 | | - &pParse->rc, sizeof(Fts5ExprPhrase) |
| 242177 | + &pParse->rc, SZ_FTS5EXPRPHRASE(1) |
| 241998 | 242178 | ); |
| 241999 | 242179 | if( pPhrase ){ |
| 242000 | 242180 | if( parseGrowPhraseArray(pParse) ){ |
| 242001 | 242181 | fts5ExprPhraseFree(pPhrase); |
| 242002 | 242182 | }else{ |
| | @@ -242061,11 +242241,11 @@ |
| 242061 | 242241 | nChild = 2; |
| 242062 | 242242 | if( pLeft->eType==eType ) nChild += pLeft->nChild-1; |
| 242063 | 242243 | if( pRight->eType==eType ) nChild += pRight->nChild-1; |
| 242064 | 242244 | } |
| 242065 | 242245 | |
| 242066 | | - nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); |
| 242246 | + nByte = SZ_FTS5EXPRNODE(nChild); |
| 242067 | 242247 | pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); |
| 242068 | 242248 | |
| 242069 | 242249 | if( pRet ){ |
| 242070 | 242250 | pRet->eType = eType; |
| 242071 | 242251 | pRet->pNear = pNear; |
| | @@ -242936,11 +243116,11 @@ |
| 242936 | 243116 | } |
| 242937 | 243117 | return rc; |
| 242938 | 243118 | } |
| 242939 | 243119 | |
| 242940 | 243120 | /* |
| 242941 | | -** Clear the token mappings for all Fts5IndexIter objects mannaged by |
| 243121 | +** Clear the token mappings for all Fts5IndexIter objects managed by |
| 242942 | 243122 | ** the expression passed as the only argument. |
| 242943 | 243123 | */ |
| 242944 | 243124 | static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ |
| 242945 | 243125 | int ii; |
| 242946 | 243126 | for(ii=0; ii<pExpr->nPhrase; ii++){ |
| | @@ -242971,11 +243151,11 @@ |
| 242971 | 243151 | |
| 242972 | 243152 | typedef struct Fts5HashEntry Fts5HashEntry; |
| 242973 | 243153 | |
| 242974 | 243154 | /* |
| 242975 | 243155 | ** This file contains the implementation of an in-memory hash table used |
| 242976 | | -** to accumuluate "term -> doclist" content before it is flused to a level-0 |
| 243156 | +** to accumulate "term -> doclist" content before it is flushed to a level-0 |
| 242977 | 243157 | ** segment. |
| 242978 | 243158 | */ |
| 242979 | 243159 | |
| 242980 | 243160 | |
| 242981 | 243161 | struct Fts5Hash { |
| | @@ -243028,11 +243208,11 @@ |
| 243028 | 243208 | int iPos; /* Position of last value written */ |
| 243029 | 243209 | i64 iRowid; /* Rowid of last value written */ |
| 243030 | 243210 | }; |
| 243031 | 243211 | |
| 243032 | 243212 | /* |
| 243033 | | -** Eqivalent to: |
| 243213 | +** Equivalent to: |
| 243034 | 243214 | ** |
| 243035 | 243215 | ** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } |
| 243036 | 243216 | */ |
| 243037 | 243217 | #define fts5EntryKey(p) ( ((char *)(&(p)[1])) ) |
| 243038 | 243218 | |
| | @@ -243964,13 +244144,17 @@ |
| 243964 | 244144 | int nRef; /* Object reference count */ |
| 243965 | 244145 | u64 nWriteCounter; /* Total leaves written to level 0 */ |
| 243966 | 244146 | u64 nOriginCntr; /* Origin value for next top-level segment */ |
| 243967 | 244147 | int nSegment; /* Total segments in this structure */ |
| 243968 | 244148 | int nLevel; /* Number of levels in this index */ |
| 243969 | | - Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ |
| 244149 | + Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */ |
| 243970 | 244150 | }; |
| 243971 | 244151 | |
| 244152 | +/* Size (in bytes) of an Fts5Structure object holding up to N levels */ |
| 244153 | +#define SZ_FTS5STRUCTURE(N) \ |
| 244154 | + (offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel)) |
| 244155 | + |
| 243972 | 244156 | /* |
| 243973 | 244157 | ** An object of type Fts5SegWriter is used to write to segments. |
| 243974 | 244158 | */ |
| 243975 | 244159 | struct Fts5PageWriter { |
| 243976 | 244160 | int pgno; /* Page number for this page */ |
| | @@ -244096,14 +244280,18 @@ |
| 244096 | 244280 | |
| 244097 | 244281 | /* |
| 244098 | 244282 | ** Array of tombstone pages. Reference counted. |
| 244099 | 244283 | */ |
| 244100 | 244284 | struct Fts5TombstoneArray { |
| 244101 | | - int nRef; /* Number of pointers to this object */ |
| 244285 | + int nRef; /* Number of pointers to this object */ |
| 244102 | 244286 | int nTombstone; |
| 244103 | | - Fts5Data *apTombstone[1]; /* Array of tombstone pages */ |
| 244287 | + Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */ |
| 244104 | 244288 | }; |
| 244289 | + |
| 244290 | +/* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */ |
| 244291 | +#define SZ_FTS5TOMBSTONEARRAY(N) \ |
| 244292 | + (offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*)) |
| 244105 | 244293 | |
| 244106 | 244294 | /* |
| 244107 | 244295 | ** Argument is a pointer to an Fts5Data structure that contains a |
| 244108 | 244296 | ** leaf page. |
| 244109 | 244297 | */ |
| | @@ -244169,12 +244357,15 @@ |
| 244169 | 244357 | int bRev; /* True to iterate in reverse order */ |
| 244170 | 244358 | u8 bSkipEmpty; /* True to skip deleted entries */ |
| 244171 | 244359 | |
| 244172 | 244360 | i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ |
| 244173 | 244361 | Fts5CResult *aFirst; /* Current merge state (see above) */ |
| 244174 | | - Fts5SegIter aSeg[1]; /* Array of segment iterators */ |
| 244362 | + Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */ |
| 244175 | 244363 | }; |
| 244364 | + |
| 244365 | +/* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */ |
| 244366 | +#define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter)) |
| 244176 | 244367 | |
| 244177 | 244368 | /* |
| 244178 | 244369 | ** An instance of the following type is used to iterate through the contents |
| 244179 | 244370 | ** of a doclist-index record. |
| 244180 | 244371 | ** |
| | @@ -244198,12 +244389,16 @@ |
| 244198 | 244389 | i64 iRowid; /* First rowid on leaf iLeafPgno */ |
| 244199 | 244390 | }; |
| 244200 | 244391 | struct Fts5DlidxIter { |
| 244201 | 244392 | int nLvl; |
| 244202 | 244393 | int iSegid; |
| 244203 | | - Fts5DlidxLvl aLvl[1]; |
| 244394 | + Fts5DlidxLvl aLvl[FLEXARRAY]; |
| 244204 | 244395 | }; |
| 244396 | + |
| 244397 | +/* Size (in bytes) of an Fts5DlidxIter object with up to N levels */ |
| 244398 | +#define SZ_FTS5DLIDXITER(N) \ |
| 244399 | + (offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl)) |
| 244205 | 244400 | |
| 244206 | 244401 | static void fts5PutU16(u8 *aOut, u16 iVal){ |
| 244207 | 244402 | aOut[0] = (iVal>>8); |
| 244208 | 244403 | aOut[1] = (iVal&0xFF); |
| 244209 | 244404 | } |
| | @@ -244568,11 +244763,11 @@ |
| 244568 | 244763 | ** an error occurs, (*pRc) is set to an SQLite error code before returning. |
| 244569 | 244764 | */ |
| 244570 | 244765 | static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ |
| 244571 | 244766 | Fts5Structure *p = *pp; |
| 244572 | 244767 | if( *pRc==SQLITE_OK && p->nRef>1 ){ |
| 244573 | | - i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel); |
| 244768 | + i64 nByte = SZ_FTS5STRUCTURE(p->nLevel); |
| 244574 | 244769 | Fts5Structure *pNew; |
| 244575 | 244770 | pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte); |
| 244576 | 244771 | if( pNew ){ |
| 244577 | 244772 | int i; |
| 244578 | 244773 | memcpy(pNew, p, nByte); |
| | @@ -244642,14 +244837,11 @@ |
| 244642 | 244837 | if( nLevel>FTS5_MAX_SEGMENT || nLevel<0 |
| 244643 | 244838 | || nSegment>FTS5_MAX_SEGMENT || nSegment<0 |
| 244644 | 244839 | ){ |
| 244645 | 244840 | return FTS5_CORRUPT; |
| 244646 | 244841 | } |
| 244647 | | - nByte = ( |
| 244648 | | - sizeof(Fts5Structure) + /* Main structure */ |
| 244649 | | - sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */ |
| 244650 | | - ); |
| 244842 | + nByte = SZ_FTS5STRUCTURE(nLevel); |
| 244651 | 244843 | pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte); |
| 244652 | 244844 | |
| 244653 | 244845 | if( pRet ){ |
| 244654 | 244846 | pRet->nRef = 1; |
| 244655 | 244847 | pRet->nLevel = nLevel; |
| | @@ -244725,14 +244917,11 @@ |
| 244725 | 244917 | fts5StructureMakeWritable(pRc, ppStruct); |
| 244726 | 244918 | assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK ); |
| 244727 | 244919 | if( *pRc==SQLITE_OK ){ |
| 244728 | 244920 | Fts5Structure *pStruct = *ppStruct; |
| 244729 | 244921 | int nLevel = pStruct->nLevel; |
| 244730 | | - sqlite3_int64 nByte = ( |
| 244731 | | - sizeof(Fts5Structure) + /* Main structure */ |
| 244732 | | - sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */ |
| 244733 | | - ); |
| 244922 | + sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2); |
| 244734 | 244923 | |
| 244735 | 244924 | pStruct = sqlite3_realloc64(pStruct, nByte); |
| 244736 | 244925 | if( pStruct ){ |
| 244737 | 244926 | memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel)); |
| 244738 | 244927 | pStruct->nLevel++; |
| | @@ -245267,11 +245456,11 @@ |
| 245267 | 245456 | Fts5DlidxIter *pIter = 0; |
| 245268 | 245457 | int i; |
| 245269 | 245458 | int bDone = 0; |
| 245270 | 245459 | |
| 245271 | 245460 | for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ |
| 245272 | | - sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); |
| 245461 | + sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1); |
| 245273 | 245462 | Fts5DlidxIter *pNew; |
| 245274 | 245463 | |
| 245275 | 245464 | pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); |
| 245276 | 245465 | if( pNew==0 ){ |
| 245277 | 245466 | p->rc = SQLITE_NOMEM; |
| | @@ -245485,11 +245674,11 @@ |
| 245485 | 245674 | ** leave an error in the Fts5Index object. |
| 245486 | 245675 | */ |
| 245487 | 245676 | static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ |
| 245488 | 245677 | const int nTomb = pIter->pSeg->nPgTombstone; |
| 245489 | 245678 | if( nTomb>0 ){ |
| 245490 | | - int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); |
| 245679 | + int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); |
| 245491 | 245680 | Fts5TombstoneArray *pNew; |
| 245492 | 245681 | pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); |
| 245493 | 245682 | if( pNew ){ |
| 245494 | 245683 | pNew->nTombstone = nTomb; |
| 245495 | 245684 | pNew->nRef = 1; |
| | @@ -246946,12 +247135,11 @@ |
| 246946 | 247135 | Fts5Iter *pNew; |
| 246947 | 247136 | i64 nSlot; /* Power of two >= nSeg */ |
| 246948 | 247137 | |
| 246949 | 247138 | for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2); |
| 246950 | 247139 | pNew = fts5IdxMalloc(p, |
| 246951 | | - sizeof(Fts5Iter) + /* pNew */ |
| 246952 | | - sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */ |
| 247140 | + SZ_FTS5ITER(nSlot) + /* pNew + pNew->aSeg[] */ |
| 246953 | 247141 | sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ |
| 246954 | 247142 | ); |
| 246955 | 247143 | if( pNew ){ |
| 246956 | 247144 | pNew->nSeg = nSlot; |
| 246957 | 247145 | pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot]; |
| | @@ -249313,11 +249501,11 @@ |
| 249313 | 249501 | static Fts5Structure *fts5IndexOptimizeStruct( |
| 249314 | 249502 | Fts5Index *p, |
| 249315 | 249503 | Fts5Structure *pStruct |
| 249316 | 249504 | ){ |
| 249317 | 249505 | Fts5Structure *pNew = 0; |
| 249318 | | - sqlite3_int64 nByte = sizeof(Fts5Structure); |
| 249506 | + sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1); |
| 249319 | 249507 | int nSeg = pStruct->nSegment; |
| 249320 | 249508 | int i; |
| 249321 | 249509 | |
| 249322 | 249510 | /* Figure out if this structure requires optimization. A structure does |
| 249323 | 249511 | ** not require optimization if either: |
| | @@ -249343,10 +249531,11 @@ |
| 249343 | 249531 | } |
| 249344 | 249532 | assert( pStruct->aLevel[i].nMerge<=nThis ); |
| 249345 | 249533 | } |
| 249346 | 249534 | |
| 249347 | 249535 | nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); |
| 249536 | + assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); |
| 249348 | 249537 | pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); |
| 249349 | 249538 | |
| 249350 | 249539 | if( pNew ){ |
| 249351 | 249540 | Fts5StructureLevel *pLvl; |
| 249352 | 249541 | nByte = nSeg * sizeof(Fts5StructureSegment); |
| | @@ -249919,12 +250108,16 @@ |
| 249919 | 250108 | /* The following are used for other full-token tokendata queries only. */ |
| 249920 | 250109 | int nIter; |
| 249921 | 250110 | int nIterAlloc; |
| 249922 | 250111 | Fts5PoslistReader *aPoslistReader; |
| 249923 | 250112 | int *aPoslistToIter; |
| 249924 | | - Fts5Iter *apIter[1]; |
| 250113 | + Fts5Iter *apIter[FLEXARRAY]; |
| 249925 | 250114 | }; |
| 250115 | + |
| 250116 | +/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */ |
| 250117 | +#define SZ_FTS5TOKENDATAITER(N) \ |
| 250118 | + (offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter)) |
| 249926 | 250119 | |
| 249927 | 250120 | /* |
| 249928 | 250121 | ** The two input arrays - a1[] and a2[] - are in sorted order. This function |
| 249929 | 250122 | ** merges the two arrays together and writes the result to output array |
| 249930 | 250123 | ** aOut[]. aOut[] is guaranteed to be large enough to hold the result. |
| | @@ -249993,11 +250186,11 @@ |
| 249993 | 250186 | } |
| 249994 | 250187 | |
| 249995 | 250188 | /* |
| 249996 | 250189 | ** Sort the contents of the pT->aMap[] array. |
| 249997 | 250190 | ** |
| 249998 | | -** The sorting algorithm requries a malloc(). If this fails, an error code |
| 250191 | +** The sorting algorithm requires a malloc(). If this fails, an error code |
| 249999 | 250192 | ** is left in Fts5Index.rc before returning. |
| 250000 | 250193 | */ |
| 250001 | 250194 | static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ |
| 250002 | 250195 | Fts5TokenDataMap *aTmp = 0; |
| 250003 | 250196 | int nByte = pT->nMap * sizeof(Fts5TokenDataMap); |
| | @@ -250184,11 +250377,11 @@ |
| 250184 | 250377 | if( iIdx==0 |
| 250185 | 250378 | && p->pConfig->eDetail==FTS5_DETAIL_FULL |
| 250186 | 250379 | && p->pConfig->bPrefixInsttoken |
| 250187 | 250380 | ){ |
| 250188 | 250381 | s.pTokendata = &s2; |
| 250189 | | - s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); |
| 250382 | + s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1)); |
| 250190 | 250383 | } |
| 250191 | 250384 | |
| 250192 | 250385 | if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ |
| 250193 | 250386 | s.xMerge = fts5MergeRowidLists; |
| 250194 | 250387 | s.xAppend = fts5AppendRowid; |
| | @@ -250312,19 +250505,21 @@ |
| 250312 | 250505 | ** The %_data table is completely empty when this function is called. This |
| 250313 | 250506 | ** function populates it with the initial structure objects for each index, |
| 250314 | 250507 | ** and the initial version of the "averages" record (a zero-byte blob). |
| 250315 | 250508 | */ |
| 250316 | 250509 | static int sqlite3Fts5IndexReinit(Fts5Index *p){ |
| 250317 | | - Fts5Structure s; |
| 250510 | + Fts5Structure *pTmp; |
| 250511 | + u8 tmpSpace[SZ_FTS5STRUCTURE(1)]; |
| 250318 | 250512 | fts5StructureInvalidate(p); |
| 250319 | 250513 | fts5IndexDiscardData(p); |
| 250320 | | - memset(&s, 0, sizeof(Fts5Structure)); |
| 250514 | + pTmp = (Fts5Structure*)tmpSpace; |
| 250515 | + memset(pTmp, 0, SZ_FTS5STRUCTURE(1)); |
| 250321 | 250516 | if( p->pConfig->bContentlessDelete ){ |
| 250322 | | - s.nOriginCntr = 1; |
| 250517 | + pTmp->nOriginCntr = 1; |
| 250323 | 250518 | } |
| 250324 | 250519 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); |
| 250325 | | - fts5StructureWrite(p, &s); |
| 250520 | + fts5StructureWrite(p, pTmp); |
| 250326 | 250521 | return fts5IndexReturn(p); |
| 250327 | 250522 | } |
| 250328 | 250523 | |
| 250329 | 250524 | /* |
| 250330 | 250525 | ** Open a new Fts5Index handle. If the bCreate argument is true, create |
| | @@ -250528,11 +250723,11 @@ |
| 250528 | 250723 | Fts5TokenDataIter *pRet = pIn; |
| 250529 | 250724 | |
| 250530 | 250725 | if( p->rc==SQLITE_OK ){ |
| 250531 | 250726 | if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ |
| 250532 | 250727 | int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; |
| 250533 | | - int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); |
| 250728 | + int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); |
| 250534 | 250729 | Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); |
| 250535 | 250730 | |
| 250536 | 250731 | if( pNew==0 ){ |
| 250537 | 250732 | p->rc = SQLITE_NOMEM; |
| 250538 | 250733 | }else{ |
| | @@ -251044,11 +251239,12 @@ |
| 251044 | 251239 | |
| 251045 | 251240 | memset(&ctx, 0, sizeof(ctx)); |
| 251046 | 251241 | |
| 251047 | 251242 | fts5BufferGrow(&p->rc, &token, nToken+1); |
| 251048 | 251243 | assert( token.p!=0 || p->rc!=SQLITE_OK ); |
| 251049 | | - ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); |
| 251244 | + ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, |
| 251245 | + SZ_FTS5TOKENDATAITER(1)); |
| 251050 | 251246 | |
| 251051 | 251247 | if( p->rc==SQLITE_OK ){ |
| 251052 | 251248 | |
| 251053 | 251249 | /* Fill in the token prefix to search for */ |
| 251054 | 251250 | token.p[0] = FTS5_MAIN_PREFIX; |
| | @@ -251175,11 +251371,12 @@ |
| 251175 | 251371 | assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); |
| 251176 | 251372 | assert( pIter->pTokenDataIter || pIter->nSeg>0 ); |
| 251177 | 251373 | if( pIter->nSeg>0 ){ |
| 251178 | 251374 | /* This is a prefix term iterator. */ |
| 251179 | 251375 | if( pT==0 ){ |
| 251180 | | - pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); |
| 251376 | + pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, |
| 251377 | + SZ_FTS5TOKENDATAITER(1)); |
| 251181 | 251378 | pIter->pTokenDataIter = pT; |
| 251182 | 251379 | } |
| 251183 | 251380 | if( pT ){ |
| 251184 | 251381 | fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); |
| 251185 | 251382 | fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); |
| | @@ -252209,11 +252406,11 @@ |
| 252209 | 252406 | } |
| 252210 | 252407 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 252211 | 252408 | |
| 252212 | 252409 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 252213 | 252410 | static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ |
| 252214 | | - int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ |
| 252411 | + int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid components */ |
| 252215 | 252412 | fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); |
| 252216 | 252413 | |
| 252217 | 252414 | if( iSegid==0 ){ |
| 252218 | 252415 | if( iKey==FTS5_AVERAGES_ROWID ){ |
| 252219 | 252416 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} "); |
| | @@ -253170,13 +253367,15 @@ |
| 253170 | 253367 | struct Fts5Sorter { |
| 253171 | 253368 | sqlite3_stmt *pStmt; |
| 253172 | 253369 | i64 iRowid; /* Current rowid */ |
| 253173 | 253370 | const u8 *aPoslist; /* Position lists for current row */ |
| 253174 | 253371 | int nIdx; /* Number of entries in aIdx[] */ |
| 253175 | | - int aIdx[1]; /* Offsets into aPoslist for current row */ |
| 253372 | + int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */ |
| 253176 | 253373 | }; |
| 253177 | 253374 | |
| 253375 | +/* Size (int bytes) of an Fts5Sorter object with N indexes */ |
| 253376 | +#define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64)) |
| 253178 | 253377 | |
| 253179 | 253378 | /* |
| 253180 | 253379 | ** Virtual-table cursor object. |
| 253181 | 253380 | ** |
| 253182 | 253381 | ** iSpecial: |
| | @@ -254050,11 +254249,11 @@ |
| 254050 | 254249 | int rc; |
| 254051 | 254250 | const char *zRank = pCsr->zRank; |
| 254052 | 254251 | const char *zRankArgs = pCsr->zRankArgs; |
| 254053 | 254252 | |
| 254054 | 254253 | nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); |
| 254055 | | - nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1); |
| 254254 | + nByte = SZ_FTS5SORTER(nPhrase); |
| 254056 | 254255 | pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); |
| 254057 | 254256 | if( pSorter==0 ) return SQLITE_NOMEM; |
| 254058 | 254257 | memset(pSorter, 0, (size_t)nByte); |
| 254059 | 254258 | pSorter->nIdx = nPhrase; |
| 254060 | 254259 | |
| | @@ -256576,11 +256775,11 @@ |
| 256576 | 256775 | int nArg, /* Number of args */ |
| 256577 | 256776 | sqlite3_value **apUnused /* Function arguments */ |
| 256578 | 256777 | ){ |
| 256579 | 256778 | assert( nArg==0 ); |
| 256580 | 256779 | UNUSED_PARAM2(nArg, apUnused); |
| 256581 | | - sqlite3_result_text(pCtx, "fts5: 2025-02-25 16:39:51 6f0b6d95db17e69ac7e46a39f52770291ac4cfe43eea09add224946a6e11f04e", -1, SQLITE_TRANSIENT); |
| 256780 | + sqlite3_result_text(pCtx, "fts5: 2025-03-16 00:13:29 18bda13e197e4b4ec7464b3e70012f71edc05f73d8b14bb48bad452f81c7e185", -1, SQLITE_TRANSIENT); |
| 256582 | 256781 | } |
| 256583 | 256782 | |
| 256584 | 256783 | /* |
| 256585 | 256784 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 256586 | 256785 | ** |
| 256587 | 256786 | |