| | @@ -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 | | -** fee71cd6f7294ffd02784d26811a9d11d80e with changes in files: |
| 21 | +** 3bd5456e50ef321f2cafcf67261d556a7606 with changes in files: |
| 22 | 22 | ** |
| 23 | 23 | ** |
| 24 | 24 | */ |
| 25 | 25 | #ifndef SQLITE_AMALGAMATION |
| 26 | 26 | #define SQLITE_CORE 1 |
| | @@ -467,14 +467,14 @@ |
| 467 | 467 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 468 | 468 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 469 | 469 | */ |
| 470 | 470 | #define SQLITE_VERSION "3.54.0" |
| 471 | 471 | #define SQLITE_VERSION_NUMBER 3054000 |
| 472 | | -#define SQLITE_SOURCE_ID "2026-08-11 10:46:12 fee71cd6f7294ffd02784d26811a9d11d80e83d4075e1233b8ec0289519bb891" |
| 472 | +#define SQLITE_SOURCE_ID "2026-08-20 13:25:12 3bd5456e50ef321f2cafcf67261d556a760624ce0caab430ed9454cebec233e7" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-08-11T10:46:12.896Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-08-20T13:25:12.207Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -4755,10 +4755,14 @@ |
| 4755 | 4755 | ** [prepared statement] may start.</dd>)^ |
| 4756 | 4756 | ** |
| 4757 | 4757 | ** [[SQLITE_LIMIT_SCHEMA]] ^(<dt>SQLITE_LIMIT_SCHEMA</dt> |
| 4758 | 4758 | ** <dd>The maximum number of objects (tables, indexes, triggers, and views) |
| 4759 | 4759 | ** defined by the database schema.</dd>)^ |
| 4760 | +** |
| 4761 | +** [[SQLITE_LIMIT_TRIGGER_STEPS]] ^(<dt>SQLITE_LIMIT_TRIGGER_STEPS</dt> |
| 4762 | +** <dd>The maximum number of SQL statements that can be contained within |
| 4763 | +** a single trigger.</dd>)^ |
| 4760 | 4764 | ** </dl> |
| 4761 | 4765 | */ |
| 4762 | 4766 | #define SQLITE_LIMIT_LENGTH 0 |
| 4763 | 4767 | #define SQLITE_LIMIT_SQL_LENGTH 1 |
| 4764 | 4768 | #define SQLITE_LIMIT_COLUMN 2 |
| | @@ -4771,10 +4775,11 @@ |
| 4771 | 4775 | #define SQLITE_LIMIT_VARIABLE_NUMBER 9 |
| 4772 | 4776 | #define SQLITE_LIMIT_TRIGGER_DEPTH 10 |
| 4773 | 4777 | #define SQLITE_LIMIT_WORKER_THREADS 11 |
| 4774 | 4778 | #define SQLITE_LIMIT_PARSER_DEPTH 12 |
| 4775 | 4779 | #define SQLITE_LIMIT_SCHEMA 13 |
| 4780 | +#define SQLITE_LIMIT_TRIGGER_STEPS 14 |
| 4776 | 4781 | |
| 4777 | 4782 | /* |
| 4778 | 4783 | ** CAPI3REF: Prepare Flags |
| 4779 | 4784 | ** |
| 4780 | 4785 | ** These constants define various flags that can be passed into the |
| | @@ -15067,10 +15072,18 @@ |
| 15067 | 15072 | */ |
| 15068 | 15073 | #ifndef SQLITE_MAX_SCHEMA |
| 15069 | 15074 | # define SQLITE_MAX_SCHEMA 10000000 |
| 15070 | 15075 | #endif |
| 15071 | 15076 | |
| 15077 | +/* |
| 15078 | +** Maximum number of SQL statements allowed in the body of a single |
| 15079 | +** trigger. |
| 15080 | +*/ |
| 15081 | +#ifndef SQLITE_MAX_TRIGGER_STEPS |
| 15082 | +# define SQLITE_MAX_TRIGGER_STEPS 65000 |
| 15083 | +#endif |
| 15084 | + |
| 15072 | 15085 | /************** End of sqliteLimit.h *****************************************/ |
| 15073 | 15086 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| 15074 | 15087 | |
| 15075 | 15088 | /* Disable nuisance warnings on Borland compilers */ |
| 15076 | 15089 | #if defined(__BORLANDC__) |
| | @@ -15143,29 +15156,42 @@ |
| 15143 | 15156 | ** |
| 15144 | 15157 | ** SQLITE_INLINE Strive to in-line this function |
| 15145 | 15158 | ** |
| 15146 | 15159 | ** SQLITE_OPT_INLINE In-line this function if building the |
| 15147 | 15160 | ** amalgamation. |
| 15161 | +** |
| 15162 | +** SQLITE_USES_INLINE Set to 1 or 0 according to whether or not |
| 15163 | +** inline functions are supported. |
| 15148 | 15164 | */ |
| 15149 | | -#if defined(__GNUC__) |
| 15165 | +#if defined(SQLITE_DISABLE_INLINE) |
| 15166 | +# define SQLITE_NOINLINE |
| 15167 | +# define SQLITE_INLINE |
| 15168 | +# define SQLITE_OPT_INLINE |
| 15169 | +# define SQLITE_USES_INLINE 0 |
| 15170 | +#elif defined(__GNUC__) |
| 15150 | 15171 | # define SQLITE_NOINLINE __attribute__((noinline)) |
| 15151 | 15172 | # define SQLITE_INLINE __attribute__((always_inline)) inline |
| 15152 | 15173 | # define SQLITE_OPT_INLINE __attribute__((always_inline)) inline |
| 15174 | +# define SQLITE_USES_INLINE 1 |
| 15153 | 15175 | #elif defined(_MSC_VER) && _MSC_VER>=1310 |
| 15154 | 15176 | # define SQLITE_NOINLINE __declspec(noinline) |
| 15155 | 15177 | # define SQLITE_INLINE __forceinline |
| 15156 | 15178 | # define SQLITE_OPT_INLINE __forceinline |
| 15179 | +# define SQLITE_USES_INLINE 1 |
| 15157 | 15180 | #else |
| 15158 | 15181 | # define SQLITE_NOINLINE |
| 15159 | 15182 | # define SQLITE_INLINE |
| 15160 | 15183 | # define SQLITE_OPT_INLINE |
| 15184 | +# define SQLITE_USES_INLINE 0 |
| 15161 | 15185 | #endif |
| 15162 | 15186 | #if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__) |
| 15163 | 15187 | # undef SQLITE_INLINE |
| 15164 | 15188 | # define SQLITE_INLINE |
| 15165 | 15189 | # undef SQLITE_OPT_INLINE |
| 15166 | 15190 | # define SQLITE_OPT_INLINE |
| 15191 | +# undef SQLITE_USES_INLINE |
| 15192 | +# define SQLITE_USES_INLINE 0 |
| 15167 | 15193 | #endif |
| 15168 | 15194 | #if !defined(SQLITE_AMALGAMATION) |
| 15169 | 15195 | # undef SQLITE_OPT_INLINE |
| 15170 | 15196 | # define SQLITE_OPT_INLINE |
| 15171 | 15197 | #endif |
| | @@ -17694,12 +17720,10 @@ |
| 17694 | 17720 | int p3; /* The third parameter */ |
| 17695 | 17721 | union p4union { /* fourth parameter */ |
| 17696 | 17722 | int i; /* Integer value if p4type==P4_INT32 */ |
| 17697 | 17723 | void *p; /* Generic pointer */ |
| 17698 | 17724 | char *z; /* Pointer to data for string (char array) types */ |
| 17699 | | - i64 *pI64; /* Used when p4type is P4_INT64 */ |
| 17700 | | - double *pReal; /* Used when p4type is P4_REAL */ |
| 17701 | 17725 | FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ |
| 17702 | 17726 | sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ |
| 17703 | 17727 | CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ |
| 17704 | 17728 | Mem *pMem; /* Used when p4type is P4_MEM */ |
| 17705 | 17729 | VTable *pVtab; /* Used when p4type is P4_VTAB */ |
| | @@ -17750,10 +17774,23 @@ |
| 17750 | 17774 | signed char p1; /* First operand */ |
| 17751 | 17775 | signed char p2; /* Second parameter (often the jump destination) */ |
| 17752 | 17776 | signed char p3; /* Third parameter */ |
| 17753 | 17777 | }; |
| 17754 | 17778 | typedef struct VdbeOpList VdbeOpList; |
| 17779 | + |
| 17780 | +/* |
| 17781 | +** Combine two int32 values into a single int64. The least significant |
| 17782 | +** term comes first. |
| 17783 | +*/ |
| 17784 | +#define INT32_TO_64(a,b) (i64)(((u64)(u32)(b)<<32)|(u32)(a)) |
| 17785 | + |
| 17786 | +/* |
| 17787 | +** Return an int32 that is the lower or upper 32-bits of an int64. |
| 17788 | +*/ |
| 17789 | +#define LOWER32(x) (int)(((u64)(x))&0xffffffff) |
| 17790 | +#define UPPER32(x) (int)(((u64)(x))>>32) |
| 17791 | + |
| 17755 | 17792 | |
| 17756 | 17793 | /* |
| 17757 | 17794 | ** Allowed values of VdbeOp.p4type |
| 17758 | 17795 | */ |
| 17759 | 17796 | #define P4_NOTUSED 0 /* The P4 parameter is not used */ |
| | @@ -17770,16 +17807,14 @@ |
| 17770 | 17807 | #define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ |
| 17771 | 17808 | #define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ |
| 17772 | 17809 | #define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ |
| 17773 | 17810 | #define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ |
| 17774 | 17811 | #define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ |
| 17775 | | -#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ |
| 17776 | | -#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ |
| 17777 | | -#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ |
| 17778 | | -#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ |
| 17779 | | -#define P4_TABLEREF (-17) /* Like P4_TABLE, but reference counted */ |
| 17780 | | -#define P4_SUBRTNSIG (-18) /* P4 is a SubrtnSig pointer */ |
| 17812 | +#define P4_INTARRAY (-13) /* P4 is a vector of 32-bit integers */ |
| 17813 | +#define P4_FUNCCTX (-14) /* P4 is a pointer to an sqlite3_context object */ |
| 17814 | +#define P4_TABLEREF (-15) /* Like P4_TABLE, but reference counted */ |
| 17815 | +#define P4_SUBRTNSIG (-16) /* P4 is a SubrtnSig pointer */ |
| 17781 | 17816 | |
| 17782 | 17817 | /* Error message codes for OP_Halt */ |
| 17783 | 17818 | #define P5_ConstraintNotNull 1 |
| 17784 | 17819 | #define P5_ConstraintUnique 2 |
| 17785 | 17820 | #define P5_ConstraintCheck 3 |
| | @@ -17891,11 +17926,11 @@ |
| 17891 | 17926 | #define OP_Return 69 |
| 17892 | 17927 | #define OP_EndCoroutine 70 |
| 17893 | 17928 | #define OP_HaltIfNull 71 /* synopsis: if r[P3]=null halt */ |
| 17894 | 17929 | #define OP_Halt 72 |
| 17895 | 17930 | #define OP_Integer 73 /* synopsis: r[P2]=P1 */ |
| 17896 | | -#define OP_Int64 74 /* synopsis: r[P2]=P4 */ |
| 17931 | +#define OP_Int64 74 /* synopsis: r[P2]=PINT13 */ |
| 17897 | 17932 | #define OP_String 75 /* synopsis: r[P2]='P4' (len=P1) */ |
| 17898 | 17933 | #define OP_BeginSubrtn 76 /* synopsis: r[P2]=NULL */ |
| 17899 | 17934 | #define OP_Null 77 /* synopsis: r[P2..P3]=NULL */ |
| 17900 | 17935 | #define OP_SoftNull 78 /* synopsis: r[P1]=NULL */ |
| 17901 | 17936 | #define OP_Blob 79 /* synopsis: r[P2]=P4 (len=P1) */ |
| | @@ -17942,11 +17977,11 @@ |
| 17942 | 17977 | #define OP_OpenEphemeral 120 /* synopsis: nColumn=P2 */ |
| 17943 | 17978 | #define OP_SorterOpen 121 |
| 17944 | 17979 | #define OP_SequenceTest 122 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ |
| 17945 | 17980 | #define OP_OpenPseudo 123 /* synopsis: P3 columns in r[P2] */ |
| 17946 | 17981 | #define OP_Close 124 |
| 17947 | | -#define OP_ColumnsUsed 125 |
| 17982 | +#define OP_ColumnsUsed 125 /* synopsis: Cursor P1 uses columns PHEX23 */ |
| 17948 | 17983 | #define OP_SeekScan 126 /* synopsis: Scan-ahead up to P1 rows */ |
| 17949 | 17984 | #define OP_SeekHit 127 /* synopsis: set P2<=seekHit<=P3 */ |
| 17950 | 17985 | #define OP_Sequence 128 /* synopsis: r[P2]=cursor[P1].ctr++ */ |
| 17951 | 17986 | #define OP_NewRowid 129 /* synopsis: r[P2]=rowid */ |
| 17952 | 17987 | #define OP_Insert 130 /* synopsis: intkey=r[P3] data=r[P2] */ |
| | @@ -17971,11 +18006,11 @@ |
| 17971 | 18006 | #define OP_CreateBtree 149 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ |
| 17972 | 18007 | #define OP_SqlExec 150 |
| 17973 | 18008 | #define OP_ParseSchema 151 |
| 17974 | 18009 | #define OP_LoadAnalysis 152 |
| 17975 | 18010 | #define OP_DropTable 153 |
| 17976 | | -#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 18011 | +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=PDBL13 */ |
| 17977 | 18012 | #define OP_DropIndex 155 |
| 17978 | 18013 | #define OP_DropTrigger 156 |
| 17979 | 18014 | #define OP_IntegrityCk 157 |
| 17980 | 18015 | #define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */ |
| 17981 | 18016 | #define OP_Param 159 |
| | @@ -18079,12 +18114,13 @@ |
| 18079 | 18114 | SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); |
| 18080 | 18115 | SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); |
| 18081 | 18116 | SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); |
| 18082 | 18117 | SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); |
| 18083 | 18118 | SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); |
| 18119 | +SQLITE_PRIVATE int sqlite3VdbeAddInt64(Vdbe*,int,i64); |
| 18120 | +SQLITE_PRIVATE int sqlite3VdbeAddDouble(Vdbe*,int,double); |
| 18084 | 18121 | SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); |
| 18085 | | -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); |
| 18086 | 18122 | SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); |
| 18087 | 18123 | SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); |
| 18088 | 18124 | SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); |
| 18089 | 18125 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) |
| 18090 | 18126 | SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); |
| | @@ -18331,10 +18367,11 @@ |
| 18331 | 18367 | ** This header file defines the interface that the sqlite page cache |
| 18332 | 18368 | ** subsystem. |
| 18333 | 18369 | */ |
| 18334 | 18370 | |
| 18335 | 18371 | #ifndef _PCACHE_H_ |
| 18372 | +#define _PCACHE_H_ |
| 18336 | 18373 | |
| 18337 | 18374 | typedef struct PgHdr PgHdr; |
| 18338 | 18375 | typedef struct PCache PCache; |
| 18339 | 18376 | |
| 18340 | 18377 | /* |
| | @@ -18689,11 +18726,11 @@ |
| 18689 | 18726 | |
| 18690 | 18727 | /* |
| 18691 | 18728 | ** The number of different kinds of things that can be limited |
| 18692 | 18729 | ** using the sqlite3_limit() interface. |
| 18693 | 18730 | */ |
| 18694 | | -#define SQLITE_N_LIMIT (SQLITE_LIMIT_SCHEMA+1) |
| 18731 | +#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_STEPS+1) |
| 18695 | 18732 | |
| 18696 | 18733 | /* |
| 18697 | 18734 | ** Lookaside malloc is a set of fixed-size buffers that can be used |
| 18698 | 18735 | ** to satisfy small transient memory allocation requests for objects |
| 18699 | 18736 | ** associated with a particular database connection. The use of |
| | @@ -21008,10 +21045,17 @@ |
| 21008 | 21045 | ParseCleanup *pNext; /* Next cleanup task */ |
| 21009 | 21046 | void *pPtr; /* Pointer to object to deallocate */ |
| 21010 | 21047 | void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ |
| 21011 | 21048 | }; |
| 21012 | 21049 | |
| 21050 | +/* |
| 21051 | +** Number of 64-bit entried in the variable number bitmap cache (VNBMC). |
| 21052 | +*/ |
| 21053 | +#ifndef SQLITE_VNBMC |
| 21054 | +# define SQLITE_VNBMC 2 |
| 21055 | +#endif |
| 21056 | + |
| 21013 | 21057 | /* |
| 21014 | 21058 | ** An SQL parser context. A copy of this structure is passed through |
| 21015 | 21059 | ** the parser and down into all the parser action routine in order to |
| 21016 | 21060 | ** carry around information that is global to the entire parse. |
| 21017 | 21061 | ** |
| | @@ -21126,10 +21170,11 @@ |
| 21126 | 21170 | ** first field in the recursive region. |
| 21127 | 21171 | ************************************************************************/ |
| 21128 | 21172 | |
| 21129 | 21173 | Token sLastToken; /* The last token parsed */ |
| 21130 | 21174 | ynVar nVar; /* Number of '?' variables seen in the SQL so far */ |
| 21175 | + u64 aVnbmc[SQLITE_VNBMC]; /* Varible Number Bitmap Cache */ |
| 21131 | 21176 | u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ |
| 21132 | 21177 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| 21133 | 21178 | u8 eParseMode; /* PARSE_MODE_XXX constant */ |
| 21134 | 21179 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 21135 | 21180 | int nVtabLock; /* Number of virtual tables to lock */ |
| | @@ -22165,10 +22210,11 @@ |
| 22165 | 22210 | SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); |
| 22166 | 22211 | SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); |
| 22167 | 22212 | SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); |
| 22168 | 22213 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); |
| 22169 | 22214 | SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); |
| 22215 | +SQLITE_PRIVATE int sqlite3ExprCanReturnSubtype(Parse*,Expr*); |
| 22170 | 22216 | SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); |
| 22171 | 22217 | SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); |
| 22172 | 22218 | SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); |
| 22173 | 22219 | SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); |
| 22174 | 22220 | SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); |
| | @@ -22389,10 +22435,11 @@ |
| 22389 | 22435 | SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); |
| 22390 | 22436 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); |
| 22391 | 22437 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); |
| 22392 | 22438 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); |
| 22393 | 22439 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); |
| 22440 | +SQLITE_PRIVATE int sqlite3ExprListIsConstant(Parse *pParse, ExprList *pList, int bNoIs); |
| 22394 | 22441 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 22395 | 22442 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 22396 | 22443 | #endif |
| 22397 | 22444 | SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); |
| 22398 | 22445 | SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); |
| | @@ -22544,10 +22591,11 @@ |
| 22544 | 22591 | ** be defined locally, but now we use the varint routines in the util.c |
| 22545 | 22592 | ** file. |
| 22546 | 22593 | */ |
| 22547 | 22594 | SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); |
| 22548 | 22595 | SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); |
| 22596 | +SQLITE_PRIVATE i64 sqlite3VarintValue(const unsigned char*); |
| 22549 | 22597 | SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); |
| 22550 | 22598 | SQLITE_PRIVATE int sqlite3VarintLen(u64 v); |
| 22551 | 22599 | |
| 22552 | 22600 | /* |
| 22553 | 22601 | ** The common case is for a varint to be a single byte. They following |
| | @@ -22559,13 +22607,10 @@ |
| 22559 | 22607 | #define getVarint32NR(A,B) \ |
| 22560 | 22608 | B=(u32)*(A);if(B>=0x80)sqlite3GetVarint32((A),(u32*)&(B)) |
| 22561 | 22609 | #define putVarint32(A,B) \ |
| 22562 | 22610 | (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ |
| 22563 | 22611 | sqlite3PutVarint((A),(B))) |
| 22564 | | -#define getVarint sqlite3GetVarint |
| 22565 | | -#define putVarint sqlite3PutVarint |
| 22566 | | - |
| 22567 | 22612 | |
| 22568 | 22613 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); |
| 22569 | 22614 | SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); |
| 22570 | 22615 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 22571 | 22616 | SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); |
| | @@ -38343,176 +38388,88 @@ |
| 38343 | 38388 | p[1] = v&0x7f; |
| 38344 | 38389 | return 2; |
| 38345 | 38390 | } |
| 38346 | 38391 | return putVarint64(p,v); |
| 38347 | 38392 | } |
| 38348 | | - |
| 38349 | | -/* |
| 38350 | | -** Bitmasks used by sqlite3GetVarint(). These precomputed constants |
| 38351 | | -** are defined here rather than simply putting the constant expressions |
| 38352 | | -** inline in order to work around bugs in the RVT compiler. |
| 38353 | | -** |
| 38354 | | -** SLOT_2_0 A mask for (0x7f<<14) | 0x7f |
| 38355 | | -** |
| 38356 | | -** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 |
| 38357 | | -*/ |
| 38358 | | -#define SLOT_2_0 0x001fc07f |
| 38359 | | -#define SLOT_4_2_0 0xf01fc07f |
| 38360 | | - |
| 38361 | 38393 | |
| 38362 | 38394 | /* |
| 38363 | 38395 | ** Read a 64-bit variable-length integer from memory starting at p[0]. |
| 38364 | 38396 | ** Return the number of bytes read. The value is stored in *v. |
| 38365 | 38397 | */ |
| 38366 | 38398 | SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ |
| 38367 | | - u32 a,b,s; |
| 38368 | | - |
| 38369 | | - if( ((signed char*)p)[0]>=0 ){ |
| 38370 | | - *v = *p; |
| 38371 | | - return 1; |
| 38372 | | - } |
| 38373 | | - if( ((signed char*)p)[1]>=0 ){ |
| 38374 | | - *v = ((u32)(p[0]&0x7f)<<7) | p[1]; |
| 38375 | | - return 2; |
| 38376 | | - } |
| 38377 | | - |
| 38378 | | - /* Verify that constants are precomputed correctly */ |
| 38379 | | - assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); |
| 38380 | | - assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); |
| 38381 | | - |
| 38382 | | - a = ((u32)p[0])<<14; |
| 38383 | | - b = p[1]; |
| 38384 | | - p += 2; |
| 38385 | | - a |= *p; |
| 38386 | | - /* a: p0<<14 | p2 (unmasked) */ |
| 38387 | | - if (!(a&0x80)) |
| 38388 | | - { |
| 38389 | | - a &= SLOT_2_0; |
| 38390 | | - b &= 0x7f; |
| 38391 | | - b = b<<7; |
| 38392 | | - a |= b; |
| 38393 | | - *v = a; |
| 38394 | | - return 3; |
| 38395 | | - } |
| 38396 | | - |
| 38397 | | - /* CSE1 from below */ |
| 38398 | | - a &= SLOT_2_0; |
| 38399 | | - p++; |
| 38400 | | - b = b<<14; |
| 38401 | | - b |= *p; |
| 38402 | | - /* b: p1<<14 | p3 (unmasked) */ |
| 38403 | | - if (!(b&0x80)) |
| 38404 | | - { |
| 38405 | | - b &= SLOT_2_0; |
| 38406 | | - /* moved CSE1 up */ |
| 38407 | | - /* a &= (0x7f<<14)|(0x7f); */ |
| 38408 | | - a = a<<7; |
| 38409 | | - a |= b; |
| 38410 | | - *v = a; |
| 38411 | | - return 4; |
| 38412 | | - } |
| 38413 | | - |
| 38414 | | - /* a: p0<<14 | p2 (masked) */ |
| 38415 | | - /* b: p1<<14 | p3 (unmasked) */ |
| 38416 | | - /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
| 38417 | | - /* moved CSE1 up */ |
| 38418 | | - /* a &= (0x7f<<14)|(0x7f); */ |
| 38419 | | - b &= SLOT_2_0; |
| 38420 | | - s = a; |
| 38421 | | - /* s: p0<<14 | p2 (masked) */ |
| 38422 | | - |
| 38423 | | - p++; |
| 38424 | | - a = a<<14; |
| 38425 | | - a |= *p; |
| 38426 | | - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ |
| 38427 | | - if (!(a&0x80)) |
| 38428 | | - { |
| 38429 | | - /* we can skip these cause they were (effectively) done above |
| 38430 | | - ** while calculating s */ |
| 38431 | | - /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ |
| 38432 | | - /* b &= (0x7f<<14)|(0x7f); */ |
| 38433 | | - b = b<<7; |
| 38434 | | - a |= b; |
| 38435 | | - s = s>>18; |
| 38436 | | - *v = ((u64)s)<<32 | a; |
| 38437 | | - return 5; |
| 38438 | | - } |
| 38439 | | - |
| 38440 | | - /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
| 38441 | | - s = s<<7; |
| 38442 | | - s |= b; |
| 38443 | | - /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
| 38444 | | - |
| 38445 | | - p++; |
| 38446 | | - b = b<<14; |
| 38447 | | - b |= *p; |
| 38448 | | - /* b: p1<<28 | p3<<14 | p5 (unmasked) */ |
| 38449 | | - if (!(b&0x80)) |
| 38450 | | - { |
| 38451 | | - /* we can skip this cause it was (effectively) done above in calc'ing s */ |
| 38452 | | - /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ |
| 38453 | | - a &= SLOT_2_0; |
| 38454 | | - a = a<<7; |
| 38455 | | - a |= b; |
| 38456 | | - s = s>>18; |
| 38457 | | - *v = ((u64)s)<<32 | a; |
| 38458 | | - return 6; |
| 38459 | | - } |
| 38460 | | - |
| 38461 | | - p++; |
| 38462 | | - a = a<<14; |
| 38463 | | - a |= *p; |
| 38464 | | - /* a: p2<<28 | p4<<14 | p6 (unmasked) */ |
| 38465 | | - if (!(a&0x80)) |
| 38466 | | - { |
| 38467 | | - a &= SLOT_4_2_0; |
| 38468 | | - b &= SLOT_2_0; |
| 38469 | | - b = b<<7; |
| 38470 | | - a |= b; |
| 38471 | | - s = s>>11; |
| 38472 | | - *v = ((u64)s)<<32 | a; |
| 38473 | | - return 7; |
| 38474 | | - } |
| 38475 | | - |
| 38476 | | - /* CSE2 from below */ |
| 38477 | | - a &= SLOT_2_0; |
| 38478 | | - p++; |
| 38479 | | - b = b<<14; |
| 38480 | | - b |= *p; |
| 38481 | | - /* b: p3<<28 | p5<<14 | p7 (unmasked) */ |
| 38482 | | - if (!(b&0x80)) |
| 38483 | | - { |
| 38484 | | - b &= SLOT_4_2_0; |
| 38485 | | - /* moved CSE2 up */ |
| 38486 | | - /* a &= (0x7f<<14)|(0x7f); */ |
| 38487 | | - a = a<<7; |
| 38488 | | - a |= b; |
| 38489 | | - s = s>>4; |
| 38490 | | - *v = ((u64)s)<<32 | a; |
| 38491 | | - return 8; |
| 38492 | | - } |
| 38493 | | - |
| 38494 | | - p++; |
| 38495 | | - a = a<<15; |
| 38496 | | - a |= *p; |
| 38497 | | - /* a: p4<<29 | p6<<15 | p8 (unmasked) */ |
| 38498 | | - |
| 38499 | | - /* moved CSE2 up */ |
| 38500 | | - /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ |
| 38501 | | - b &= SLOT_2_0; |
| 38502 | | - b = b<<8; |
| 38503 | | - a |= b; |
| 38504 | | - |
| 38505 | | - s = s<<4; |
| 38506 | | - b = p[-4]; |
| 38507 | | - b &= 0x7f; |
| 38508 | | - b = b>>3; |
| 38509 | | - s |= b; |
| 38510 | | - |
| 38511 | | - *v = ((u64)s)<<32 | a; |
| 38512 | | - |
| 38513 | | - return 9; |
| 38399 | + u64 iKey = p[0]; |
| 38400 | + const u8 *pStart = p; |
| 38401 | + if( iKey>=0x80 ){ |
| 38402 | + u8 x; |
| 38403 | + iKey = (iKey<<7) ^ (x = *++p); |
| 38404 | + if( x>=0x80 ){ |
| 38405 | + iKey = (iKey<<7) ^ (x = *++p); |
| 38406 | + if( x>=0x80 ){ |
| 38407 | + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++p); |
| 38408 | + if( x>=0x80 ){ |
| 38409 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38410 | + if( x>=0x80 ){ |
| 38411 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38412 | + if( x>=0x80 ){ |
| 38413 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38414 | + if( x>=0x80 ){ |
| 38415 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38416 | + if( x>=0x80 ){ |
| 38417 | + iKey = (iKey<<8) ^ 0x8000 ^ (*++p); |
| 38418 | + } |
| 38419 | + } |
| 38420 | + } |
| 38421 | + } |
| 38422 | + } |
| 38423 | + }else{ |
| 38424 | + iKey ^= 0x204000; |
| 38425 | + } |
| 38426 | + }else{ |
| 38427 | + iKey ^= 0x4000; |
| 38428 | + } |
| 38429 | + } |
| 38430 | + *v = iKey; |
| 38431 | + return (u8)(p - pStart) + 1; |
| 38432 | +} |
| 38433 | + |
| 38434 | +/* |
| 38435 | +** Return the value of a variable-length integer without computing |
| 38436 | +** its length. This is an optimization on sqlite3GetVarint() for the |
| 38437 | +** cases when the return value of sqlite3GetVarint() is not needed. |
| 38438 | +*/ |
| 38439 | +SQLITE_PRIVATE i64 sqlite3VarintValue(const unsigned char *p){ |
| 38440 | + u64 iKey = p[0]; |
| 38441 | + if( iKey>=0x80 ){ |
| 38442 | + u8 x; |
| 38443 | + iKey = (iKey<<7) ^ (x = *++p); |
| 38444 | + if( x>=0x80 ){ |
| 38445 | + iKey = (iKey<<7) ^ (x = *++p); |
| 38446 | + if( x>=0x80 ){ |
| 38447 | + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++p); |
| 38448 | + if( x>=0x80 ){ |
| 38449 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38450 | + if( x>=0x80 ){ |
| 38451 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38452 | + if( x>=0x80 ){ |
| 38453 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38454 | + if( x>=0x80 ){ |
| 38455 | + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); |
| 38456 | + if( x>=0x80 ){ |
| 38457 | + iKey = (iKey<<8) ^ 0x8000 ^ (*++p); |
| 38458 | + } |
| 38459 | + } |
| 38460 | + } |
| 38461 | + } |
| 38462 | + } |
| 38463 | + }else{ |
| 38464 | + iKey ^= 0x204000; |
| 38465 | + } |
| 38466 | + }else{ |
| 38467 | + iKey ^= 0x4000; |
| 38468 | + } |
| 38469 | + } |
| 38470 | + return *(i64*)&iKey; |
| 38514 | 38471 | } |
| 38515 | 38472 | |
| 38516 | 38473 | /* |
| 38517 | 38474 | ** Read a 32-bit variable-length integer from memory starting at p[0]. |
| 38518 | 38475 | ** Return the number of bytes read. The value is stored in *v. |
| | @@ -39405,11 +39362,11 @@ |
| 39405 | 39362 | /* 69 */ "Return" OpHelp(""), |
| 39406 | 39363 | /* 70 */ "EndCoroutine" OpHelp(""), |
| 39407 | 39364 | /* 71 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), |
| 39408 | 39365 | /* 72 */ "Halt" OpHelp(""), |
| 39409 | 39366 | /* 73 */ "Integer" OpHelp("r[P2]=P1"), |
| 39410 | | - /* 74 */ "Int64" OpHelp("r[P2]=P4"), |
| 39367 | + /* 74 */ "Int64" OpHelp("r[P2]=PINT13"), |
| 39411 | 39368 | /* 75 */ "String" OpHelp("r[P2]='P4' (len=P1)"), |
| 39412 | 39369 | /* 76 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), |
| 39413 | 39370 | /* 77 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 39414 | 39371 | /* 78 */ "SoftNull" OpHelp("r[P1]=NULL"), |
| 39415 | 39372 | /* 79 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| | @@ -39456,11 +39413,11 @@ |
| 39456 | 39413 | /* 120 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 39457 | 39414 | /* 121 */ "SorterOpen" OpHelp(""), |
| 39458 | 39415 | /* 122 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), |
| 39459 | 39416 | /* 123 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), |
| 39460 | 39417 | /* 124 */ "Close" OpHelp(""), |
| 39461 | | - /* 125 */ "ColumnsUsed" OpHelp(""), |
| 39418 | + /* 125 */ "ColumnsUsed" OpHelp("Cursor P1 uses columns PHEX23"), |
| 39462 | 39419 | /* 126 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), |
| 39463 | 39420 | /* 127 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), |
| 39464 | 39421 | /* 128 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), |
| 39465 | 39422 | /* 129 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 39466 | 39423 | /* 130 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| | @@ -39485,11 +39442,11 @@ |
| 39485 | 39442 | /* 149 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), |
| 39486 | 39443 | /* 150 */ "SqlExec" OpHelp(""), |
| 39487 | 39444 | /* 151 */ "ParseSchema" OpHelp(""), |
| 39488 | 39445 | /* 152 */ "LoadAnalysis" OpHelp(""), |
| 39489 | 39446 | /* 153 */ "DropTable" OpHelp(""), |
| 39490 | | - /* 154 */ "Real" OpHelp("r[P2]=P4"), |
| 39447 | + /* 154 */ "Real" OpHelp("r[P2]=PDBL13"), |
| 39491 | 39448 | /* 155 */ "DropIndex" OpHelp(""), |
| 39492 | 39449 | /* 156 */ "DropTrigger" OpHelp(""), |
| 39493 | 39450 | /* 157 */ "IntegrityCk" OpHelp(""), |
| 39494 | 39451 | /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 39495 | 39452 | /* 159 */ "Param" OpHelp(""), |
| | @@ -57486,10 +57443,11 @@ |
| 57486 | 57443 | |
| 57487 | 57444 | nNew = 2*(u64)p->nHash; |
| 57488 | 57445 | if( nNew<256 ){ |
| 57489 | 57446 | nNew = 256; |
| 57490 | 57447 | } |
| 57448 | + assert( (nNew & (nNew-1))==0 ); /* nNew is always a power of two */ |
| 57491 | 57449 | |
| 57492 | 57450 | pcache1LeaveMutex(p->pGroup); |
| 57493 | 57451 | if( p->nHash ){ sqlite3BeginBenignMalloc(); } |
| 57494 | 57452 | apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); |
| 57495 | 57453 | if( p->nHash ){ sqlite3EndBenignMalloc(); } |
| | @@ -57497,11 +57455,11 @@ |
| 57497 | 57455 | if( apNew ){ |
| 57498 | 57456 | for(i=0; i<p->nHash; i++){ |
| 57499 | 57457 | PgHdr1 *pPage; |
| 57500 | 57458 | PgHdr1 *pNext = p->apHash[i]; |
| 57501 | 57459 | while( (pPage = pNext)!=0 ){ |
| 57502 | | - unsigned int h = pPage->iKey % nNew; |
| 57460 | + unsigned int h = (unsigned int)(pPage->iKey & (nNew-1)); |
| 57503 | 57461 | pNext = pPage->pNext; |
| 57504 | 57462 | pPage->pNext = apNew[h]; |
| 57505 | 57463 | apNew[h] = pPage; |
| 57506 | 57464 | } |
| 57507 | 57465 | } |
| | @@ -57547,11 +57505,12 @@ |
| 57547 | 57505 | unsigned int h; |
| 57548 | 57506 | PCache1 *pCache = pPage->pCache; |
| 57549 | 57507 | PgHdr1 **pp; |
| 57550 | 57508 | |
| 57551 | 57509 | assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); |
| 57552 | | - h = pPage->iKey % pCache->nHash; |
| 57510 | + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); |
| 57511 | + h = pPage->iKey & (pCache->nHash-1); |
| 57553 | 57512 | for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); |
| 57554 | 57513 | *pp = (*pp)->pNext; |
| 57555 | 57514 | |
| 57556 | 57515 | pCache->nPage--; |
| 57557 | 57516 | if( freeFlag ) pcache1FreePage(pPage); |
| | @@ -57592,18 +57551,18 @@ |
| 57592 | 57551 | ){ |
| 57593 | 57552 | TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ |
| 57594 | 57553 | unsigned int h, iStop; |
| 57595 | 57554 | assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); |
| 57596 | 57555 | assert( pCache->iMaxKey >= iLimit ); |
| 57597 | | - assert( pCache->nHash > 0 ); |
| 57556 | + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); |
| 57598 | 57557 | if( pCache->iMaxKey - iLimit < pCache->nHash ){ |
| 57599 | 57558 | /* If we are just shaving the last few pages off the end of the |
| 57600 | 57559 | ** cache, then there is no point in scanning the entire hash table. |
| 57601 | 57560 | ** Only scan those hash slots that might contain pages that need to |
| 57602 | 57561 | ** be removed. */ |
| 57603 | | - h = iLimit % pCache->nHash; |
| 57604 | | - iStop = pCache->iMaxKey % pCache->nHash; |
| 57562 | + h = iLimit & (pCache->nHash-1); |
| 57563 | + iStop = pCache->iMaxKey & (pCache->nHash-1); |
| 57605 | 57564 | TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ |
| 57606 | 57565 | }else{ |
| 57607 | 57566 | /* This is the general case where many pages are being removed. |
| 57608 | 57567 | ** It is necessary to scan the entire hash table */ |
| 57609 | 57568 | h = pCache->nHash/2; |
| | @@ -57624,11 +57583,11 @@ |
| 57624 | 57583 | pp = &pPage->pNext; |
| 57625 | 57584 | TESTONLY( if( nPage>=0 ) nPage++; ) |
| 57626 | 57585 | } |
| 57627 | 57586 | } |
| 57628 | 57587 | if( h==iStop ) break; |
| 57629 | | - h = (h+1) % pCache->nHash; |
| 57588 | + h = (h+1) & (pCache->nHash-1); |
| 57630 | 57589 | } |
| 57631 | 57590 | assert( nPage<0 || pCache->nPage==(unsigned)nPage ); |
| 57632 | 57591 | } |
| 57633 | 57592 | |
| 57634 | 57593 | /******************************************************************************/ |
| | @@ -57836,10 +57795,11 @@ |
| 57836 | 57795 | return 0; |
| 57837 | 57796 | } |
| 57838 | 57797 | |
| 57839 | 57798 | if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); |
| 57840 | 57799 | assert( pCache->nHash>0 && pCache->apHash ); |
| 57800 | + assert( (pCache->nHash & (pCache->nHash-1))==0 ); |
| 57841 | 57801 | |
| 57842 | 57802 | /* Step 4. Try to recycle a page. */ |
| 57843 | 57803 | if( pCache->bPurgeable |
| 57844 | 57804 | && !pGroup->lru.pLruPrev->isAnchor |
| 57845 | 57805 | && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache)) |
| | @@ -57864,11 +57824,11 @@ |
| 57864 | 57824 | if( !pPage ){ |
| 57865 | 57825 | pPage = pcache1AllocPage(pCache, createFlag==1); |
| 57866 | 57826 | } |
| 57867 | 57827 | |
| 57868 | 57828 | if( pPage ){ |
| 57869 | | - unsigned int h = iKey % pCache->nHash; |
| 57829 | + unsigned int h = iKey & (pCache->nHash-1); |
| 57870 | 57830 | pCache->nPage++; |
| 57871 | 57831 | pPage->iKey = iKey; |
| 57872 | 57832 | pPage->pNext = pCache->apHash[h]; |
| 57873 | 57833 | pPage->pCache = pCache; |
| 57874 | 57834 | pPage->pLruNext = 0; |
| | @@ -58071,19 +58031,20 @@ |
| 58071 | 58031 | assert( iOld!=iNew ); /* The page number really is changing */ |
| 58072 | 58032 | |
| 58073 | 58033 | pcache1EnterMutex(pCache->pGroup); |
| 58074 | 58034 | |
| 58075 | 58035 | assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ |
| 58076 | | - hOld = iOld%pCache->nHash; |
| 58036 | + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); |
| 58037 | + hOld = iOld & (pCache->nHash-1); |
| 58077 | 58038 | pp = &pCache->apHash[hOld]; |
| 58078 | 58039 | while( (*pp)!=pPage ){ |
| 58079 | 58040 | pp = &(*pp)->pNext; |
| 58080 | 58041 | } |
| 58081 | 58042 | *pp = pPage->pNext; |
| 58082 | 58043 | |
| 58083 | 58044 | assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ |
| 58084 | | - hNew = iNew%pCache->nHash; |
| 58045 | + hNew = iNew & (pCache->nHash-1); |
| 58085 | 58046 | pPage->iKey = iNew; |
| 58086 | 58047 | pPage->pNext = pCache->apHash[hNew]; |
| 58087 | 58048 | pCache->apHash[hNew] = pPage; |
| 58088 | 58049 | if( iNew>pCache->iMaxKey ){ |
| 58089 | 58050 | pCache->iMaxKey = iNew; |
| | @@ -63895,11 +63856,19 @@ |
| 63895 | 63856 | |
| 63896 | 63857 | /* Open the pager file. |
| 63897 | 63858 | */ |
| 63898 | 63859 | if( zFilename && zFilename[0] ){ |
| 63899 | 63860 | int fout = 0; /* VFS flags returned by xOpen() */ |
| 63861 | + int bImmutable = sqlite3_uri_boolean(pPager->zFilename, "immutable", 0); |
| 63862 | + if( bImmutable ){ |
| 63863 | + vfsFlags |= SQLITE_OPEN_READONLY; |
| 63864 | + vfsFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 63865 | + } |
| 63900 | 63866 | rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); |
| 63867 | + if( bImmutable ){ |
| 63868 | + goto act_like_temp_file; |
| 63869 | + } |
| 63901 | 63870 | assert( !memDb ); |
| 63902 | 63871 | pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; |
| 63903 | 63872 | readOnly = (fout&SQLITE_OPEN_READONLY)!=0; |
| 63904 | 63873 | |
| 63905 | 63874 | /* If the file was successfully opened for read/write access, |
| | @@ -63935,14 +63904,13 @@ |
| 63935 | 63904 | } |
| 63936 | 63905 | } |
| 63937 | 63906 | #endif |
| 63938 | 63907 | } |
| 63939 | 63908 | pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); |
| 63940 | | - if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 |
| 63941 | | - || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ |
| 63942 | | - vfsFlags |= SQLITE_OPEN_READONLY; |
| 63943 | | - goto act_like_temp_file; |
| 63909 | + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 ){ |
| 63910 | + vfsFlags |= SQLITE_OPEN_READONLY; |
| 63911 | + goto act_like_temp_file; |
| 63944 | 63912 | } |
| 63945 | 63913 | } |
| 63946 | 63914 | }else{ |
| 63947 | 63915 | /* If a temporary file is requested, it is not opened immediately. |
| 63948 | 63916 | ** In this case we accept the default page size and delay actually |
| | @@ -63958,10 +63926,11 @@ |
| 63958 | 63926 | tempFile = 1; |
| 63959 | 63927 | pPager->eState = PAGER_READER; /* Pretend we already have a lock */ |
| 63960 | 63928 | pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ |
| 63961 | 63929 | pPager->noLock = 1; /* Do no locking */ |
| 63962 | 63930 | readOnly = (vfsFlags&SQLITE_OPEN_READONLY); |
| 63931 | + assert( readOnly==0 || readOnly==1 ); |
| 63963 | 63932 | } |
| 63964 | 63933 | |
| 63965 | 63934 | /* The following call to PagerSetPagesize() serves to set the value of |
| 63966 | 63935 | ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. |
| 63967 | 63936 | */ |
| | @@ -70452,15 +70421,19 @@ |
| 70452 | 70421 | ){ |
| 70453 | 70422 | int sz; |
| 70454 | 70423 | i64 iOffset; |
| 70455 | 70424 | sz = pWal->hdr.szPage; |
| 70456 | 70425 | sz = (sz&0xfe00) + ((sz&0x0001)<<16); |
| 70426 | + if( nOut>sz ){ |
| 70427 | + memset(pOut+sz, 0, nOut-sz); |
| 70428 | + nOut = sz; |
| 70429 | + } |
| 70457 | 70430 | testcase( sz<=32768 ); |
| 70458 | 70431 | testcase( sz>=65536 ); |
| 70459 | 70432 | iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; |
| 70460 | 70433 | /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 70461 | | - return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); |
| 70434 | + return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); |
| 70462 | 70435 | } |
| 70463 | 70436 | |
| 70464 | 70437 | /* |
| 70465 | 70438 | ** Return the size of the database in pages (or zero, if unknown). |
| 70466 | 70439 | */ |
| | @@ -72163,10 +72136,11 @@ |
| 72163 | 72136 | Pgno nCkPage; /* Pages in the database. 0 for partial check */ |
| 72164 | 72137 | int mxErr; /* Stop accumulating errors when this reaches zero */ |
| 72165 | 72138 | int nErr; /* Number of messages written to zErrMsg so far */ |
| 72166 | 72139 | int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ |
| 72167 | 72140 | u32 nStep; /* Number of steps into the integrity_check process */ |
| 72141 | + u8 nAbove; /* Current btree recursion depth */ |
| 72168 | 72142 | const char *zPfx; /* Error message prefix */ |
| 72169 | 72143 | Pgno v0; /* Value for first %u substitution in zPfx (root page) */ |
| 72170 | 72144 | Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ |
| 72171 | 72145 | int v2; /* Value for third %d substitution in zPfx */ |
| 72172 | 72146 | StrAccum errMsg; /* Accumulate the error message text here */ |
| | @@ -73774,11 +73748,11 @@ |
| 73774 | 73748 | assert( pPage->leaf==0 ); |
| 73775 | 73749 | assert( pPage->childPtrSize==4 ); |
| 73776 | 73750 | #ifndef SQLITE_DEBUG |
| 73777 | 73751 | UNUSED_PARAMETER(pPage); |
| 73778 | 73752 | #endif |
| 73779 | | - pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); |
| 73753 | + pInfo->nSize = 4 + sqlite3GetVarint(&pCell[4], (u64*)&pInfo->nKey); |
| 73780 | 73754 | pInfo->nPayload = 0; |
| 73781 | 73755 | pInfo->nLocal = 0; |
| 73782 | 73756 | pInfo->pPayload = 0; |
| 73783 | 73757 | return; |
| 73784 | 73758 | } |
| | @@ -73814,11 +73788,11 @@ |
| 73814 | 73788 | } |
| 73815 | 73789 | pIter++; |
| 73816 | 73790 | |
| 73817 | 73791 | /* The next block of code is equivalent to: |
| 73818 | 73792 | ** |
| 73819 | | - ** pIter += getVarint(pIter, (u64*)&pInfo->nKey); |
| 73793 | + ** pIter += sqlite3GetVarint(pIter, (u64*)&pInfo->nKey); |
| 73820 | 73794 | ** |
| 73821 | 73795 | ** The code is inlined and the loop is unrolled for performance. |
| 73822 | 73796 | ** This routine is a high-runner. |
| 73823 | 73797 | */ |
| 73824 | 73798 | iKey = *pIter; |
| | @@ -78425,11 +78399,11 @@ |
| 78425 | 78399 | if( pCell>=pPage->aDataEnd ){ |
| 78426 | 78400 | return SQLITE_CORRUPT_PAGE(pPage); |
| 78427 | 78401 | } |
| 78428 | 78402 | } |
| 78429 | 78403 | } |
| 78430 | | - getVarint(pCell, (u64*)&nCellKey); |
| 78404 | + nCellKey = sqlite3VarintValue(pCell); |
| 78431 | 78405 | if( nCellKey<intKey ){ |
| 78432 | 78406 | lwr = idx+1; |
| 78433 | 78407 | if( lwr>upr ){ c = -1; break; } |
| 78434 | 78408 | }else if( nCellKey>intKey ){ |
| 78435 | 78409 | upr = idx-1; |
| | @@ -79632,11 +79606,11 @@ |
| 79632 | 79606 | nPayload = pX->nData + pX->nZero; |
| 79633 | 79607 | pSrc = pX->pData; |
| 79634 | 79608 | nSrc = pX->nData; |
| 79635 | 79609 | assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ |
| 79636 | 79610 | nHeader += putVarint32(&pCell[nHeader], nPayload); |
| 79637 | | - nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); |
| 79611 | + nHeader += sqlite3PutVarint(&pCell[nHeader], *(u64*)&pX->nKey); |
| 79638 | 79612 | }else{ |
| 79639 | 79613 | assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); |
| 79640 | 79614 | nSrc = nPayload = (int)pX->nKey; |
| 79641 | 79615 | pSrc = pX->pKey; |
| 79642 | 79616 | nHeader += putVarint32(&pCell[nHeader], nPayload); |
| | @@ -81381,11 +81355,11 @@ |
| 81381 | 81355 | */ |
| 81382 | 81356 | CellInfo info; |
| 81383 | 81357 | j--; |
| 81384 | 81358 | pNew->xParseCell(pNew, b.apCell[j], &info); |
| 81385 | 81359 | pCell = pTemp; |
| 81386 | | - sz = 4 + putVarint(&pCell[4], info.nKey); |
| 81360 | + sz = 4 + sqlite3PutVarint(&pCell[4], info.nKey); |
| 81387 | 81361 | pTemp = 0; |
| 81388 | 81362 | }else{ |
| 81389 | 81363 | pCell -= 4; |
| 81390 | 81364 | /* Obscure case for non-leaf-data trees: If the cell at pCell was |
| 81391 | 81365 | ** previously stored on a leaf node, and its reported size was 4 |
| | @@ -82266,11 +82240,11 @@ |
| 82266 | 82240 | if( pSrc->info.nPayload<0x80 ){ |
| 82267 | 82241 | *(aOut++) = (u8)pSrc->info.nPayload; |
| 82268 | 82242 | }else{ |
| 82269 | 82243 | aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); |
| 82270 | 82244 | } |
| 82271 | | - if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); |
| 82245 | + if( pDest->pKeyInfo==0 ) aOut += sqlite3PutVarint(aOut, iKey); |
| 82272 | 82246 | nIn = pSrc->info.nLocal; |
| 82273 | 82247 | aIn = pSrc->info.pPayload; |
| 82274 | 82248 | if( aIn+nIn>pSrc->pPage->aDataEnd ){ |
| 82275 | 82249 | return SQLITE_CORRUPT_PAGE(pSrc->pPage); |
| 82276 | 82250 | } |
| | @@ -82736,15 +82710,24 @@ |
| 82736 | 82710 | } |
| 82737 | 82711 | |
| 82738 | 82712 | /* |
| 82739 | 82713 | ** Erase the given database page and all its children. Return |
| 82740 | 82714 | ** the page to the freelist. |
| 82715 | +** |
| 82716 | +** The freePageFlag parameter serves a double role: |
| 82717 | +** |
| 82718 | +** * Bit 0 (freePageFlag&1) means that the page should be freed |
| 82719 | +** after it is cleared. |
| 82720 | +** |
| 82721 | +** * Bits 1-31 (freePageFlag>>1) is the depth of recursion. Use this |
| 82722 | +** to prevent a corrupt database file from recursing too deeply and |
| 82723 | +** overflowing the CPU stack. |
| 82741 | 82724 | */ |
| 82742 | 82725 | static int clearDatabasePage( |
| 82743 | 82726 | BtShared *pBt, /* The BTree that contains the table */ |
| 82744 | 82727 | Pgno pgno, /* Page number to clear */ |
| 82745 | | - int freePageFlag, /* Deallocate page if true */ |
| 82728 | + int freePageFlag, /* bit 0: Deallocate page. Bits 1-31: depth */ |
| 82746 | 82729 | i64 *pnChange /* Add number of Cells freed to this counter */ |
| 82747 | 82730 | ){ |
| 82748 | 82731 | MemPage *pPage; |
| 82749 | 82732 | int rc; |
| 82750 | 82733 | unsigned char *pCell; |
| | @@ -82753,10 +82736,13 @@ |
| 82753 | 82736 | CellInfo info; |
| 82754 | 82737 | |
| 82755 | 82738 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 82756 | 82739 | if( pgno>btreePagecount(pBt) ){ |
| 82757 | 82740 | return SQLITE_CORRUPT_PGNO(pgno); |
| 82741 | + } |
| 82742 | + if( (freePageFlag>>1) > BTCURSOR_MAX_DEPTH ){ |
| 82743 | + return SQLITE_CORRUPT_PGNO(pgno); |
| 82758 | 82744 | } |
| 82759 | 82745 | rc = getAndInitPage(pBt, pgno, &pPage, 0); |
| 82760 | 82746 | if( rc ) return rc; |
| 82761 | 82747 | if( (pBt->openFlags & BTREE_SINGLE)==0 |
| 82762 | 82748 | && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) |
| | @@ -82766,26 +82752,28 @@ |
| 82766 | 82752 | } |
| 82767 | 82753 | hdr = pPage->hdrOffset; |
| 82768 | 82754 | for(i=0; i<pPage->nCell; i++){ |
| 82769 | 82755 | pCell = findCell(pPage, i); |
| 82770 | 82756 | if( !pPage->leaf ){ |
| 82771 | | - rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); |
| 82757 | + rc = clearDatabasePage(pBt, get4byte(pCell), |
| 82758 | + (freePageFlag+2)|1, pnChange); |
| 82772 | 82759 | if( rc ) goto cleardatabasepage_out; |
| 82773 | 82760 | } |
| 82774 | 82761 | BTREE_CLEAR_CELL(rc, pPage, pCell, info); |
| 82775 | 82762 | if( rc ) goto cleardatabasepage_out; |
| 82776 | 82763 | } |
| 82777 | 82764 | if( !pPage->leaf ){ |
| 82778 | | - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); |
| 82765 | + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), |
| 82766 | + (freePageFlag+2)|1, pnChange); |
| 82779 | 82767 | if( rc ) goto cleardatabasepage_out; |
| 82780 | 82768 | if( pPage->intKey ) pnChange = 0; |
| 82781 | 82769 | } |
| 82782 | 82770 | if( pnChange ){ |
| 82783 | 82771 | testcase( !pPage->intKey ); |
| 82784 | 82772 | *pnChange += pPage->nCell; |
| 82785 | 82773 | } |
| 82786 | | - if( freePageFlag ){ |
| 82774 | + if( (freePageFlag&1)!=0 ){ |
| 82787 | 82775 | freePage(pPage, &rc); |
| 82788 | 82776 | }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ |
| 82789 | 82777 | zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); |
| 82790 | 82778 | } |
| 82791 | 82779 | |
| | @@ -83416,22 +83404,27 @@ |
| 83416 | 83404 | u8 savedIsInit = 0; |
| 83417 | 83405 | |
| 83418 | 83406 | /* Check that the page exists |
| 83419 | 83407 | */ |
| 83420 | 83408 | checkProgress(pCheck); |
| 83421 | | - if( pCheck->mxErr==0 ) goto end_of_check; |
| 83409 | + if( pCheck->mxErr==0 ) return 0; |
| 83422 | 83410 | pBt = pCheck->pBt; |
| 83423 | 83411 | usableSize = pBt->usableSize; |
| 83424 | 83412 | if( iPage==0 ) return 0; |
| 83425 | 83413 | if( checkRef(pCheck, iPage) ) return 0; |
| 83426 | 83414 | pCheck->zPfx = "Tree %u page %u: "; |
| 83427 | 83415 | pCheck->v1 = iPage; |
| 83416 | + pCheck->nAbove++; |
| 83428 | 83417 | if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ |
| 83429 | 83418 | checkAppendMsg(pCheck, |
| 83430 | 83419 | "unable to get the page. error code=%d", rc); |
| 83431 | 83420 | if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; |
| 83432 | 83421 | goto end_of_check; |
| 83422 | + } |
| 83423 | + if( pCheck->nAbove > BTCURSOR_MAX_DEPTH ){ |
| 83424 | + checkAppendMsg(pCheck,"btree depth exceeds %d",BTCURSOR_MAX_DEPTH); |
| 83425 | + goto end_of_check; |
| 83433 | 83426 | } |
| 83434 | 83427 | |
| 83435 | 83428 | /* Clear MemPage.isInit to make sure the corruption detection code in |
| 83436 | 83429 | ** btreeInitPage() is executed. */ |
| 83437 | 83430 | savedIsInit = pPage->isInit; |
| | @@ -83648,10 +83641,11 @@ |
| 83648 | 83641 | if( !doCoverageCheck ) pPage->isInit = savedIsInit; |
| 83649 | 83642 | releasePage(pPage); |
| 83650 | 83643 | pCheck->zPfx = saved_zPfx; |
| 83651 | 83644 | pCheck->v1 = saved_v1; |
| 83652 | 83645 | pCheck->v2 = saved_v2; |
| 83646 | + pCheck->nAbove--; |
| 83653 | 83647 | return depth+1; |
| 83654 | 83648 | } |
| 83655 | 83649 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 83656 | 83650 | |
| 83657 | 83651 | #ifndef SQLITE_OMIT_INTEGRITY_CHECK |
| | @@ -83780,11 +83774,13 @@ |
| 83780 | 83774 | if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){ |
| 83781 | 83775 | checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); |
| 83782 | 83776 | } |
| 83783 | 83777 | #endif |
| 83784 | 83778 | sCheck.v0 = aRoot[i]; |
| 83779 | + assert( sCheck.nAbove==0 ); |
| 83785 | 83780 | checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); |
| 83781 | + assert( sCheck.nAbove==0 ); |
| 83786 | 83782 | } |
| 83787 | 83783 | sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); |
| 83788 | 83784 | } |
| 83789 | 83785 | pBt->db->flags = savedDbFlags; |
| 83790 | 83786 | |
| | @@ -87553,10 +87549,24 @@ |
| 87553 | 87549 | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 87554 | 87550 | ** Replicate in sqlite3VdbeAddOp3() */ |
| 87555 | 87551 | |
| 87556 | 87552 | return i; |
| 87557 | 87553 | } |
| 87554 | + |
| 87555 | +/* Generate an opcode that loads a 64-bit integer into register iDest |
| 87556 | +*/ |
| 87557 | +SQLITE_PRIVATE int sqlite3VdbeAddInt64(Vdbe *p, int iDest, i64 iVal){ |
| 87558 | + return sqlite3VdbeAddOp3(p, OP_Int64, LOWER32(iVal), iDest, UPPER32(iVal)); |
| 87559 | +} |
| 87560 | + |
| 87561 | +/* Generate an opcode that loads a 64-floating point value into register iDest. |
| 87562 | +*/ |
| 87563 | +SQLITE_PRIVATE int sqlite3VdbeAddDouble(Vdbe *p, int iDest, double rVal){ |
| 87564 | + i64 iVal; |
| 87565 | + memcpy(&iVal,&rVal,8); |
| 87566 | + return sqlite3VdbeAddOp3(p, OP_Real, LOWER32(iVal), iDest, UPPER32(iVal)); |
| 87567 | +} |
| 87558 | 87568 | |
| 87559 | 87569 | /* Generate code for an unconditional jump to instruction iDest |
| 87560 | 87570 | */ |
| 87561 | 87571 | SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ |
| 87562 | 87572 | return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); |
| | @@ -87657,28 +87667,10 @@ |
| 87657 | 87667 | sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); |
| 87658 | 87668 | sqlite3MayAbort(pParse); |
| 87659 | 87669 | return addr; |
| 87660 | 87670 | } |
| 87661 | 87671 | |
| 87662 | | -/* |
| 87663 | | -** Add an opcode that includes the p4 value with a P4_INT64 or |
| 87664 | | -** P4_REAL type. |
| 87665 | | -*/ |
| 87666 | | -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( |
| 87667 | | - Vdbe *p, /* Add the opcode to this VM */ |
| 87668 | | - int op, /* The new opcode */ |
| 87669 | | - int p1, /* The P1 operand */ |
| 87670 | | - int p2, /* The P2 operand */ |
| 87671 | | - int p3, /* The P3 operand */ |
| 87672 | | - const u8 *zP4, /* The P4 operand */ |
| 87673 | | - int p4type /* P4 operand type */ |
| 87674 | | -){ |
| 87675 | | - char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); |
| 87676 | | - if( p4copy ) memcpy(p4copy, zP4, 8); |
| 87677 | | - return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); |
| 87678 | | -} |
| 87679 | | - |
| 87680 | 87672 | #ifndef SQLITE_OMIT_EXPLAIN |
| 87681 | 87673 | /* |
| 87682 | 87674 | ** Return the address of the current EXPLAIN QUERY PLAN baseline. |
| 87683 | 87675 | ** 0 means "none". |
| 87684 | 87676 | */ |
| | @@ -88581,12 +88573,10 @@ |
| 88581 | 88573 | switch( p4type ){ |
| 88582 | 88574 | case P4_FUNCCTX: { |
| 88583 | 88575 | freeP4FuncCtx(db, (sqlite3_context*)p4); |
| 88584 | 88576 | break; |
| 88585 | 88577 | } |
| 88586 | | - case P4_REAL: |
| 88587 | | - case P4_INT64: |
| 88588 | 88578 | case P4_DYNAMIC: |
| 88589 | 88579 | case P4_INTARRAY: { |
| 88590 | 88580 | if( p4 ) sqlite3DbNNFreeNN(db, p4); |
| 88591 | 88581 | break; |
| 88592 | 88582 | } |
| | @@ -88936,10 +88926,13 @@ |
| 88936 | 88926 | ** |
| 88937 | 88927 | ** "PX" -> "r[X]" |
| 88938 | 88928 | ** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 |
| 88939 | 88929 | ** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 |
| 88940 | 88930 | ** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x |
| 88931 | +** "PINT13" -> int(P1|P3<<32) |
| 88932 | +** "PDBL13" -> real(P1|P3<<32) |
| 88933 | +** "PHEX23" -> hex(P2|P3<<32) |
| 88941 | 88934 | */ |
| 88942 | 88935 | SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( |
| 88943 | 88936 | sqlite3 *db, /* Optional - Oom error reporting only */ |
| 88944 | 88937 | const Op *pOp, /* The opcode to be commented */ |
| 88945 | 88938 | const char *zP4 /* Previously obtained value for P4 */ |
| | @@ -88971,10 +88964,24 @@ |
| 88971 | 88964 | if( pOp->zComment && pOp->zComment[0] ){ |
| 88972 | 88965 | sqlite3_str_appendall(&x, pOp->zComment); |
| 88973 | 88966 | seenCom = 1; |
| 88974 | 88967 | break; |
| 88975 | 88968 | } |
| 88969 | + }else if( strncmp(&zSynopsis[ii],"INT13",5)==0 ){ |
| 88970 | + sqlite3_str_appendf(&x,"%lld",INT32_TO_64(pOp->p1,pOp->p3)); |
| 88971 | + ii += 4; |
| 88972 | +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 88973 | + }else if( strncmp(&zSynopsis[ii],"HEX23",5)==0 ){ |
| 88974 | + sqlite3_str_appendf(&x,"0x%llx",INT32_TO_64(pOp->p2,pOp->p3)); |
| 88975 | + ii += 4; |
| 88976 | +#endif |
| 88977 | + }else if( strncmp(&zSynopsis[ii],"DBL13",5)==0 ){ |
| 88978 | + i64 iVal = INT32_TO_64(pOp->p1,pOp->p3); |
| 88979 | + double r; |
| 88980 | + memcpy(&r, &iVal, 8); |
| 88981 | + sqlite3_str_appendf(&x,"%.17g",r); |
| 88982 | + ii += 4; |
| 88976 | 88983 | }else{ |
| 88977 | 88984 | int v1 = translateP(c, pOp); |
| 88978 | 88985 | int v2; |
| 88979 | 88986 | if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ |
| 88980 | 88987 | ii += 3; |
| | @@ -89148,22 +89155,14 @@ |
| 89148 | 89155 | case P4_FUNCCTX: { |
| 89149 | 89156 | FuncDef *pDef = pOp->p4.pCtx->pFunc; |
| 89150 | 89157 | sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); |
| 89151 | 89158 | break; |
| 89152 | 89159 | } |
| 89153 | | - case P4_INT64: { |
| 89154 | | - sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); |
| 89155 | | - break; |
| 89156 | | - } |
| 89157 | 89160 | case P4_INT32: { |
| 89158 | 89161 | sqlite3_str_appendf(&x, "%d", pOp->p4.i); |
| 89159 | 89162 | break; |
| 89160 | 89163 | } |
| 89161 | | - case P4_REAL: { |
| 89162 | | - sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); |
| 89163 | | - break; |
| 89164 | | - } |
| 89165 | 89164 | case P4_MEM: { |
| 89166 | 89165 | Mem *pMem = pOp->p4.pMem; |
| 89167 | 89166 | if( pMem->flags & MEM_Str ){ |
| 89168 | 89167 | zP4 = pMem->z; |
| 89169 | 89168 | }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ |
| | @@ -97360,35 +97359,39 @@ |
| 97360 | 97359 | pOut = out2Prerelease(p, pOp); |
| 97361 | 97360 | pOut->u.i = pOp->p1; |
| 97362 | 97361 | break; |
| 97363 | 97362 | } |
| 97364 | 97363 | |
| 97365 | | -/* Opcode: Int64 * P2 * P4 * |
| 97366 | | -** Synopsis: r[P2]=P4 |
| 97364 | +/* Opcode: Int64 P1 P2 P3 * * |
| 97365 | +** Synopsis: r[P2]=PINT13 |
| 97367 | 97366 | ** |
| 97368 | | -** P4 is a pointer to a 64-bit integer value. |
| 97369 | | -** Write that value into register P2. |
| 97367 | +** Combine P1 and P3 into a signed 64-bit integer. P1 is the least |
| 97368 | +** significant 32 bits and P3 is the most significant. Store the |
| 97369 | +** result in register P2. |
| 97370 | 97370 | */ |
| 97371 | 97371 | case OP_Int64: { /* out2 */ |
| 97372 | 97372 | pOut = out2Prerelease(p, pOp); |
| 97373 | | - assert( pOp->p4.pI64!=0 ); |
| 97374 | | - pOut->u.i = *pOp->p4.pI64; |
| 97373 | + pOut->u.i = INT32_TO_64(pOp->p1,pOp->p3); |
| 97375 | 97374 | break; |
| 97376 | 97375 | } |
| 97377 | 97376 | |
| 97378 | 97377 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 97379 | | -/* Opcode: Real * P2 * P4 * |
| 97380 | | -** Synopsis: r[P2]=P4 |
| 97378 | +/* Opcode: Real P1 P2 P3 * * |
| 97379 | +** Synopsis: r[P2]=PDBL13 |
| 97381 | 97380 | ** |
| 97382 | | -** P4 is a pointer to a 64-bit floating point value. |
| 97383 | | -** Write that value into register P2. |
| 97381 | +** P1 and P3 are combined to 64 bits with P1 being the lower the P3 |
| 97382 | +** the upper. The result is interpreted as a 64-bit floating-point |
| 97383 | +** and stored in register P2. |
| 97384 | 97384 | */ |
| 97385 | 97385 | case OP_Real: { /* same as TK_FLOAT, out2 */ |
| 97386 | + u64 ii; |
| 97386 | 97387 | pOut = out2Prerelease(p, pOp); |
| 97387 | 97388 | pOut->flags = MEM_Real; |
| 97388 | | - assert( !sqlite3IsNaN(*pOp->p4.pReal) ); |
| 97389 | | - pOut->u.r = *pOp->p4.pReal; |
| 97389 | + ii = (u64)INT32_TO_64(pOp->p1,pOp->p3); |
| 97390 | + swapMixedEndianFloat(ii); |
| 97391 | + memcpy(&pOut->u.r, &ii, 8); |
| 97392 | + assert( !sqlite3IsNaN(pOut->u.r) ); |
| 97390 | 97393 | break; |
| 97391 | 97394 | } |
| 97392 | 97395 | #endif |
| 97393 | 97396 | |
| 97394 | 97397 | /* Opcode: String8 * P2 * P4 * |
| | @@ -99461,26 +99464,13 @@ |
| 99461 | 99464 | while( 1 /*exit-by-break*/ ){ |
| 99462 | 99465 | assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); |
| 99463 | 99466 | assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) ); |
| 99464 | 99467 | applyAffinity(pIn1, zAffinity[0], encoding); |
| 99465 | 99468 | if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ |
| 99466 | | - /* When applying REAL affinity, if the result is still an MEM_Int |
| 99467 | | - ** that will fit in 6 bytes, then change the type to MEM_IntReal |
| 99468 | | - ** so that we keep the high-resolution integer value but know that |
| 99469 | | - ** the type really wants to be REAL. */ |
| 99470 | | - testcase( pIn1->u.i==140737488355328LL ); |
| 99471 | | - testcase( pIn1->u.i==140737488355327LL ); |
| 99472 | | - testcase( pIn1->u.i==-140737488355328LL ); |
| 99473 | | - testcase( pIn1->u.i==-140737488355329LL ); |
| 99474 | | - if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){ |
| 99475 | | - pIn1->flags |= MEM_IntReal; |
| 99476 | | - pIn1->flags &= ~MEM_Int; |
| 99477 | | - }else{ |
| 99478 | | - pIn1->u.r = (double)pIn1->u.i; |
| 99479 | | - pIn1->flags |= MEM_Real; |
| 99480 | | - pIn1->flags &= ~(MEM_Int|MEM_Str); |
| 99481 | | - } |
| 99469 | + pIn1->u.r = (double)pIn1->u.i; |
| 99470 | + pIn1->flags |= MEM_Real; |
| 99471 | + pIn1->flags &= ~(MEM_Int|MEM_Str); |
| 99482 | 99472 | } |
| 99483 | 99473 | REGISTER_TRACE((int)(pIn1-aMem), pIn1); |
| 99484 | 99474 | zAffinity++; |
| 99485 | 99475 | if( zAffinity[0]==0 ) break; |
| 99486 | 99476 | pIn1++; |
| | @@ -100794,25 +100784,25 @@ |
| 100794 | 100784 | p->apCsr[pOp->p1] = 0; |
| 100795 | 100785 | break; |
| 100796 | 100786 | } |
| 100797 | 100787 | |
| 100798 | 100788 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 100799 | | -/* Opcode: ColumnsUsed P1 * * P4 * |
| 100789 | +/* Opcode: ColumnsUsed P1 P2 P3 * * |
| 100790 | +** Synopsis: Cursor P1 uses columns PHEX23 |
| 100800 | 100791 | ** |
| 100801 | 100792 | ** This opcode (which only exists if SQLite was compiled with |
| 100802 | 100793 | ** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the |
| 100803 | | -** table or index for cursor P1 are used. P4 is a 64-bit integer |
| 100804 | | -** (P4_INT64) in which the first 63 bits are one for each of the |
| 100805 | | -** first 63 columns of the table or index that are actually used |
| 100806 | | -** by the cursor. The high-order bit is set if any column after |
| 100807 | | -** the 64th is used. |
| 100794 | +** table or index for cursor P1 are used. P2 and P3 combine to give |
| 100795 | +** a 64-bit unsigned integer mask. P2 stores the lower 32 bits and |
| 100796 | +** P3 stores the upper 32 bits. If the high-order bit of P3 is set |
| 100797 | +** that means that and 64-th or some later column is used. |
| 100808 | 100798 | */ |
| 100809 | 100799 | case OP_ColumnsUsed: { |
| 100810 | 100800 | VdbeCursor *pC; |
| 100811 | 100801 | pC = p->apCsr[pOp->p1]; |
| 100812 | 100802 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 100813 | | - pC->maskUsed = *(u64*)pOp->p4.pI64; |
| 100803 | + pC->maskUsed = INT32_TO_64(pOp->p2,pOp->p3); |
| 100814 | 100804 | break; |
| 100815 | 100805 | } |
| 100816 | 100806 | #endif |
| 100817 | 100807 | |
| 100818 | 100808 | /* Opcode: SeekGE P1 P2 P3 P4 * |
| | @@ -113899,10 +113889,12 @@ |
| 113899 | 113889 | } |
| 113900 | 113890 | x = (ynVar)i; |
| 113901 | 113891 | if( x>pParse->nVar ){ |
| 113902 | 113892 | pParse->nVar = (int)x; |
| 113903 | 113893 | doAdd = 1; |
| 113894 | + }else if( x<SQLITE_VNBMC*64 ){ |
| 113895 | + doAdd = (pParse->aVnbmc[x>>6] & MASKBIT64(x&63))==0; |
| 113904 | 113896 | }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ |
| 113905 | 113897 | doAdd = 1; |
| 113906 | 113898 | } |
| 113907 | 113899 | }else{ |
| 113908 | 113900 | /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| | @@ -113915,10 +113907,13 @@ |
| 113915 | 113907 | doAdd = 1; |
| 113916 | 113908 | } |
| 113917 | 113909 | } |
| 113918 | 113910 | if( doAdd ){ |
| 113919 | 113911 | pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); |
| 113912 | + if( pParse->pVList!=0 && x<SQLITE_VNBMC*64 ){ |
| 113913 | + pParse->aVnbmc[x>>6] |= MASKBIT64(x&63); |
| 113914 | + } |
| 113920 | 113915 | } |
| 113921 | 113916 | } |
| 113922 | 113917 | pExpr->iColumn = x; |
| 113923 | 113918 | if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 113924 | 113919 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| | @@ -115067,10 +115062,11 @@ |
| 115067 | 115062 | ** |
| 115068 | 115063 | ** sqlite3ExprIsConstant() pWalker->eCode==1 |
| 115069 | 115064 | ** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 |
| 115070 | 115065 | ** sqlite3ExprIsTableConstant() pWalker->eCode==3 |
| 115071 | 115066 | ** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 |
| 115067 | +** sqlite3ExprListIsConstant() pWalker->eCode==1 or 6 |
| 115072 | 115068 | ** |
| 115073 | 115069 | ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression |
| 115074 | 115070 | ** is found to not be a constant. |
| 115075 | 115071 | ** |
| 115076 | 115072 | ** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT |
| | @@ -115139,10 +115135,17 @@ |
| 115139 | 115135 | testcase( pExpr->op==TK_IF_NULL_ROW ); |
| 115140 | 115136 | testcase( pExpr->op==TK_DOT ); |
| 115141 | 115137 | testcase( pExpr->op==TK_RAISE ); |
| 115142 | 115138 | pWalker->eCode = 0; |
| 115143 | 115139 | return WRC_Abort; |
| 115140 | + case TK_IS: |
| 115141 | + case TK_ISNOT: |
| 115142 | + if( pWalker->eCode==6 ){ |
| 115143 | + pWalker->eCode = 0; |
| 115144 | + return WRC_Abort; |
| 115145 | + } |
| 115146 | + return WRC_Continue; |
| 115144 | 115147 | case TK_VARIABLE: |
| 115145 | 115148 | if( pWalker->eCode==5 ){ |
| 115146 | 115149 | /* Silently convert bound parameters that appear inside of CREATE |
| 115147 | 115150 | ** statements into a NULL when parsing the CREATE statement text out |
| 115148 | 115151 | ** of the sqlite_schema table */ |
| | @@ -115188,10 +115191,26 @@ |
| 115188 | 115191 | ** function and on its parameters. |
| 115189 | 115192 | */ |
| 115190 | 115193 | SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ |
| 115191 | 115194 | return exprIsConst(pParse, p, 1); |
| 115192 | 115195 | } |
| 115196 | + |
| 115197 | +/* |
| 115198 | +** Return true if all expressions in pList are constant. If parameter bNoIs |
| 115199 | +** is true, do not consider expressions that contain "IS" operators to be |
| 115200 | +** constant. IS operators are not always considered constant as expressions |
| 115201 | +** like "x IS TRUE" need to be transformed to TK_TRUTH expression nodes, |
| 115202 | +** which happens at the same time as column name resolution. |
| 115203 | +*/ |
| 115204 | +SQLITE_PRIVATE int sqlite3ExprListIsConstant(Parse *pParse, ExprList *pList, int bNoIs){ |
| 115205 | + const int iInit = bNoIs ? 6 : 1; |
| 115206 | + int ii; |
| 115207 | + for(ii=0; ii<pList->nExpr; ii++){ |
| 115208 | + if( 0==exprIsConst(pParse, pList->a[ii].pExpr, iInit) ) return 0; |
| 115209 | + } |
| 115210 | + return 1; |
| 115211 | +} |
| 115193 | 115212 | |
| 115194 | 115213 | /* |
| 115195 | 115214 | ** Walk an expression tree. Return non-zero if |
| 115196 | 115215 | ** |
| 115197 | 115216 | ** (1) the expression is constant, and |
| | @@ -115922,13 +115941,13 @@ |
| 115922 | 115941 | assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); |
| 115923 | 115942 | eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; |
| 115924 | 115943 | |
| 115925 | 115944 | if( prRhsHasNull ){ |
| 115926 | 115945 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 115927 | | - i64 mask = (1<<nExpr)-1; |
| 115928 | | - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, |
| 115929 | | - iTab, 0, 0, (u8*)&mask, P4_INT64); |
| 115946 | + u64 mask = (1<<nExpr)-1; |
| 115947 | + sqlite3VdbeAddOp3(v, OP_ColumnsUsed, |
| 115948 | + iTab, LOWER32(mask), UPPER32(mask)); |
| 115930 | 115949 | #endif |
| 115931 | 115950 | *prRhsHasNull = ++pParse->nMem; |
| 115932 | 115951 | if( nExpr==1 ){ |
| 115933 | 115952 | sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); |
| 115934 | 115953 | } |
| | @@ -116878,11 +116897,11 @@ |
| 116878 | 116897 | if( ALWAYS(z!=0) ){ |
| 116879 | 116898 | double value; |
| 116880 | 116899 | sqlite3AtoF(z, &value); |
| 116881 | 116900 | assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ |
| 116882 | 116901 | if( negateFlag ) value = -value; |
| 116883 | | - sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); |
| 116902 | + sqlite3VdbeAddDouble(v, iMem, value); |
| 116884 | 116903 | } |
| 116885 | 116904 | } |
| 116886 | 116905 | #endif |
| 116887 | 116906 | |
| 116888 | 116907 | |
| | @@ -116919,11 +116938,11 @@ |
| 116919 | 116938 | codeReal(v, z, negFlag, iMem); |
| 116920 | 116939 | } |
| 116921 | 116940 | #endif |
| 116922 | 116941 | }else{ |
| 116923 | 116942 | if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } |
| 116924 | | - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); |
| 116943 | + sqlite3VdbeAddInt64(v, iMem, value); |
| 116925 | 116944 | } |
| 116926 | 116945 | } |
| 116927 | 116946 | } |
| 116928 | 116947 | |
| 116929 | 116948 | |
| | @@ -117310,11 +117329,11 @@ |
| 117310 | 117329 | ** A TRUE return does not guarantee that a subtype will be returned. |
| 117311 | 117330 | ** It only indicates that a subtype return is possible. False positives |
| 117312 | 117331 | ** are acceptable as they only disable an optimization. False negatives, |
| 117313 | 117332 | ** on the other hand, can lead to incorrect answers. |
| 117314 | 117333 | */ |
| 117315 | | -static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ |
| 117334 | +SQLITE_PRIVATE int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ |
| 117316 | 117335 | Walker w; |
| 117317 | 117336 | memset(&w, 0, sizeof(w)); |
| 117318 | 117337 | w.pParse = pParse; |
| 117319 | 117338 | w.xExprCallback = exprNodeCanReturnSubtype; |
| 117320 | 117339 | sqlite3WalkExpr(&w, pExpr); |
| | @@ -139361,29 +139380,17 @@ |
| 139361 | 139380 | sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); |
| 139362 | 139381 | } |
| 139363 | 139382 | } |
| 139364 | 139383 | } |
| 139365 | 139384 | |
| 139366 | | -/* |
| 139367 | | -** Return true if all expressions in the expression-list passed as the |
| 139368 | | -** only argument are constant. |
| 139369 | | -*/ |
| 139370 | | -static int exprListIsConstant(Parse *pParse, ExprList *pRow){ |
| 139371 | | - int ii; |
| 139372 | | - for(ii=0; ii<pRow->nExpr; ii++){ |
| 139373 | | - if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; |
| 139374 | | - } |
| 139375 | | - return 1; |
| 139376 | | -} |
| 139377 | | - |
| 139378 | 139385 | /* |
| 139379 | 139386 | ** Return true if all expressions in the expression-list passed as the |
| 139380 | 139387 | ** only argument are both constant and have no affinity. |
| 139381 | 139388 | */ |
| 139382 | 139389 | static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ |
| 139383 | 139390 | int ii; |
| 139384 | | - if( exprListIsConstant(pParse,pRow)==0 ) return 0; |
| 139391 | + if( sqlite3ExprListIsConstant(pParse, pRow, 0)==0 ) return 0; |
| 139385 | 139392 | for(ii=0; ii<pRow->nExpr; ii++){ |
| 139386 | 139393 | Expr *pExpr = pRow->a[ii].pExpr; |
| 139387 | 139394 | assert( pExpr->op!=TK_RAISE ); |
| 139388 | 139395 | assert( pExpr->affExpr==0 ); |
| 139389 | 139396 | if( 0!=sqlite3ExprAffinity(pExpr) ) return 0; |
| | @@ -139445,11 +139452,11 @@ |
| 139445 | 139452 | */ |
| 139446 | 139453 | SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ |
| 139447 | 139454 | |
| 139448 | 139455 | if( pParse->bHasWith /* condition (a) above */ |
| 139449 | 139456 | || pParse->db->init.busy /* condition (b) above */ |
| 139450 | | - || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ |
| 139457 | + || sqlite3ExprListIsConstant(pParse, pRow, 1)==0 /* condition (c) above */ |
| 139451 | 139458 | || (pLeft->pSrc->nSrc==0 && |
| 139452 | 139459 | exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ |
| 139453 | 139460 | || IN_SPECIAL_PARSE |
| 139454 | 139461 | ){ |
| 139455 | 139462 | /* The co-routine method cannot be used. Fall back to UNION ALL. */ |
| | @@ -144968,11 +144975,11 @@ |
| 144968 | 144975 | |
| 144969 | 144976 | /* |
| 144970 | 144977 | ** Generate code to return a single integer value. |
| 144971 | 144978 | */ |
| 144972 | 144979 | static void returnSingleInt(Vdbe *v, i64 value){ |
| 144973 | | - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64); |
| 144980 | + sqlite3VdbeAddInt64(v, 1, value); |
| 144974 | 144981 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 144975 | 144982 | } |
| 144976 | 144983 | |
| 144977 | 144984 | /* |
| 144978 | 144985 | ** Generate code to return a single text value. |
| | @@ -153756,16 +153763,25 @@ |
| 153756 | 153763 | ** Either EP_OuterON or EP_InnerON|EP_OuterON */ |
| 153757 | 153764 | Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ |
| 153758 | 153765 | }; |
| 153759 | 153766 | |
| 153760 | 153767 | /* |
| 153761 | | -** Add a new entry to the pConst object. Except, do not add duplicate |
| 153762 | | -** pColumn entries. Also, do not add if doing so would not be appropriate. |
| 153768 | +** Add a new entry to the pConst object, if appropriate. |
| 153763 | 153769 | ** |
| 153764 | | -** The caller guarantees the pColumn is a column and pValue is a constant. |
| 153765 | | -** This routine has to do some additional checks before completing the |
| 153766 | | -** insert. |
| 153770 | +** * Do not add if pValue is not constant. (This is enforced by |
| 153771 | +** the caller) |
| 153772 | +** |
| 153773 | +** * Do not add duplicate pColumn entries |
| 153774 | +** |
| 153775 | +** * Do not add if pValue has an affinity |
| 153776 | +** |
| 153777 | +** * Do not add if the comparison uses a collating sequence other |
| 153778 | +** than binary. |
| 153779 | +** |
| 153780 | +** * Do not add if pValue is a function that might return a subtype |
| 153781 | +** |
| 153782 | +** The caller guarantees the pColumn is a column. |
| 153767 | 153783 | */ |
| 153768 | 153784 | static void constInsert( |
| 153769 | 153785 | WhereConst *pConst, /* The WhereConst into which we are inserting */ |
| 153770 | 153786 | Expr *pColumn, /* The COLUMN part of the constraint */ |
| 153771 | 153787 | Expr *pValue, /* The VALUE part of the constraint */ |
| | @@ -153772,16 +153788,16 @@ |
| 153772 | 153788 | Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */ |
| 153773 | 153789 | ){ |
| 153774 | 153790 | int i; |
| 153775 | 153791 | assert( pColumn->op==TK_COLUMN ); |
| 153776 | 153792 | assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); |
| 153777 | | - |
| 153778 | 153793 | if( ExprHasProperty(pColumn, EP_FixedCol) ) return; |
| 153779 | 153794 | if( sqlite3ExprAffinity(pValue)!=0 ) return; |
| 153780 | 153795 | if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ |
| 153781 | 153796 | return; |
| 153782 | 153797 | } |
| 153798 | + if( sqlite3ExprCanReturnSubtype(pConst->pParse, pValue) ) return; |
| 153783 | 153799 | |
| 153784 | 153800 | /* 2018-10-25 ticket [cf5ed20f] |
| 153785 | 153801 | ** Make sure the same pColumn is not inserted more than once */ |
| 153786 | 153802 | for(i=0; i<pConst->nConst; i++){ |
| 153787 | 153803 | const Expr *pE2 = pConst->apExpr[i*2]; |
| | @@ -158538,20 +158554,25 @@ |
| 158538 | 158554 | char *zName; /* Name of trigger */ |
| 158539 | 158555 | sqlite3 *db = pParse->db; /* The database */ |
| 158540 | 158556 | DbFixer sFix; /* Fixer object */ |
| 158541 | 158557 | int iDb; /* Database containing the trigger */ |
| 158542 | 158558 | Token nameToken; /* Trigger name for error reporting */ |
| 158559 | + i64 n; /* Number of steps */ |
| 158543 | 158560 | |
| 158544 | 158561 | pParse->pNewTrigger = 0; |
| 158545 | 158562 | if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; |
| 158546 | 158563 | zName = pTrig->zName; |
| 158547 | 158564 | iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); |
| 158548 | 158565 | assert( iDb>=00 && iDb<db->nDb ); |
| 158549 | 158566 | pTrig->step_list = pStepList; |
| 158550 | | - while( pStepList ){ |
| 158567 | + for(n=0; pStepList; n++){ |
| 158551 | 158568 | pStepList->pTrig = pTrig; |
| 158552 | 158569 | pStepList = pStepList->pNext; |
| 158570 | + } |
| 158571 | + if( n>pParse->db->aLimit[SQLITE_LIMIT_TRIGGER_STEPS] ){ |
| 158572 | + sqlite3ErrorMsg(pParse, "trigger \"%w\" contains too many steps", zName); |
| 158573 | + goto triggerfinish_cleanup; |
| 158553 | 158574 | } |
| 158554 | 158575 | sqlite3TokenInit(&nameToken, pTrig->zName); |
| 158555 | 158576 | sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); |
| 158556 | 158577 | if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) |
| 158557 | 158578 | || sqlite3FixExpr(&sFix, pTrig->pWhen) |
| | @@ -164681,10 +164702,21 @@ |
| 164681 | 164702 | if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ |
| 164682 | 164703 | eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); |
| 164683 | 164704 | }else{ |
| 164684 | 164705 | sqlite3 *db = pParse->db; |
| 164685 | 164706 | Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); |
| 164707 | + if( nEq>1 ){ |
| 164708 | + /* If this IN(SELECT ...) expression drives more than one column of |
| 164709 | + ** the index, disable the seek-scan optimization. The reasons for this |
| 164710 | + ** are that (a) it is only possible to make this happen by populating |
| 164711 | + ** the sqlite_stat1 table with inconsistent information, and (b) it |
| 164712 | + ** would require sqlite3FindInIndex() to find an index that is not |
| 164713 | + ** only unique for the columns in question, but also delivers them |
| 164714 | + ** in sorted order (requires checking asc/desc, and rejecting cases |
| 164715 | + ** where the indexed columns are not in the right order). */ |
| 164716 | + pLoop->wsFlags &= ~WHERE_IN_SEEKSCAN; |
| 164717 | + } |
| 164686 | 164718 | if( !db->mallocFailed ){ |
| 164687 | 164719 | aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); |
| 164688 | 164720 | eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); |
| 164689 | 164721 | } |
| 164690 | 164722 | sqlite3ExprDelete(db, pXMod); |
| | @@ -166895,21 +166927,29 @@ |
| 166895 | 166927 | pFrom = &uSrc.sSrc; |
| 166896 | 166928 | pFrom->nSrc = 1; |
| 166897 | 166929 | pFrom->nAlloc = 1; |
| 166898 | 166930 | memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); |
| 166899 | 166931 | pFrom->a[0].fg.jointype = 0; |
| 166900 | | - assert( pParse->withinRJSubrtn < 100 ); |
| 166932 | + if( pParse->withinRJSubrtn >= 100 ){ |
| 166933 | + /* This limit --------------^^^ |
| 166934 | + ** is based on an historical assert(). It is not compile-time or |
| 166935 | + ** run-time configurable. It could perhaps be raised as high as 254, |
| 166936 | + ** but only an attack robot would ever do even 100 RIGHT JOINS within |
| 166937 | + ** a single query, so we'll just leave it as it is. */ |
| 166938 | + sqlite3ErrorMsg(pParse, "too many RIGHT JOINs"); |
| 166939 | + return; |
| 166940 | + } |
| 166901 | 166941 | pParse->withinRJSubrtn++; |
| 166902 | 166942 | pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, |
| 166903 | 166943 | WHERE_RIGHT_JOIN, 0); |
| 166904 | 166944 | if( pSubWInfo ){ |
| 166905 | | - int iCur = pLevel->iTabCur; |
| 166906 | | - int r = ++pParse->nMem; |
| 166907 | | - int nPk; |
| 166908 | | - int jmp = 0; |
| 166945 | + int iCur = pLevel->iTabCur; /* Table on RHS of RIGHT JOIN &*/ |
| 166946 | + int r = ++pParse->nMem; /* Register range to hold primary key */ |
| 166947 | + int nPk; /* Number of values in the primary key */ |
| 166948 | + int r2; /* Register holding record for primary key */ |
| 166909 | 166949 | int addrCont = sqlite3WhereContinueLabel(pSubWInfo); |
| 166910 | | - Table *pTab = pTabItem->pSTab; |
| 166950 | + Table *pTab = pTabItem->pSTab; /* Table on RHS of RIGHT JOIN */ |
| 166911 | 166951 | if( HasRowid(pTab) ){ |
| 166912 | 166952 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); |
| 166913 | 166953 | nPk = 1; |
| 166914 | 166954 | }else{ |
| 166915 | 166955 | int iPk; |
| | @@ -166919,17 +166959,35 @@ |
| 166919 | 166959 | for(iPk=0; iPk<nPk; iPk++){ |
| 166920 | 166960 | int iCol = pPk->aiColumn[iPk]; |
| 166921 | 166961 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); |
| 166922 | 166962 | } |
| 166923 | 166963 | } |
| 166964 | + |
| 166965 | + /* Generate code that checks to see if the current row of the RHS table |
| 166966 | + ** has appeared in any prior output row. */ |
| 166924 | 166967 | if( pRJ->regBloom ){ |
| 166925 | | - jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); |
| 166968 | + sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, |
| 166969 | + sqlite3VdbeCurrentAddr(v)+2, r, nPk); |
| 166926 | 166970 | VdbeCoverage(v); |
| 166927 | 166971 | } |
| 166928 | 166972 | sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); |
| 166929 | 166973 | VdbeCoverage(v); |
| 166930 | | - if( jmp ) sqlite3VdbeJumpHere(v, jmp); |
| 166974 | + r2 = sqlite3GetTempReg(pParse); |
| 166975 | + |
| 166976 | + /* Generate code that inserts the PK of the RHS table into the |
| 166977 | + ** pRH->iMatch index to indicate that the current row has appeared |
| 166978 | + ** in the output set. */ |
| 166979 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, r2); |
| 166980 | + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r2, r, nPk); |
| 166981 | + sqlite3ReleaseTempReg(pParse, r2); |
| 166982 | + if( pRJ->regBloom ){ |
| 166983 | + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r, nPk); |
| 166984 | + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 166985 | + } |
| 166986 | + |
| 166987 | + /* Invoke the subroutine that actually puts the current RHS table row |
| 166988 | + ** into the output set, with NULLs for the LHS. */ |
| 166931 | 166989 | sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); |
| 166932 | 166990 | sqlite3WhereEnd(pSubWInfo); |
| 166933 | 166991 | } |
| 166934 | 166992 | sqlite3ExprDelete(pParse->db, pSubWhere); |
| 166935 | 166993 | ExplainQueryPlanPop(pParse); |
| | @@ -176241,12 +176299,12 @@ |
| 176241 | 176299 | #endif |
| 176242 | 176300 | { |
| 176243 | 176301 | sqlite3VdbeChangeP5(v, bFordelete); |
| 176244 | 176302 | } |
| 176245 | 176303 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 176246 | | - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, |
| 176247 | | - (const u8*)&pTabItem->colUsed, P4_INT64); |
| 176304 | + sqlite3VdbeAddOp3(v, OP_ColumnsUsed, pTabItem->iCursor, |
| 176305 | + LOWER32(pTabItem->colUsed), UPPER32(pTabItem->colUsed)); |
| 176248 | 176306 | #endif |
| 176249 | 176307 | if( ii>=2 |
| 176250 | 176308 | && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 |
| 176251 | 176309 | && pLevel->addrHalt==pWInfo->a[0].addrHalt |
| 176252 | 176310 | ){ |
| | @@ -176319,12 +176377,12 @@ |
| 176319 | 176377 | if( jj<0 ) continue; |
| 176320 | 176378 | if( jj>63 ) jj = 63; |
| 176321 | 176379 | if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; |
| 176322 | 176380 | colUsed |= ((u64)1)<<(ii<63 ? ii : 63); |
| 176323 | 176381 | } |
| 176324 | | - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, |
| 176325 | | - (u8*)&colUsed, P4_INT64); |
| 176382 | + sqlite3VdbeAddOp3(v, OP_ColumnsUsed, iIndexCur, |
| 176383 | + LOWER32(colUsed),UPPER32(colUsed)); |
| 176326 | 176384 | } |
| 176327 | 176385 | #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ |
| 176328 | 176386 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 176329 | 176387 | if( HasRowid(pTab) ){ |
| 176330 | 176388 | sqlite3VdbeAddOp3(v, OP_CursorHint, iIndexCur, 0, pTabItem->iCursor); |
| | @@ -190540,10 +190598,11 @@ |
| 190540 | 190598 | SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ |
| 190541 | 190599 | SQLITE_MAX_TRIGGER_DEPTH, |
| 190542 | 190600 | SQLITE_MAX_WORKER_THREADS, |
| 190543 | 190601 | SQLITE_MAX_PARSER_DEPTH, |
| 190544 | 190602 | SQLITE_MAX_SCHEMA, |
| 190603 | + SQLITE_MAX_TRIGGER_STEPS, |
| 190545 | 190604 | }; |
| 190546 | 190605 | |
| 190547 | 190606 | /* |
| 190548 | 190607 | ** Make sure the hard limits are set to reasonable values |
| 190549 | 190608 | */ |
| | @@ -190580,10 +190639,13 @@ |
| 190580 | 190639 | #if SQLITE_MAX_TRIGGER_DEPTH<1 |
| 190581 | 190640 | # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 |
| 190582 | 190641 | #endif |
| 190583 | 190642 | #if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 |
| 190584 | 190643 | # error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 |
| 190644 | +#endif |
| 190645 | +#if SQLITE_MAX_TRIGGER_STEPS<0 || SQLITE_MAX_TRIGGER_STEPS>65535 |
| 190646 | +# error SQLITE_MAX_TRIGGER_STEPS must be between 0 and 65535 |
| 190585 | 190647 | #endif |
| 190586 | 190648 | |
| 190587 | 190649 | |
| 190588 | 190650 | /* |
| 190589 | 190651 | ** Change the value of a limit. Report the old value. |
| | @@ -190623,11 +190685,12 @@ |
| 190623 | 190685 | SQLITE_MAX_LIKE_PATTERN_LENGTH ); |
| 190624 | 190686 | assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); |
| 190625 | 190687 | assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); |
| 190626 | 190688 | assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); |
| 190627 | 190689 | assert( aHardLimit[SQLITE_LIMIT_SCHEMA]==SQLITE_MAX_SCHEMA ); |
| 190628 | | - assert( SQLITE_LIMIT_SCHEMA==(SQLITE_N_LIMIT-1) ); |
| 190690 | + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_STEPS]==SQLITE_MAX_TRIGGER_STEPS ); |
| 190691 | + assert( SQLITE_LIMIT_TRIGGER_STEPS==(SQLITE_N_LIMIT-1) ); |
| 190629 | 190692 | |
| 190630 | 190693 | |
| 190631 | 190694 | if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ |
| 190632 | 190695 | return -1; |
| 190633 | 190696 | } |
| | @@ -200499,10 +200562,18 @@ |
| 200499 | 200562 | } |
| 200500 | 200563 | |
| 200501 | 200564 | #define FTS4AUX_EQ_CONSTRAINT 1 |
| 200502 | 200565 | #define FTS4AUX_GE_CONSTRAINT 2 |
| 200503 | 200566 | #define FTS4AUX_LE_CONSTRAINT 4 |
| 200567 | + |
| 200568 | +/* |
| 200569 | +** Return true if constraint iCons of pInfo uses the "binary" collation |
| 200570 | +** sequence. Or false it it uses anything else. |
| 200571 | +*/ |
| 200572 | +static int fts3auxIsBinary(sqlite3_index_info *pInfo, int iCons){ |
| 200573 | + return 0==sqlite3_stricmp("binary", sqlite3_vtab_collation(pInfo, iCons)); |
| 200574 | +} |
| 200504 | 200575 | |
| 200505 | 200576 | /* |
| 200506 | 200577 | ** xBestIndex - Analyze a WHERE and ORDER BY clause. |
| 200507 | 200578 | */ |
| 200508 | 200579 | static int fts3auxBestIndexMethod( |
| | @@ -200527,11 +200598,11 @@ |
| 200527 | 200598 | } |
| 200528 | 200599 | |
| 200529 | 200600 | /* Search for equality and range constraints on the "term" column. |
| 200530 | 200601 | ** And equality constraints on the hidden "languageid" column. */ |
| 200531 | 200602 | for(i=0; i<pInfo->nConstraint; i++){ |
| 200532 | | - if( pInfo->aConstraint[i].usable ){ |
| 200603 | + if( pInfo->aConstraint[i].usable && fts3auxIsBinary(pInfo, i) ){ |
| 200533 | 200604 | int op = pInfo->aConstraint[i].op; |
| 200534 | 200605 | int iCol = pInfo->aConstraint[i].iColumn; |
| 200535 | 200606 | |
| 200536 | 200607 | if( iCol==0 ){ |
| 200537 | 200608 | if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; |
| | @@ -200698,11 +200769,11 @@ |
| 200698 | 200769 | break; |
| 200699 | 200770 | |
| 200700 | 200771 | /* State 3. The integer just read is a column number. */ |
| 200701 | 200772 | default: assert( eState==3 ); |
| 200702 | 200773 | iCol = (int)v; |
| 200703 | | - if( iCol<1 || iCol>(pFts3->nColumn+1) ){ |
| 200774 | + if( iCol<1 || iCol>32767 ){ |
| 200704 | 200775 | rc = SQLITE_CORRUPT_VTAB; |
| 200705 | 200776 | break; |
| 200706 | 200777 | } |
| 200707 | 200778 | if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; |
| 200708 | 200779 | pCsr->aStat[iCol+1].nDoc++; |
| | @@ -200773,21 +200844,21 @@ |
| 200773 | 200844 | memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); |
| 200774 | 200845 | |
| 200775 | 200846 | pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; |
| 200776 | 200847 | if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; |
| 200777 | 200848 | |
| 200778 | | - if( iEq>=0 || iGe>=0 ){ |
| 200849 | + if( (iEq>=0 || iGe>=0) && sqlite3_value_type(apVal[0])==SQLITE_TEXT ){ |
| 200779 | 200850 | const unsigned char *zStr = sqlite3_value_text(apVal[0]); |
| 200780 | 200851 | assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); |
| 200781 | 200852 | if( zStr ){ |
| 200782 | 200853 | pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); |
| 200783 | 200854 | if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; |
| 200784 | 200855 | pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm); |
| 200785 | 200856 | } |
| 200786 | 200857 | } |
| 200787 | 200858 | |
| 200788 | | - if( iLe>=0 ){ |
| 200859 | + if( iLe>=0 && sqlite3_value_type(apVal[0])==SQLITE_TEXT ){ |
| 200789 | 200860 | pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); |
| 200790 | 200861 | if( pCsr->zStop==0 ) return SQLITE_NOMEM; |
| 200791 | 200862 | pCsr->nStop = (int)strlen(pCsr->zStop); |
| 200792 | 200863 | } |
| 200793 | 200864 | |
| | @@ -210899,10 +210970,11 @@ |
| 210899 | 210970 | int nList; /* Number of phrases in expression */ |
| 210900 | 210971 | SnippetIter sIter; /* Iterates through snippet candidates */ |
| 210901 | 210972 | sqlite3_int64 nByte; /* Number of bytes of space to allocate */ |
| 210902 | 210973 | int iBestScore = -1; /* Best snippet score found so far */ |
| 210903 | 210974 | int i; /* Loop counter */ |
| 210975 | + Fts3Expr *pExpr = pCsr->pExpr; |
| 210904 | 210976 | |
| 210905 | 210977 | memset(&sIter, 0, sizeof(sIter)); |
| 210906 | 210978 | |
| 210907 | 210979 | /* Iterate through the phrases in the expression to count them. The same |
| 210908 | 210980 | ** callback makes sure the doclists are loaded for each phrase. |
| | @@ -210927,13 +210999,16 @@ |
| 210927 | 210999 | sIter.pCsr = pCsr; |
| 210928 | 211000 | sIter.iCol = iCol; |
| 210929 | 211001 | sIter.nSnippet = nSnippet; |
| 210930 | 211002 | sIter.nPhrase = nList; |
| 210931 | 211003 | sIter.iCurrent = -1; |
| 210932 | | - rc = sqlite3Fts3ExprIterate( |
| 210933 | | - pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter |
| 210934 | | - ); |
| 211004 | + rc = sqlite3Fts3ExprIterate(pExpr, fts3SnippetFindPositions, (void*)&sIter); |
| 211005 | + if( rc==SQLITE_OK ){ |
| 211006 | + /* Iterate through the expression twice, in case pointers garnered during |
| 211007 | + ** the first iteration are invalidated by a call to fts5EvalRestart(). */ |
| 211008 | + rc = sqlite3Fts3ExprIterate(pExpr, fts3SnippetFindPositions, (void*)&sIter); |
| 211009 | + } |
| 210935 | 211010 | if( rc==SQLITE_OK ){ |
| 210936 | 211011 | |
| 210937 | 211012 | /* Set the *pmSeen output variable. */ |
| 210938 | 211013 | for(i=0; i<nList; i++){ |
| 210939 | 211014 | if( sIter.aPhrase[i].pHead ){ |
| | @@ -215052,16 +215127,129 @@ |
| 215052 | 215127 | assert( !px.bReadOnly ); |
| 215053 | 215128 | sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); |
| 215054 | 215129 | } |
| 215055 | 215130 | } |
| 215056 | 215131 | |
| 215057 | | -/* The byte at index i is a node type-code. This routine |
| 215132 | +/* |
| 215133 | +** This a helper routine for jsonbPayloadSize() and |
| 215134 | +** jsonbPayloadSizeSemiInline(). This routine is called using tail |
| 215135 | +** recursion to handle the (relatively uncommon) cases where the |
| 215136 | +** the payload size is a 2, 4, or 8 byte integer. |
| 215137 | +*/ |
| 215138 | +static u32 jsonbPayloadSizeWide( |
| 215139 | + const JsonParse *pParse, /* JSON parsing context */ |
| 215140 | + u32 i, /* Index of the node type-code */ |
| 215141 | + u32 *pSz, /* Write payload size here */ |
| 215142 | + u8 x /* pParse->aBlob[i]>>4 */ |
| 215143 | +){ |
| 215144 | + u32 sz; |
| 215145 | + u32 n; |
| 215146 | + assert( i<pParse->nBlob ); |
| 215147 | + assert( x==(pParse->aBlob[i]>>4) ); |
| 215148 | + assert( x>=13 ); |
| 215149 | + if( x==13 ){ |
| 215150 | + if( i+2>=pParse->nBlob ){ |
| 215151 | + *pSz = 0; |
| 215152 | + return 0; |
| 215153 | + } |
| 215154 | + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; |
| 215155 | + n = 3; |
| 215156 | + }else if( x==14 ){ |
| 215157 | + if( i+4>=pParse->nBlob ){ |
| 215158 | + *pSz = 0; |
| 215159 | + return 0; |
| 215160 | + } |
| 215161 | + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + |
| 215162 | + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; |
| 215163 | + n = 5; |
| 215164 | + }else{ |
| 215165 | + if( i+8>=pParse->nBlob |
| 215166 | + || pParse->aBlob[i+1]!=0 |
| 215167 | + || pParse->aBlob[i+2]!=0 |
| 215168 | + || pParse->aBlob[i+3]!=0 |
| 215169 | + || pParse->aBlob[i+4]!=0 |
| 215170 | + ){ |
| 215171 | + *pSz = 0; |
| 215172 | + return 0; |
| 215173 | + } |
| 215174 | + sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + |
| 215175 | + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; |
| 215176 | + n = 9; |
| 215177 | + } |
| 215178 | + testcase( (i64)i+sz+n > pParse->nBlob ); |
| 215179 | + testcase( (i64)i+sz+n > pParse->nBlob-pParse->delta |
| 215180 | + && (i64)i+sz+n > pParse->nBlob ); |
| 215181 | + testcase( pParse->delta>0 ); |
| 215182 | + testcase( pParse->delta<0 ); |
| 215183 | + /* Quirks with -Os and gcov cause the NO_TEST line below to show up as |
| 215184 | + ** false-positive coverage miss. The testcases() macros above are |
| 215185 | + ** sufficient to prove that the branch is in fact covered */ |
| 215186 | + if( (i64)i+sz+n > pParse->nBlob |
| 215187 | + && (i64)i+sz+n > pParse->nBlob-pParse->delta /*NO_TEST*/ |
| 215188 | + ){ |
| 215189 | + *pSz = 0; |
| 215190 | + return 0; |
| 215191 | + } |
| 215192 | + *pSz = sz; |
| 215193 | + return n; |
| 215194 | +} |
| 215195 | + |
| 215196 | +/* |
| 215197 | +** This is the main routine for determining the size of a node in JSONB. |
| 215198 | +** The jsonbPayloadSizeWide() above is a helper. The two routines |
| 215199 | +** jsonbPayloadSizeInline() and jsonbPayloadSizeSemiInline() below are |
| 215200 | +** optional optimizations. It is important to keep all these routines in |
| 215201 | +** sync. Agents reading this code: Help us humans to remember that! |
| 215202 | +** |
| 215203 | +** The byte at index i is a node type-code. This routine |
| 215058 | 215204 | ** determines the payload size for that node and writes that |
| 215059 | 215205 | ** payload size in to *pSz. It returns the offset from i to the |
| 215060 | 215206 | ** beginning of the payload. Return 0 on error. |
| 215061 | 215207 | */ |
| 215062 | | -static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ |
| 215208 | +static u32 jsonbPayloadSize( |
| 215209 | + const JsonParse *pParse, /* JSON parsing context */ |
| 215210 | + u32 i, /* Index of the node type-code */ |
| 215211 | + u32 *pSz /* Write payload size here */ |
| 215212 | +){ |
| 215213 | + u8 x; |
| 215214 | + u32 sz; |
| 215215 | + u32 n; |
| 215216 | + if( i>=pParse->nBlob ){ |
| 215217 | + *pSz = 0; |
| 215218 | + return 0; |
| 215219 | + }else if( (x = pParse->aBlob[i]>>4)<=11 ){ |
| 215220 | + sz = x; |
| 215221 | + n = 1; |
| 215222 | + }else if( x==12 ){ |
| 215223 | + if( i+1>=pParse->nBlob ){ |
| 215224 | + *pSz = 0; |
| 215225 | + return 0; |
| 215226 | + } |
| 215227 | + sz = pParse->aBlob[i+1]; |
| 215228 | + n = 2; |
| 215229 | + }else{ |
| 215230 | + return jsonbPayloadSizeWide(pParse, i, pSz, x); |
| 215231 | + } |
| 215232 | + if( (i64)i+sz+n > pParse->nBlob |
| 215233 | + && (i64)i+sz+n > pParse->nBlob-pParse->delta |
| 215234 | + ){ |
| 215235 | + *pSz = 0; |
| 215236 | + return 0; |
| 215237 | + } |
| 215238 | + *pSz = sz; |
| 215239 | + return n; |
| 215240 | +} |
| 215241 | + |
| 215242 | +#if SQLITE_USES_INLINE |
| 215243 | +/* A separate inline version of jsonbPayloadSize(), used in one particulary |
| 215244 | +** performance-critical place. |
| 215245 | +*/ |
| 215246 | +static SQLITE_INLINE u32 jsonbPayloadSizeInline( |
| 215247 | + const JsonParse *pParse, /* JSON parsing context */ |
| 215248 | + u32 i, /* Index of the node type-code */ |
| 215249 | + u32 *pSz /* Write payload size here */ |
| 215250 | +){ |
| 215063 | 215251 | u8 x; |
| 215064 | 215252 | u32 sz; |
| 215065 | 215253 | u32 n; |
| 215066 | 215254 | if( i>=pParse->nBlob ){ |
| 215067 | 215255 | *pSz = 0; |
| | @@ -215112,11 +215300,65 @@ |
| 215112 | 215300 | return 0; |
| 215113 | 215301 | } |
| 215114 | 215302 | *pSz = sz; |
| 215115 | 215303 | return n; |
| 215116 | 215304 | } |
| 215305 | +#else /* if !SQLITE_USES_INLINE */ |
| 215306 | + /* On compilers that do not support in-lining, just call the original |
| 215307 | + ** jsonbPayloadSize(). It's slower, but it gets the right answer. */ |
| 215308 | +# define jsonbPayloadSizeInline(a,b,c) jsonbPayloadSize(a,b,c) |
| 215309 | +#endif |
| 215117 | 215310 | |
| 215311 | + |
| 215312 | +#if SQLITE_USES_INLINE |
| 215313 | +/* A separate inline version of jsonbPayloadSize() that implements the more |
| 215314 | +** common paths inline but then calls out to a subroutine for the uncommon |
| 215315 | +** paths. |
| 215316 | +** |
| 215317 | +** * It is guaranteed that the i parameter is a valid index for |
| 215318 | +** pParse->aBlob[]. There is no possibility of running of the end |
| 215319 | +** of the allocation. |
| 215320 | +** |
| 215321 | +** * Large sizes (greater than 255) are uncommon and are handled |
| 215322 | +** by a subroutine call to the jsonbPayloadSizeWide(). |
| 215323 | +*/ |
| 215324 | +static SQLITE_INLINE u32 jsonbPayloadSizeSemiInline( |
| 215325 | + const JsonParse *pParse, /* JSON parsing context */ |
| 215326 | + u32 i, /* Index of the node type-code */ |
| 215327 | + u32 *pSz /* Write payload size here */ |
| 215328 | +){ |
| 215329 | + u8 x; |
| 215330 | + u32 sz; |
| 215331 | + u32 n; |
| 215332 | + assert( i<pParse->nBlob ); |
| 215333 | + if( (x = pParse->aBlob[i]>>4)<=11 ){ |
| 215334 | + sz = x; |
| 215335 | + n = 1; |
| 215336 | + }else if( x==12 ){ |
| 215337 | + if( i+1>=pParse->nBlob ){ |
| 215338 | + *pSz = 0; |
| 215339 | + return 0; |
| 215340 | + } |
| 215341 | + sz = pParse->aBlob[i+1]; |
| 215342 | + n = 2; |
| 215343 | + }else{ |
| 215344 | + return jsonbPayloadSizeWide(pParse,i,pSz,x); |
| 215345 | + } |
| 215346 | + if( (i64)i+sz+n > pParse->nBlob |
| 215347 | + && (i64)i+sz+n > pParse->nBlob-pParse->delta |
| 215348 | + ){ |
| 215349 | + *pSz = 0; |
| 215350 | + return 0; |
| 215351 | + } |
| 215352 | + *pSz = sz; |
| 215353 | + return n; |
| 215354 | +} |
| 215355 | +#else /* if !SQLITE_USES_INLINE */ |
| 215356 | + /* On compilers that do not support in-lining, just call the original |
| 215357 | + ** jsonbPayloadSize(). It's slower, but it gets the right answer. */ |
| 215358 | +# define jsonbPayloadSizeSemiInline(a,b,c) jsonbPayloadSize(a,b,c) |
| 215359 | +#endif |
| 215118 | 215360 | |
| 215119 | 215361 | /* |
| 215120 | 215362 | ** Translate the binary JSONB representation of JSON beginning at |
| 215121 | 215363 | ** pParse->aBlob[i] into a JSON text string. Append the JSON |
| 215122 | 215364 | ** text onto the end of pOut. Return the index in pParse->aBlob[] |
| | @@ -215134,11 +215376,11 @@ |
| 215134 | 215376 | u32 i, /* Start rendering at this index */ |
| 215135 | 215377 | JsonString *pOut /* Write JSON here */ |
| 215136 | 215378 | ){ |
| 215137 | 215379 | u32 sz, n, j, iEnd; |
| 215138 | 215380 | |
| 215139 | | - n = jsonbPayloadSize(pParse, i, &sz); |
| 215381 | + n = jsonbPayloadSizeInline(pParse, i, &sz); |
| 215140 | 215382 | if( n==0 ){ |
| 215141 | 215383 | pOut->eErr |= JSTRING_MALFORMED; |
| 215142 | 215384 | return pParse->nBlob+1; |
| 215143 | 215385 | } |
| 215144 | 215386 | switch( pParse->aBlob[i] & 0x0f ){ |
| | @@ -215474,11 +215716,11 @@ |
| 215474 | 215716 | u32 n, sz, i, iEnd; |
| 215475 | 215717 | u32 k = 0; |
| 215476 | 215718 | n = jsonbPayloadSize(pParse, iRoot, &sz); |
| 215477 | 215719 | iEnd = iRoot+n+sz; |
| 215478 | 215720 | for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){ |
| 215479 | | - n = jsonbPayloadSize(pParse, i, &sz); |
| 215721 | + n = jsonbPayloadSizeSemiInline(pParse, i, &sz); |
| 215480 | 215722 | } |
| 215481 | 215723 | return k; |
| 215482 | 215724 | } |
| 215483 | 215725 | |
| 215484 | 215726 | /* |
| | @@ -215984,11 +216226,11 @@ |
| 215984 | 216226 | while( j<iEnd ){ |
| 215985 | 216227 | int rawLabel; |
| 215986 | 216228 | const char *zLabel; |
| 215987 | 216229 | x = pParse->aBlob[j] & 0x0f; |
| 215988 | 216230 | if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; |
| 215989 | | - n = jsonbPayloadSize(pParse, j, &sz); |
| 216231 | + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); |
| 215990 | 216232 | if( n==0 ) return JSON_LOOKUP_ERROR; |
| 215991 | 216233 | k = j+n; /* k is the index of the label text */ |
| 215992 | 216234 | if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; |
| 215993 | 216235 | zLabel = (const char*)&pParse->aBlob[k]; |
| 215994 | 216236 | rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; |
| | @@ -216006,11 +216248,11 @@ |
| 216006 | 216248 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); |
| 216007 | 216249 | return rc; |
| 216008 | 216250 | } |
| 216009 | 216251 | j = k+sz; |
| 216010 | 216252 | if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; |
| 216011 | | - n = jsonbPayloadSize(pParse, j, &sz); |
| 216253 | + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); |
| 216012 | 216254 | if( n==0 ) return JSON_LOOKUP_ERROR; |
| 216013 | 216255 | j += n+sz; |
| 216014 | 216256 | } |
| 216015 | 216257 | if( j>iEnd ) return JSON_LOOKUP_ERROR; |
| 216016 | 216258 | if( pParse->eEdit>=JEDIT_INS ){ |
| | @@ -216095,11 +216337,11 @@ |
| 216095 | 216337 | pParse->iDepth--; |
| 216096 | 216338 | if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); |
| 216097 | 216339 | return rc; |
| 216098 | 216340 | } |
| 216099 | 216341 | kk--; |
| 216100 | | - n = jsonbPayloadSize(pParse, j, &sz); |
| 216342 | + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); |
| 216101 | 216343 | if( n==0 ) return JSON_LOOKUP_ERROR; |
| 216102 | 216344 | j += n+sz; |
| 216103 | 216345 | } |
| 216104 | 216346 | if( j>iEnd ) return JSON_LOOKUP_ERROR; |
| 216105 | 216347 | if( kk>0 ) return JSON_LOOKUP_NOTFOUND; |
| | @@ -223583,10 +223825,12 @@ |
| 223583 | 223825 | /* |
| 223584 | 223826 | ** Function: geopoly_regular(X,Y,R,N) |
| 223585 | 223827 | ** |
| 223586 | 223828 | ** Construct a simple, convex, regular polygon centered at X, Y |
| 223587 | 223829 | ** with circumradius R and with N sides. |
| 223830 | +** |
| 223831 | +** Maximum N is 1000. Maximum R is 1.0e+300. |
| 223588 | 223832 | */ |
| 223589 | 223833 | static void geopolyRegularFunc( |
| 223590 | 223834 | sqlite3_context *context, |
| 223591 | 223835 | int argc, |
| 223592 | 223836 | sqlite3_value **argv |
| | @@ -223597,11 +223841,11 @@ |
| 223597 | 223841 | int n = sqlite3_value_int(argv[3]); |
| 223598 | 223842 | int i; |
| 223599 | 223843 | GeoPoly *p; |
| 223600 | 223844 | (void)argc; |
| 223601 | 223845 | |
| 223602 | | - if( n<3 || r<=0.0 ) return; |
| 223846 | + if( n<3 || r<=0.0 || r>=1e300 ) return; |
| 223603 | 223847 | if( n>1000 ) n = 1000; |
| 223604 | 223848 | p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); |
| 223605 | 223849 | if( p==0 ){ |
| 223606 | 223850 | sqlite3_result_error_nomem(context); |
| 223607 | 223851 | return; |
| | @@ -233626,12 +233870,18 @@ |
| 233626 | 233870 | return SQLITE_OK; |
| 233627 | 233871 | } |
| 233628 | 233872 | default: { |
| 233629 | 233873 | const struct iovec *p = (struct iovec*)pCur->pPtr; |
| 233630 | 233874 | assert( pCur->eType==CARRAY_BLOB ); |
| 233631 | | - sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base, |
| 233632 | | - (int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT); |
| 233875 | + p += pCur->iRowid-1; |
| 233876 | + if( p->iov_len>0x7fffffff ){ |
| 233877 | + sqlite3_result_error_toobig(ctx); |
| 233878 | + return SQLITE_TOOBIG; |
| 233879 | + }else{ |
| 233880 | + sqlite3_result_blob(ctx, p->iov_base, (int)p->iov_len, |
| 233881 | + SQLITE_TRANSIENT); |
| 233882 | + } |
| 233633 | 233883 | return SQLITE_OK; |
| 233634 | 233884 | } |
| 233635 | 233885 | } |
| 233636 | 233886 | } |
| 233637 | 233887 | } |
| | @@ -239561,14 +239811,14 @@ |
| 239561 | 239811 | int flags /* SESSION_APPLY_XXX flags */ |
| 239562 | 239812 | ){ |
| 239563 | 239813 | int schemaMismatch = 0; |
| 239564 | 239814 | int rc = SQLITE_OK; /* Return code */ |
| 239565 | 239815 | const char *zTab = 0; /* Name of current table */ |
| 239566 | | - int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ |
| 239567 | 239816 | SessionApplyCtx sApply; /* changeset_apply() context object */ |
| 239568 | 239817 | int bPatchset; |
| 239569 | 239818 | u64 savedFlag = db->flags & SQLITE_FkNoAction; |
| 239819 | + int bNew = 0; /* True for first entry of new table */ |
| 239570 | 239820 | |
| 239571 | 239821 | assert( xConflict!=0 ); |
| 239572 | 239822 | |
| 239573 | 239823 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); |
| 239574 | 239824 | if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ |
| | @@ -239586,19 +239836,20 @@ |
| 239586 | 239836 | rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); |
| 239587 | 239837 | } |
| 239588 | 239838 | if( rc==SQLITE_OK ){ |
| 239589 | 239839 | rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); |
| 239590 | 239840 | } |
| 239591 | | - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ |
| 239841 | + while( rc==SQLITE_OK && SQLITE_ROW==sessionChangesetNext(pIter, 0, 0,&bNew) ){ |
| 239592 | 239842 | int nCol; |
| 239593 | 239843 | int op; |
| 239594 | 239844 | const char *zNew; |
| 239595 | 239845 | |
| 239596 | 239846 | sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); |
| 239597 | 239847 | |
| 239598 | | - if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ |
| 239848 | + if( bNew ){ |
| 239599 | 239849 | u8 *abPK; |
| 239850 | + bNew = 0; |
| 239600 | 239851 | |
| 239601 | 239852 | rc = sessionRetryConstraints( |
| 239602 | 239853 | db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx |
| 239603 | 239854 | ); |
| 239604 | 239855 | if( rc!=SQLITE_OK ) break; |
| | @@ -239629,11 +239880,10 @@ |
| 239629 | 239880 | zTab = sqlite3_mprintf("%s", zNew); |
| 239630 | 239881 | if( zTab==0 ){ |
| 239631 | 239882 | rc = SQLITE_NOMEM; |
| 239632 | 239883 | break; |
| 239633 | 239884 | } |
| 239634 | | - nTab = (int)strlen(zTab); |
| 239635 | 239885 | sApply.azCol = (const char **)zTab; |
| 239636 | 239886 | }else{ |
| 239637 | 239887 | int nMinCol = 0; |
| 239638 | 239888 | int i; |
| 239639 | 239889 | |
| | @@ -239682,11 +239932,10 @@ |
| 239682 | 239932 | break; |
| 239683 | 239933 | } |
| 239684 | 239934 | sApply.bStat1 = 0; |
| 239685 | 239935 | } |
| 239686 | 239936 | } |
| 239687 | | - nTab = sqlite3Strlen30(zTab); |
| 239688 | 239937 | } |
| 239689 | 239938 | } |
| 239690 | 239939 | |
| 239691 | 239940 | /* If there is a schema mismatch on the current table, proceed to the |
| 239692 | 239941 | ** next change. A log message has already been issued. */ |
| | @@ -251353,11 +251602,16 @@ |
| 251353 | 251602 | ** sequentially starting from 1. |
| 251354 | 251603 | */ |
| 251355 | 251604 | #define FTS5_DATA_ID_B 16 /* Max seg id number 65535 */ |
| 251356 | 251605 | #define FTS5_DATA_DLI_B 1 /* Doclist-index flag (1 bit) */ |
| 251357 | 251606 | #define FTS5_DATA_HEIGHT_B 5 /* Max dlidx tree height of 32 */ |
| 251358 | | -#define FTS5_DATA_PAGE_B 31 /* Max page number of 2147483648 */ |
| 251607 | +#define FTS5_DATA_PAGE_B 31 /* 31-bit page numbers */ |
| 251608 | + |
| 251609 | +/* Maximum page number within a segment. Declare any structure read from |
| 251610 | +** the database with a page number greater than this corrupt. It is not |
| 251611 | +** actually possible to create a database this large. */ |
| 251612 | +#define FTS5_MAX_PGNO 0x7FFFFF00 |
| 251359 | 251613 | |
| 251360 | 251614 | #define fts5_dri(segid, dlidx, height, pgno) ( \ |
| 251361 | 251615 | ((i64)(segid) << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) + \ |
| 251362 | 251616 | ((i64)(dlidx) << (FTS5_DATA_PAGE_B + FTS5_DATA_HEIGHT_B)) + \ |
| 251363 | 251617 | ((i64)(height) << (FTS5_DATA_PAGE_B)) + \ |
| | @@ -252266,11 +252520,11 @@ |
| 252266 | 252520 | i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone); |
| 252267 | 252521 | i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone); |
| 252268 | 252522 | i += fts5GetVarint(&pData[i], &pSeg->nEntry); |
| 252269 | 252523 | nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2); |
| 252270 | 252524 | } |
| 252271 | | - if( pSeg->pgnoLast<pSeg->pgnoFirst ){ |
| 252525 | + if( pSeg->pgnoLast<pSeg->pgnoFirst || pSeg->pgnoLast>FTS5_MAX_PGNO ){ |
| 252272 | 252526 | rc = FTS5_CORRUPT; |
| 252273 | 252527 | break; |
| 252274 | 252528 | } |
| 252275 | 252529 | } |
| 252276 | 252530 | if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT; |
| | @@ -252862,10 +253116,13 @@ |
| 252862 | 253116 | pLvl->pData = fts5DataRead(p, iRowid); |
| 252863 | 253117 | if( pLvl->pData && (pLvl->pData->p[0] & 0x0001)==0 ){ |
| 252864 | 253118 | bDone = 1; |
| 252865 | 253119 | } |
| 252866 | 253120 | pIter->nLvl = i+1; |
| 253121 | + if( pIter->nLvl > (1<<FTS5_DATA_HEIGHT_B) ){ |
| 253122 | + p->rc = FTS5_CORRUPT; |
| 253123 | + } |
| 252867 | 253124 | } |
| 252868 | 253125 | } |
| 252869 | 253126 | |
| 252870 | 253127 | if( p->rc==SQLITE_OK ){ |
| 252871 | 253128 | pIter->iSegid = iSegid; |
| | @@ -256583,38 +256840,42 @@ |
| 256583 | 256840 | ** iNextOff: Offset to move data from |
| 256584 | 256841 | */ |
| 256585 | 256842 | if( p->rc==SQLITE_OK ){ |
| 256586 | 256843 | const int nMove = nPg - iNextOff; /* Number of bytes to move */ |
| 256587 | 256844 | int nShift = iNextOff - iOff; /* Distance to move them */ |
| 256588 | | - |
| 256845 | + int nNewPg = 0; |
| 256589 | 256846 | int iPrevKeyOut = 0; |
| 256590 | | - int iKeyIn = 0; |
| 256847 | + i64 iKeyIn = 0; |
| 256591 | 256848 | |
| 256592 | 256849 | if( nMove>0 ){ |
| 256593 | 256850 | memmove(&aPg[iOff], &aPg[iNextOff], nMove); |
| 256594 | 256851 | } |
| 256595 | 256852 | iPgIdx -= nShift; |
| 256596 | | - nPg = iPgIdx; |
| 256853 | + nNewPg = iPgIdx; |
| 256597 | 256854 | fts5PutU16(&aPg[2], iPgIdx); |
| 256598 | 256855 | |
| 256599 | 256856 | for(iIdx=0; iIdx<nIdx; /* no-op */){ |
| 256600 | 256857 | u32 iVal = 0; |
| 256601 | 256858 | iIdx += fts5GetVarint32(&aIdx[iIdx], iVal); |
| 256602 | 256859 | iKeyIn += iVal; |
| 256860 | + if( iKeyIn>nPg ){ |
| 256861 | + FTS5_CORRUPT_IDX(p); |
| 256862 | + break; |
| 256863 | + } |
| 256603 | 256864 | if( iKeyIn!=iDelKeyOff ){ |
| 256604 | 256865 | int iKeyOut = (iKeyIn - (iKeyIn>iOff ? nShift : 0)); |
| 256605 | | - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOut - iPrevKeyOut); |
| 256866 | + nNewPg += sqlite3Fts5PutVarint(&aPg[nNewPg], iKeyOut - iPrevKeyOut); |
| 256606 | 256867 | iPrevKeyOut = iKeyOut; |
| 256607 | 256868 | } |
| 256608 | 256869 | } |
| 256609 | 256870 | |
| 256610 | | - if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ |
| 256871 | + if( p->rc==SQLITE_OK && iPgIdx==nNewPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ |
| 256611 | 256872 | fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); |
| 256612 | 256873 | } |
| 256613 | 256874 | |
| 256614 | | - assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); |
| 256615 | | - fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nPg); |
| 256875 | + assert_nc( nNewPg>4 || fts5GetU16(aPg)==0 ); |
| 256876 | + fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nNewPg); |
| 256616 | 256877 | } |
| 256617 | 256878 | sqlite3_free(aIdx); |
| 256618 | 256879 | } |
| 256619 | 256880 | |
| 256620 | 256881 | /* |
| | @@ -264272,11 +264533,11 @@ |
| 264272 | 264533 | int nArg, /* Number of args */ |
| 264273 | 264534 | sqlite3_value **apUnused /* Function arguments */ |
| 264274 | 264535 | ){ |
| 264275 | 264536 | assert( nArg==0 ); |
| 264276 | 264537 | UNUSED_PARAM2(nArg, apUnused); |
| 264277 | | - sqlite3_result_text(pCtx, "fts5: 2026-08-11 10:46:12 fee71cd6f7294ffd02784d26811a9d11d80e83d4075e1233b8ec0289519bb891", -1, SQLITE_TRANSIENT); |
| 264538 | + sqlite3_result_text(pCtx, "fts5: 2026-08-20 13:25:12 3bd5456e50ef321f2cafcf67261d556a760624ce0caab430ed9454cebec233e7", -1, SQLITE_TRANSIENT); |
| 264278 | 264539 | } |
| 264279 | 264540 | |
| 264280 | 264541 | /* |
| 264281 | 264542 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 264282 | 264543 | ** |
| | @@ -268951,10 +269212,18 @@ |
| 268951 | 269212 | sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
| 268952 | 269213 | char **pzErr /* OUT: sqlite3_malloc'd error message */ |
| 268953 | 269214 | ){ |
| 268954 | 269215 | return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); |
| 268955 | 269216 | } |
| 269217 | + |
| 269218 | +/* |
| 269219 | +** Return true if constraint iCons of pInfo uses the "binary" collation |
| 269220 | +** sequence. Or false it it uses anything else. |
| 269221 | +*/ |
| 269222 | +static int fts5VocabIsBinary(sqlite3_index_info *pInfo, int iCons){ |
| 269223 | + return 0==sqlite3_stricmp("binary", sqlite3_vtab_collation(pInfo, iCons)); |
| 269224 | +} |
| 268956 | 269225 | |
| 268957 | 269226 | /* |
| 268958 | 269227 | ** Implementation of the xBestIndex method. |
| 268959 | 269228 | ** |
| 268960 | 269229 | ** Only constraints of the form: |
| | @@ -268982,11 +269251,11 @@ |
| 268982 | 269251 | assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); |
| 268983 | 269252 | |
| 268984 | 269253 | for(i=0; i<pInfo->nConstraint; i++){ |
| 268985 | 269254 | struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; |
| 268986 | 269255 | if( p->usable==0 ) continue; |
| 268987 | | - if( p->iColumn==0 ){ /* term column */ |
| 269256 | + if( p->iColumn==0 && fts5VocabIsBinary(pInfo, i) ){ /* term column */ |
| 268988 | 269257 | if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; |
| 268989 | 269258 | if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i; |
| 268990 | 269259 | if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i; |
| 268991 | 269260 | if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i; |
| 268992 | 269261 | if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i; |
| | @@ -269320,10 +269589,30 @@ |
| 269320 | 269589 | rc = FTS5_CORRUPT; |
| 269321 | 269590 | } |
| 269322 | 269591 | } |
| 269323 | 269592 | return rc; |
| 269324 | 269593 | } |
| 269594 | + |
| 269595 | +/* |
| 269596 | +** If value pVal is an SQLITE_TEXT value, return a pointer to a buffer |
| 269597 | +** containing the UTF-8 representation of the value, and set output |
| 269598 | +** parameter (*pnText) to the size of the buffer contents in bytes. Or, |
| 269599 | +** if pVal is some other type of value, return NULL and set (*pnText) |
| 269600 | +** to 0 before returning. |
| 269601 | +*/ |
| 269602 | +static const char *fts5VocabValueText(sqlite3_value *pVal, int *pnText){ |
| 269603 | + const char *zRet = 0; |
| 269604 | + int nRet = 0; |
| 269605 | + |
| 269606 | + if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ |
| 269607 | + zRet = (const char*)sqlite3_value_text(pVal); |
| 269608 | + nRet = sqlite3_value_bytes(pVal); |
| 269609 | + } |
| 269610 | + |
| 269611 | + *pnText = nRet; |
| 269612 | + return zRet; |
| 269613 | +} |
| 269325 | 269614 | |
| 269326 | 269615 | /* |
| 269327 | 269616 | ** This is the xFilter implementation for the virtual table. |
| 269328 | 269617 | */ |
| 269329 | 269618 | static int fts5VocabFilterMethod( |
| | @@ -269354,22 +269643,19 @@ |
| 269354 | 269643 | if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; |
| 269355 | 269644 | if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; |
| 269356 | 269645 | pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); |
| 269357 | 269646 | |
| 269358 | 269647 | if( pEq ){ |
| 269359 | | - zTerm = (const char *)sqlite3_value_text(pEq); |
| 269360 | | - nTerm = sqlite3_value_bytes(pEq); |
| 269648 | + zTerm = fts5VocabValueText(pEq, &nTerm); |
| 269361 | 269649 | f = FTS5INDEX_QUERY_NOTOKENDATA; |
| 269362 | 269650 | }else{ |
| 269363 | 269651 | if( pGe ){ |
| 269364 | | - zTerm = (const char *)sqlite3_value_text(pGe); |
| 269365 | | - nTerm = sqlite3_value_bytes(pGe); |
| 269652 | + zTerm = fts5VocabValueText(pGe, &nTerm); |
| 269366 | 269653 | } |
| 269367 | 269654 | if( pLe ){ |
| 269368 | | - const char *zCopy = (const char *)sqlite3_value_text(pLe); |
| 269655 | + const char *zCopy = fts5VocabValueText(pLe, &pCsr->nLeTerm); |
| 269369 | 269656 | if( zCopy==0 ) zCopy = ""; |
| 269370 | | - pCsr->nLeTerm = sqlite3_value_bytes(pLe); |
| 269371 | 269657 | pCsr->zLeTerm = sqlite3_malloc64((i64)pCsr->nLeTerm+1); |
| 269372 | 269658 | if( pCsr->zLeTerm==0 ){ |
| 269373 | 269659 | rc = SQLITE_NOMEM; |
| 269374 | 269660 | }else{ |
| 269375 | 269661 | memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1); |
| 269376 | 269662 | |