| | @@ -656,11 +656,11 @@ |
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | | -#define SQLITE_SOURCE_ID "2013-09-04 04:04:08 8df95bb0b3f72222cf262174247a467c234f9939" |
| 661 | +#define SQLITE_SOURCE_ID "2013-09-16 12:57:19 daf6ba413cb3cb6065774ba07495eab4a28b49b0" |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| | @@ -10143,12 +10143,10 @@ |
| 10143 | 10143 | #endif |
| 10144 | 10144 | void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); |
| 10145 | 10145 | void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); |
| 10146 | 10146 | void *pCollNeededArg; |
| 10147 | 10147 | sqlite3_value *pErr; /* Most recent error message */ |
| 10148 | | - char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ |
| 10149 | | - char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ |
| 10150 | 10148 | union { |
| 10151 | 10149 | volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ |
| 10152 | 10150 | double notUsed1; /* Spacer */ |
| 10153 | 10151 | } u1; |
| 10154 | 10152 | Lookaside lookaside; /* Lookaside malloc configuration */ |
| | @@ -10254,10 +10252,11 @@ |
| 10254 | 10252 | #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ |
| 10255 | 10253 | #define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ |
| 10256 | 10254 | #define SQLITE_Transitive 0x0200 /* Transitive constraints */ |
| 10257 | 10255 | #define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ |
| 10258 | 10256 | #define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */ |
| 10257 | +#define SQLITE_AdjustOutEst 0x1000 /* Adjust output estimates using WHERE */ |
| 10259 | 10258 | #define SQLITE_AllOpts 0xffff /* All optimizations */ |
| 10260 | 10259 | |
| 10261 | 10260 | /* |
| 10262 | 10261 | ** Macros for testing whether or not optimizations are enabled or disabled. |
| 10263 | 10262 | */ |
| | @@ -10287,12 +10286,11 @@ |
| 10287 | 10286 | ** hash table. When multiple functions have the same name, the hash table |
| 10288 | 10287 | ** points to a linked list of these structures. |
| 10289 | 10288 | */ |
| 10290 | 10289 | struct FuncDef { |
| 10291 | 10290 | i16 nArg; /* Number of arguments. -1 means unlimited */ |
| 10292 | | - u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */ |
| 10293 | | - u8 flags; /* Some combination of SQLITE_FUNC_* */ |
| 10291 | + u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ |
| 10294 | 10292 | void *pUserData; /* User data parameter */ |
| 10295 | 10293 | FuncDef *pNext; /* Next function with same name */ |
| 10296 | 10294 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ |
| 10297 | 10295 | void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */ |
| 10298 | 10296 | void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */ |
| | @@ -10324,18 +10322,20 @@ |
| 10324 | 10322 | /* |
| 10325 | 10323 | ** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF |
| 10326 | 10324 | ** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There |
| 10327 | 10325 | ** are assert() statements in the code to verify this. |
| 10328 | 10326 | */ |
| 10329 | | -#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ |
| 10330 | | -#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ |
| 10331 | | -#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */ |
| 10332 | | -#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */ |
| 10333 | | -#define SQLITE_FUNC_COUNT 0x10 /* Built-in count(*) aggregate */ |
| 10334 | | -#define SQLITE_FUNC_COALESCE 0x20 /* Built-in coalesce() or ifnull() function */ |
| 10335 | | -#define SQLITE_FUNC_LENGTH 0x40 /* Built-in length() function */ |
| 10336 | | -#define SQLITE_FUNC_TYPEOF 0x80 /* Built-in typeof() function */ |
| 10327 | +#define SQLITE_FUNC_ENCMASK 0x003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ |
| 10328 | +#define SQLITE_FUNC_LIKE 0x004 /* Candidate for the LIKE optimization */ |
| 10329 | +#define SQLITE_FUNC_CASE 0x008 /* Case-sensitive LIKE-type function */ |
| 10330 | +#define SQLITE_FUNC_EPHEM 0x010 /* Ephemeral. Delete with VDBE */ |
| 10331 | +#define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */ |
| 10332 | +#define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */ |
| 10333 | +#define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */ |
| 10334 | +#define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ |
| 10335 | +#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ |
| 10336 | +#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ |
| 10337 | 10337 | |
| 10338 | 10338 | /* |
| 10339 | 10339 | ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are |
| 10340 | 10340 | ** used to create the initializers for the FuncDef structures. |
| 10341 | 10341 | ** |
| | @@ -10359,22 +10359,22 @@ |
| 10359 | 10359 | ** available as the function user-data (sqlite3_user_data()). The |
| 10360 | 10360 | ** FuncDef.flags variable is set to the value passed as the flags |
| 10361 | 10361 | ** parameter. |
| 10362 | 10362 | */ |
| 10363 | 10363 | #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ |
| 10364 | | - {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10364 | + {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10365 | 10365 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} |
| 10366 | 10366 | #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ |
| 10367 | | - {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ |
| 10367 | + {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ |
| 10368 | 10368 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} |
| 10369 | 10369 | #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ |
| 10370 | | - {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \ |
| 10370 | + {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10371 | 10371 | pArg, 0, xFunc, 0, 0, #zName, 0, 0} |
| 10372 | 10372 | #define LIKEFUNC(zName, nArg, arg, flags) \ |
| 10373 | | - {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} |
| 10373 | + {nArg, SQLITE_UTF8|flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} |
| 10374 | 10374 | #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ |
| 10375 | | - {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \ |
| 10375 | + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ |
| 10376 | 10376 | SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} |
| 10377 | 10377 | |
| 10378 | 10378 | /* |
| 10379 | 10379 | ** All current savepoints are stored in a linked list starting at |
| 10380 | 10380 | ** sqlite3.pSavepoint. The first element in the list is the most recently |
| | @@ -10945,11 +10945,11 @@ |
| 10945 | 10945 | ** allocated, regardless of whether or not EP_Reduced is set. |
| 10946 | 10946 | */ |
| 10947 | 10947 | struct Expr { |
| 10948 | 10948 | u8 op; /* Operation performed by this node */ |
| 10949 | 10949 | char affinity; /* The affinity of the column or 0 if not a column */ |
| 10950 | | - u16 flags; /* Various flags. EP_* See below */ |
| 10950 | + u32 flags; /* Various flags. EP_* See below */ |
| 10951 | 10951 | union { |
| 10952 | 10952 | char *zToken; /* Token value. Zero terminated and dequoted */ |
| 10953 | 10953 | int iValue; /* Non-negative integer value if EP_IntValue */ |
| 10954 | 10954 | } u; |
| 10955 | 10955 | |
| | @@ -10959,12 +10959,12 @@ |
| 10959 | 10959 | *********************************************************************/ |
| 10960 | 10960 | |
| 10961 | 10961 | Expr *pLeft; /* Left subnode */ |
| 10962 | 10962 | Expr *pRight; /* Right subnode */ |
| 10963 | 10963 | union { |
| 10964 | | - ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */ |
| 10965 | | - Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */ |
| 10964 | + ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */ |
| 10965 | + Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */ |
| 10966 | 10966 | } x; |
| 10967 | 10967 | |
| 10968 | 10968 | /* If the EP_Reduced flag is set in the Expr.flags mask, then no |
| 10969 | 10969 | ** space is allocated for the fields below this point. An attempt to |
| 10970 | 10970 | ** access them will result in a segfault or malfunction. |
| | @@ -10973,16 +10973,16 @@ |
| 10973 | 10973 | #if SQLITE_MAX_EXPR_DEPTH>0 |
| 10974 | 10974 | int nHeight; /* Height of the tree headed by this node */ |
| 10975 | 10975 | #endif |
| 10976 | 10976 | int iTable; /* TK_COLUMN: cursor number of table holding column |
| 10977 | 10977 | ** TK_REGISTER: register number |
| 10978 | | - ** TK_TRIGGER: 1 -> new, 0 -> old */ |
| 10978 | + ** TK_TRIGGER: 1 -> new, 0 -> old |
| 10979 | + ** EP_Unlikely: 1000 times likelihood */ |
| 10979 | 10980 | ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. |
| 10980 | 10981 | ** TK_VARIABLE: variable number (always >= 1). */ |
| 10981 | 10982 | i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ |
| 10982 | 10983 | i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ |
| 10983 | | - u8 flags2; /* Second set of flags. EP2_... */ |
| 10984 | 10984 | u8 op2; /* TK_REGISTER: original value of Expr.op |
| 10985 | 10985 | ** TK_COLUMN: the value of p5 for OP_Column |
| 10986 | 10986 | ** TK_AGG_FUNCTION: nesting depth */ |
| 10987 | 10987 | AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ |
| 10988 | 10988 | Table *pTab; /* Table for TK_COLUMN expressions. */ |
| | @@ -10989,53 +10989,48 @@ |
| 10989 | 10989 | }; |
| 10990 | 10990 | |
| 10991 | 10991 | /* |
| 10992 | 10992 | ** The following are the meanings of bits in the Expr.flags field. |
| 10993 | 10993 | */ |
| 10994 | | -#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ |
| 10995 | | -#define EP_Agg 0x0002 /* Contains one or more aggregate functions */ |
| 10996 | | -#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ |
| 10997 | | -#define EP_Error 0x0008 /* Expression contains one or more errors */ |
| 10998 | | -#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */ |
| 10999 | | -#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */ |
| 11000 | | -#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */ |
| 11001 | | -#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */ |
| 11002 | | -#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */ |
| 11003 | | -#define EP_FixedDest 0x0200 /* Result needed in a specific register */ |
| 11004 | | -#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */ |
| 11005 | | -#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */ |
| 11006 | | -#define EP_Hint 0x1000 /* Not used */ |
| 11007 | | -#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */ |
| 11008 | | -#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */ |
| 11009 | | -#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */ |
| 11010 | | - |
| 11011 | | -/* |
| 11012 | | -** The following are the meanings of bits in the Expr.flags2 field. |
| 11013 | | -*/ |
| 11014 | | -#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11015 | | -#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11016 | | - |
| 11017 | | -/* |
| 11018 | | -** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible |
| 11019 | | -** flag on an expression structure. This flag is used for VV&A only. The |
| 11020 | | -** routine is implemented as a macro that only works when in debugging mode, |
| 11021 | | -** so as not to burden production code. |
| 11022 | | -*/ |
| 11023 | | -#ifdef SQLITE_DEBUG |
| 11024 | | -# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible |
| 11025 | | -#else |
| 11026 | | -# define ExprSetIrreducible(X) |
| 11027 | | -#endif |
| 10994 | +#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */ |
| 10995 | +#define EP_Agg 0x000002 /* Contains one or more aggregate functions */ |
| 10996 | +#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ |
| 10997 | +#define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 10998 | +#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 10999 | +#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| 11000 | +#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ |
| 11001 | +#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ |
| 11002 | +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */ |
| 11003 | +#define EP_FixedDest 0x000200 /* Result needed in a specific register */ |
| 11004 | +#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ |
| 11005 | +#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ |
| 11006 | +#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ |
| 11007 | +#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ |
| 11008 | +#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ |
| 11009 | +#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ |
| 11010 | +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11011 | +#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11012 | +#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ |
| 11028 | 11013 | |
| 11029 | 11014 | /* |
| 11030 | 11015 | ** These macros can be used to test, set, or clear bits in the |
| 11031 | 11016 | ** Expr.flags field. |
| 11032 | 11017 | */ |
| 11033 | | -#define ExprHasProperty(E,P) (((E)->flags&(P))==(P)) |
| 11034 | | -#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0) |
| 11018 | +#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) |
| 11019 | +#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) |
| 11035 | 11020 | #define ExprSetProperty(E,P) (E)->flags|=(P) |
| 11036 | 11021 | #define ExprClearProperty(E,P) (E)->flags&=~(P) |
| 11022 | + |
| 11023 | +/* The ExprSetVVAProperty() macro is used for Verification, Validation, |
| 11024 | +** and Accreditation only. It works like ExprSetProperty() during VVA |
| 11025 | +** processes but is a no-op for delivery. |
| 11026 | +*/ |
| 11027 | +#ifdef SQLITE_DEBUG |
| 11028 | +# define ExprSetVVAProperty(E,P) (E)->flags|=(P) |
| 11029 | +#else |
| 11030 | +# define ExprSetVVAProperty(E,P) |
| 11031 | +#endif |
| 11037 | 11032 | |
| 11038 | 11033 | /* |
| 11039 | 11034 | ** Macros to determine the number of bytes required by a normal Expr |
| 11040 | 11035 | ** struct, an Expr struct with the EP_Reduced flag set in Expr.flags |
| 11041 | 11036 | ** and an Expr struct with the EP_TokenOnly flag set. |
| | @@ -12411,10 +12406,11 @@ |
| 12411 | 12406 | SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); |
| 12412 | 12407 | SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); |
| 12413 | 12408 | SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); |
| 12414 | 12409 | SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); |
| 12415 | 12410 | SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); |
| 12411 | +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); |
| 12416 | 12412 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); |
| 12417 | 12413 | SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); |
| 12418 | 12414 | SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); |
| 12419 | 12415 | SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); |
| 12420 | 12416 | SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); |
| | @@ -12431,22 +12427,22 @@ |
| 12431 | 12427 | ** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In |
| 12432 | 12428 | ** this case foreign keys are parsed, but no other functionality is |
| 12433 | 12429 | ** provided (enforcement of FK constraints requires the triggers sub-system). |
| 12434 | 12430 | */ |
| 12435 | 12431 | #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 12436 | | -SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int); |
| 12432 | +SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); |
| 12437 | 12433 | SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); |
| 12438 | | -SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int); |
| 12434 | +SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); |
| 12439 | 12435 | SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); |
| 12440 | 12436 | SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); |
| 12441 | 12437 | SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); |
| 12442 | 12438 | #else |
| 12443 | | - #define sqlite3FkActions(a,b,c,d) |
| 12439 | + #define sqlite3FkActions(a,b,c,d,e,f) |
| 12444 | 12440 | #define sqlite3FkCheck(a,b,c,d) |
| 12445 | 12441 | #define sqlite3FkDropTable(a,b,c) |
| 12446 | | - #define sqlite3FkOldmask(a,b) 0 |
| 12447 | | - #define sqlite3FkRequired(a,b,c,d) 0 |
| 12442 | + #define sqlite3FkOldmask(a,b) 0 |
| 12443 | + #define sqlite3FkRequired(a,b,c,d,e,f) 0 |
| 12448 | 12444 | #endif |
| 12449 | 12445 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 12450 | 12446 | SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); |
| 12451 | 12447 | SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); |
| 12452 | 12448 | #else |
| | @@ -13589,10 +13585,11 @@ |
| 13589 | 13585 | int iStatement; /* Statement number (or 0 if has not opened stmt) */ |
| 13590 | 13586 | u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ |
| 13591 | 13587 | #ifndef SQLITE_OMIT_TRACE |
| 13592 | 13588 | i64 startTime; /* Time when query started - used for profiling */ |
| 13593 | 13589 | #endif |
| 13590 | + i64 iCurrentTime; /* Value of julianday('now') for this statement */ |
| 13594 | 13591 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13595 | 13592 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| 13596 | 13593 | i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ |
| 13597 | 13594 | char *zSql; /* Text of the SQL statement that generated this */ |
| 13598 | 13595 | void *pFree; /* Free this when deleting the vdbe */ |
| | @@ -14268,12 +14265,12 @@ |
| 14268 | 14265 | ** Set the time to the current time reported by the VFS. |
| 14269 | 14266 | ** |
| 14270 | 14267 | ** Return the number of errors. |
| 14271 | 14268 | */ |
| 14272 | 14269 | static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ |
| 14273 | | - sqlite3 *db = sqlite3_context_db_handle(context); |
| 14274 | | - if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){ |
| 14270 | + p->iJD = sqlite3StmtCurrentTime(context); |
| 14271 | + if( p->iJD>0 ){ |
| 14275 | 14272 | p->validJD = 1; |
| 14276 | 14273 | return 0; |
| 14277 | 14274 | }else{ |
| 14278 | 14275 | return 1; |
| 14279 | 14276 | } |
| | @@ -15052,12 +15049,12 @@ |
| 15052 | 15049 | char zBuf[20]; |
| 15053 | 15050 | |
| 15054 | 15051 | UNUSED_PARAMETER(argc); |
| 15055 | 15052 | UNUSED_PARAMETER(argv); |
| 15056 | 15053 | |
| 15057 | | - db = sqlite3_context_db_handle(context); |
| 15058 | | - if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return; |
| 15054 | + iT = sqlite3StmtCurrentTime(context); |
| 15055 | + if( iT<=0 ) return; |
| 15059 | 15056 | t = iT/1000 - 10000*(sqlite3_int64)21086676; |
| 15060 | 15057 | #ifdef HAVE_GMTIME_R |
| 15061 | 15058 | pTm = gmtime_r(&t, &sNow); |
| 15062 | 15059 | #else |
| 15063 | 15060 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| | @@ -19259,10 +19256,11 @@ |
| 19259 | 19256 | ** Free memory that might be associated with a particular database |
| 19260 | 19257 | ** connection. |
| 19261 | 19258 | */ |
| 19262 | 19259 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ |
| 19263 | 19260 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); |
| 19261 | + if( p==0 ) return; |
| 19264 | 19262 | if( db ){ |
| 19265 | 19263 | if( db->pnBytesFreed ){ |
| 19266 | 19264 | *db->pnBytesFreed += sqlite3DbMallocSize(db, p); |
| 19267 | 19265 | return; |
| 19268 | 19266 | } |
| | @@ -21374,11 +21372,12 @@ |
| 21374 | 21372 | case '"': break; |
| 21375 | 21373 | case '`': break; /* For MySQL compatibility */ |
| 21376 | 21374 | case '[': quote = ']'; break; /* For MS SqlServer compatibility */ |
| 21377 | 21375 | default: return -1; |
| 21378 | 21376 | } |
| 21379 | | - for(i=1, j=0; ALWAYS(z[i]); i++){ |
| 21377 | + for(i=1, j=0;; i++){ |
| 21378 | + assert( z[i] ); |
| 21380 | 21379 | if( z[i]==quote ){ |
| 21381 | 21380 | if( z[i+1]==quote ){ |
| 21382 | 21381 | z[j++] = quote; |
| 21383 | 21382 | i++; |
| 21384 | 21383 | }else{ |
| | @@ -30809,10 +30808,18 @@ |
| 30809 | 30808 | */ |
| 30810 | 30809 | #ifndef winIsDirSep |
| 30811 | 30810 | # define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) |
| 30812 | 30811 | #endif |
| 30813 | 30812 | |
| 30813 | +/* |
| 30814 | +** This macro is used when a local variable is set to a value that is |
| 30815 | +** [sometimes] not used by the code (e.g. via conditional compilation). |
| 30816 | +*/ |
| 30817 | +#ifndef UNUSED_VARIABLE_VALUE |
| 30818 | +# define UNUSED_VARIABLE_VALUE(x) (void)(x) |
| 30819 | +#endif |
| 30820 | + |
| 30814 | 30821 | /* |
| 30815 | 30822 | ** Returns the string that should be used as the directory separator. |
| 30816 | 30823 | */ |
| 30817 | 30824 | #ifndef winGetDirDep |
| 30818 | 30825 | # ifdef __CYGWIN__ |
| | @@ -31059,11 +31066,12 @@ |
| 31059 | 31066 | ** In order to facilitate testing on a WinNT system, the test fixture |
| 31060 | 31067 | ** can manually set this value to 1 to emulate Win98 behavior. |
| 31061 | 31068 | */ |
| 31062 | 31069 | #ifdef SQLITE_TEST |
| 31063 | 31070 | SQLITE_API int sqlite3_os_type = 0; |
| 31064 | | -#else |
| 31071 | +#elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ |
| 31072 | + defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE) |
| 31065 | 31073 | static int sqlite3_os_type = 0; |
| 31066 | 31074 | #endif |
| 31067 | 31075 | |
| 31068 | 31076 | #ifndef SYSCALL |
| 31069 | 31077 | # define SYSCALL sqlite3_syscall_ptr |
| | @@ -31374,89 +31382,98 @@ |
| 31374 | 31382 | #endif |
| 31375 | 31383 | |
| 31376 | 31384 | #define osGetVersionExA ((BOOL(WINAPI*)( \ |
| 31377 | 31385 | LPOSVERSIONINFOA))aSyscall[34].pCurrent) |
| 31378 | 31386 | |
| 31387 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 31388 | + { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, |
| 31389 | +#else |
| 31390 | + { "GetVersionExW", (SYSCALL)0, 0 }, |
| 31391 | +#endif |
| 31392 | + |
| 31393 | +#define osGetVersionExW ((BOOL(WINAPI*)( \ |
| 31394 | + LPOSVERSIONINFOW))aSyscall[35].pCurrent) |
| 31395 | + |
| 31379 | 31396 | { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, |
| 31380 | 31397 | |
| 31381 | 31398 | #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ |
| 31382 | | - SIZE_T))aSyscall[35].pCurrent) |
| 31399 | + SIZE_T))aSyscall[36].pCurrent) |
| 31383 | 31400 | |
| 31384 | 31401 | #if !SQLITE_OS_WINRT |
| 31385 | 31402 | { "HeapCreate", (SYSCALL)HeapCreate, 0 }, |
| 31386 | 31403 | #else |
| 31387 | 31404 | { "HeapCreate", (SYSCALL)0, 0 }, |
| 31388 | 31405 | #endif |
| 31389 | 31406 | |
| 31390 | 31407 | #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ |
| 31391 | | - SIZE_T))aSyscall[36].pCurrent) |
| 31408 | + SIZE_T))aSyscall[37].pCurrent) |
| 31392 | 31409 | |
| 31393 | 31410 | #if !SQLITE_OS_WINRT |
| 31394 | 31411 | { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, |
| 31395 | 31412 | #else |
| 31396 | 31413 | { "HeapDestroy", (SYSCALL)0, 0 }, |
| 31397 | 31414 | #endif |
| 31398 | 31415 | |
| 31399 | | -#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent) |
| 31416 | +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) |
| 31400 | 31417 | |
| 31401 | 31418 | { "HeapFree", (SYSCALL)HeapFree, 0 }, |
| 31402 | 31419 | |
| 31403 | | -#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent) |
| 31420 | +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) |
| 31404 | 31421 | |
| 31405 | 31422 | { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, |
| 31406 | 31423 | |
| 31407 | 31424 | #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ |
| 31408 | | - SIZE_T))aSyscall[39].pCurrent) |
| 31425 | + SIZE_T))aSyscall[40].pCurrent) |
| 31409 | 31426 | |
| 31410 | 31427 | { "HeapSize", (SYSCALL)HeapSize, 0 }, |
| 31411 | 31428 | |
| 31412 | 31429 | #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ |
| 31413 | | - LPCVOID))aSyscall[40].pCurrent) |
| 31430 | + LPCVOID))aSyscall[41].pCurrent) |
| 31414 | 31431 | |
| 31415 | 31432 | #if !SQLITE_OS_WINRT |
| 31416 | 31433 | { "HeapValidate", (SYSCALL)HeapValidate, 0 }, |
| 31417 | 31434 | #else |
| 31418 | 31435 | { "HeapValidate", (SYSCALL)0, 0 }, |
| 31419 | 31436 | #endif |
| 31420 | 31437 | |
| 31421 | 31438 | #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ |
| 31422 | | - LPCVOID))aSyscall[41].pCurrent) |
| 31439 | + LPCVOID))aSyscall[42].pCurrent) |
| 31423 | 31440 | |
| 31424 | 31441 | #if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 31425 | 31442 | { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, |
| 31426 | 31443 | #else |
| 31427 | 31444 | { "LoadLibraryA", (SYSCALL)0, 0 }, |
| 31428 | 31445 | #endif |
| 31429 | 31446 | |
| 31430 | | -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent) |
| 31447 | +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[43].pCurrent) |
| 31431 | 31448 | |
| 31432 | 31449 | #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
| 31433 | 31450 | !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 31434 | 31451 | { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, |
| 31435 | 31452 | #else |
| 31436 | 31453 | { "LoadLibraryW", (SYSCALL)0, 0 }, |
| 31437 | 31454 | #endif |
| 31438 | 31455 | |
| 31439 | | -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent) |
| 31456 | +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[44].pCurrent) |
| 31440 | 31457 | |
| 31441 | 31458 | #if !SQLITE_OS_WINRT |
| 31442 | 31459 | { "LocalFree", (SYSCALL)LocalFree, 0 }, |
| 31443 | 31460 | #else |
| 31444 | 31461 | { "LocalFree", (SYSCALL)0, 0 }, |
| 31445 | 31462 | #endif |
| 31446 | 31463 | |
| 31447 | | -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent) |
| 31464 | +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[45].pCurrent) |
| 31448 | 31465 | |
| 31449 | 31466 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 31450 | 31467 | { "LockFile", (SYSCALL)LockFile, 0 }, |
| 31451 | 31468 | #else |
| 31452 | 31469 | { "LockFile", (SYSCALL)0, 0 }, |
| 31453 | 31470 | #endif |
| 31454 | 31471 | |
| 31455 | 31472 | #ifndef osLockFile |
| 31456 | 31473 | #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 31457 | | - DWORD))aSyscall[45].pCurrent) |
| 31474 | + DWORD))aSyscall[46].pCurrent) |
| 31458 | 31475 | #endif |
| 31459 | 31476 | |
| 31460 | 31477 | #if !SQLITE_OS_WINCE |
| 31461 | 31478 | { "LockFileEx", (SYSCALL)LockFileEx, 0 }, |
| 31462 | 31479 | #else |
| | @@ -31463,218 +31480,218 @@ |
| 31463 | 31480 | { "LockFileEx", (SYSCALL)0, 0 }, |
| 31464 | 31481 | #endif |
| 31465 | 31482 | |
| 31466 | 31483 | #ifndef osLockFileEx |
| 31467 | 31484 | #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 31468 | | - LPOVERLAPPED))aSyscall[46].pCurrent) |
| 31485 | + LPOVERLAPPED))aSyscall[47].pCurrent) |
| 31469 | 31486 | #endif |
| 31470 | 31487 | |
| 31471 | 31488 | #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) |
| 31472 | 31489 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 31473 | 31490 | #else |
| 31474 | 31491 | { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 31475 | 31492 | #endif |
| 31476 | 31493 | |
| 31477 | 31494 | #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 31478 | | - SIZE_T))aSyscall[47].pCurrent) |
| 31495 | + SIZE_T))aSyscall[48].pCurrent) |
| 31479 | 31496 | |
| 31480 | 31497 | { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, |
| 31481 | 31498 | |
| 31482 | 31499 | #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ |
| 31483 | | - int))aSyscall[48].pCurrent) |
| 31500 | + int))aSyscall[49].pCurrent) |
| 31484 | 31501 | |
| 31485 | 31502 | { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, |
| 31486 | 31503 | |
| 31487 | 31504 | #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ |
| 31488 | | - LARGE_INTEGER*))aSyscall[49].pCurrent) |
| 31505 | + LARGE_INTEGER*))aSyscall[50].pCurrent) |
| 31489 | 31506 | |
| 31490 | 31507 | { "ReadFile", (SYSCALL)ReadFile, 0 }, |
| 31491 | 31508 | |
| 31492 | 31509 | #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ |
| 31493 | | - LPOVERLAPPED))aSyscall[50].pCurrent) |
| 31510 | + LPOVERLAPPED))aSyscall[51].pCurrent) |
| 31494 | 31511 | |
| 31495 | 31512 | { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, |
| 31496 | 31513 | |
| 31497 | | -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent) |
| 31514 | +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent) |
| 31498 | 31515 | |
| 31499 | 31516 | #if !SQLITE_OS_WINRT |
| 31500 | 31517 | { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, |
| 31501 | 31518 | #else |
| 31502 | 31519 | { "SetFilePointer", (SYSCALL)0, 0 }, |
| 31503 | 31520 | #endif |
| 31504 | 31521 | |
| 31505 | 31522 | #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ |
| 31506 | | - DWORD))aSyscall[52].pCurrent) |
| 31523 | + DWORD))aSyscall[53].pCurrent) |
| 31507 | 31524 | |
| 31508 | 31525 | #if !SQLITE_OS_WINRT |
| 31509 | 31526 | { "Sleep", (SYSCALL)Sleep, 0 }, |
| 31510 | 31527 | #else |
| 31511 | 31528 | { "Sleep", (SYSCALL)0, 0 }, |
| 31512 | 31529 | #endif |
| 31513 | 31530 | |
| 31514 | | -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent) |
| 31531 | +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[54].pCurrent) |
| 31515 | 31532 | |
| 31516 | 31533 | { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, |
| 31517 | 31534 | |
| 31518 | 31535 | #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ |
| 31519 | | - LPFILETIME))aSyscall[54].pCurrent) |
| 31536 | + LPFILETIME))aSyscall[55].pCurrent) |
| 31520 | 31537 | |
| 31521 | 31538 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 31522 | 31539 | { "UnlockFile", (SYSCALL)UnlockFile, 0 }, |
| 31523 | 31540 | #else |
| 31524 | 31541 | { "UnlockFile", (SYSCALL)0, 0 }, |
| 31525 | 31542 | #endif |
| 31526 | 31543 | |
| 31527 | 31544 | #ifndef osUnlockFile |
| 31528 | 31545 | #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 31529 | | - DWORD))aSyscall[55].pCurrent) |
| 31546 | + DWORD))aSyscall[56].pCurrent) |
| 31530 | 31547 | #endif |
| 31531 | 31548 | |
| 31532 | 31549 | #if !SQLITE_OS_WINCE |
| 31533 | 31550 | { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, |
| 31534 | 31551 | #else |
| 31535 | 31552 | { "UnlockFileEx", (SYSCALL)0, 0 }, |
| 31536 | 31553 | #endif |
| 31537 | 31554 | |
| 31538 | 31555 | #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 31539 | | - LPOVERLAPPED))aSyscall[56].pCurrent) |
| 31556 | + LPOVERLAPPED))aSyscall[57].pCurrent) |
| 31540 | 31557 | |
| 31541 | 31558 | #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) |
| 31542 | 31559 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 31543 | 31560 | #else |
| 31544 | 31561 | { "UnmapViewOfFile", (SYSCALL)0, 0 }, |
| 31545 | 31562 | #endif |
| 31546 | 31563 | |
| 31547 | | -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent) |
| 31564 | +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[58].pCurrent) |
| 31548 | 31565 | |
| 31549 | 31566 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 31550 | 31567 | |
| 31551 | 31568 | #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ |
| 31552 | | - LPCSTR,LPBOOL))aSyscall[58].pCurrent) |
| 31569 | + LPCSTR,LPBOOL))aSyscall[59].pCurrent) |
| 31553 | 31570 | |
| 31554 | 31571 | { "WriteFile", (SYSCALL)WriteFile, 0 }, |
| 31555 | 31572 | |
| 31556 | 31573 | #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ |
| 31557 | | - LPOVERLAPPED))aSyscall[59].pCurrent) |
| 31574 | + LPOVERLAPPED))aSyscall[60].pCurrent) |
| 31558 | 31575 | |
| 31559 | 31576 | #if SQLITE_OS_WINRT |
| 31560 | 31577 | { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, |
| 31561 | 31578 | #else |
| 31562 | 31579 | { "CreateEventExW", (SYSCALL)0, 0 }, |
| 31563 | 31580 | #endif |
| 31564 | 31581 | |
| 31565 | 31582 | #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ |
| 31566 | | - DWORD,DWORD))aSyscall[60].pCurrent) |
| 31583 | + DWORD,DWORD))aSyscall[61].pCurrent) |
| 31567 | 31584 | |
| 31568 | 31585 | #if !SQLITE_OS_WINRT |
| 31569 | 31586 | { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, |
| 31570 | 31587 | #else |
| 31571 | 31588 | { "WaitForSingleObject", (SYSCALL)0, 0 }, |
| 31572 | 31589 | #endif |
| 31573 | 31590 | |
| 31574 | 31591 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 31575 | | - DWORD))aSyscall[61].pCurrent) |
| 31592 | + DWORD))aSyscall[62].pCurrent) |
| 31576 | 31593 | |
| 31577 | 31594 | #if SQLITE_OS_WINRT |
| 31578 | 31595 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 31579 | 31596 | #else |
| 31580 | 31597 | { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 31581 | 31598 | #endif |
| 31582 | 31599 | |
| 31583 | 31600 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 31584 | | - BOOL))aSyscall[62].pCurrent) |
| 31601 | + BOOL))aSyscall[63].pCurrent) |
| 31585 | 31602 | |
| 31586 | 31603 | #if SQLITE_OS_WINRT |
| 31587 | 31604 | { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 31588 | 31605 | #else |
| 31589 | 31606 | { "SetFilePointerEx", (SYSCALL)0, 0 }, |
| 31590 | 31607 | #endif |
| 31591 | 31608 | |
| 31592 | 31609 | #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ |
| 31593 | | - PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent) |
| 31610 | + PLARGE_INTEGER,DWORD))aSyscall[64].pCurrent) |
| 31594 | 31611 | |
| 31595 | 31612 | #if SQLITE_OS_WINRT |
| 31596 | 31613 | { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, |
| 31597 | 31614 | #else |
| 31598 | 31615 | { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, |
| 31599 | 31616 | #endif |
| 31600 | 31617 | |
| 31601 | 31618 | #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ |
| 31602 | | - FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent) |
| 31619 | + FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[65].pCurrent) |
| 31603 | 31620 | |
| 31604 | 31621 | #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) |
| 31605 | 31622 | { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 31606 | 31623 | #else |
| 31607 | 31624 | { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 31608 | 31625 | #endif |
| 31609 | 31626 | |
| 31610 | 31627 | #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ |
| 31611 | | - SIZE_T))aSyscall[65].pCurrent) |
| 31628 | + SIZE_T))aSyscall[66].pCurrent) |
| 31612 | 31629 | |
| 31613 | 31630 | #if SQLITE_OS_WINRT |
| 31614 | 31631 | { "CreateFile2", (SYSCALL)CreateFile2, 0 }, |
| 31615 | 31632 | #else |
| 31616 | 31633 | { "CreateFile2", (SYSCALL)0, 0 }, |
| 31617 | 31634 | #endif |
| 31618 | 31635 | |
| 31619 | 31636 | #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ |
| 31620 | | - LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent) |
| 31637 | + LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[67].pCurrent) |
| 31621 | 31638 | |
| 31622 | 31639 | #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 31623 | 31640 | { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, |
| 31624 | 31641 | #else |
| 31625 | 31642 | { "LoadPackagedLibrary", (SYSCALL)0, 0 }, |
| 31626 | 31643 | #endif |
| 31627 | 31644 | |
| 31628 | 31645 | #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ |
| 31629 | | - DWORD))aSyscall[67].pCurrent) |
| 31646 | + DWORD))aSyscall[68].pCurrent) |
| 31630 | 31647 | |
| 31631 | 31648 | #if SQLITE_OS_WINRT |
| 31632 | 31649 | { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, |
| 31633 | 31650 | #else |
| 31634 | 31651 | { "GetTickCount64", (SYSCALL)0, 0 }, |
| 31635 | 31652 | #endif |
| 31636 | 31653 | |
| 31637 | | -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent) |
| 31654 | +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[69].pCurrent) |
| 31638 | 31655 | |
| 31639 | 31656 | #if SQLITE_OS_WINRT |
| 31640 | 31657 | { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, |
| 31641 | 31658 | #else |
| 31642 | 31659 | { "GetNativeSystemInfo", (SYSCALL)0, 0 }, |
| 31643 | 31660 | #endif |
| 31644 | 31661 | |
| 31645 | 31662 | #define osGetNativeSystemInfo ((VOID(WINAPI*)( \ |
| 31646 | | - LPSYSTEM_INFO))aSyscall[69].pCurrent) |
| 31663 | + LPSYSTEM_INFO))aSyscall[70].pCurrent) |
| 31647 | 31664 | |
| 31648 | 31665 | #if defined(SQLITE_WIN32_HAS_ANSI) |
| 31649 | 31666 | { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, |
| 31650 | 31667 | #else |
| 31651 | 31668 | { "OutputDebugStringA", (SYSCALL)0, 0 }, |
| 31652 | 31669 | #endif |
| 31653 | 31670 | |
| 31654 | | -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent) |
| 31671 | +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[71].pCurrent) |
| 31655 | 31672 | |
| 31656 | 31673 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 31657 | 31674 | { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, |
| 31658 | 31675 | #else |
| 31659 | 31676 | { "OutputDebugStringW", (SYSCALL)0, 0 }, |
| 31660 | 31677 | #endif |
| 31661 | 31678 | |
| 31662 | | -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent) |
| 31679 | +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[72].pCurrent) |
| 31663 | 31680 | |
| 31664 | 31681 | { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 31665 | 31682 | |
| 31666 | | -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent) |
| 31683 | +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[73].pCurrent) |
| 31667 | 31684 | |
| 31668 | 31685 | #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) |
| 31669 | 31686 | { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, |
| 31670 | 31687 | #else |
| 31671 | 31688 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 31672 | 31689 | #endif |
| 31673 | 31690 | |
| 31674 | 31691 | #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ |
| 31675 | | - LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent) |
| 31692 | + LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[74].pCurrent) |
| 31676 | 31693 | |
| 31677 | 31694 | }; /* End of the overrideable system calls */ |
| 31678 | 31695 | |
| 31679 | 31696 | /* |
| 31680 | 31697 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -31826,20 +31843,30 @@ |
| 31826 | 31843 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 31827 | 31844 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31828 | 31845 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31829 | 31846 | ** the LockFileEx() API. |
| 31830 | 31847 | */ |
| 31848 | +#ifndef NTDDI_WIN8 |
| 31849 | +# define NTDDI_WIN8 0x06020000 |
| 31850 | +#endif |
| 31851 | + |
| 31831 | 31852 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 31832 | 31853 | # define osIsNT() (1) |
| 31833 | 31854 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31834 | 31855 | # define osIsNT() (0) |
| 31835 | 31856 | #else |
| 31836 | 31857 | static int osIsNT(void){ |
| 31837 | 31858 | if( sqlite3_os_type==0 ){ |
| 31859 | +#if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8 |
| 31860 | + OSVERSIONINFOW sInfo; |
| 31861 | + sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31862 | + osGetVersionExW(&sInfo); |
| 31863 | +#else |
| 31838 | 31864 | OSVERSIONINFOA sInfo; |
| 31839 | 31865 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31840 | 31866 | osGetVersionExA(&sInfo); |
| 31867 | +#endif |
| 31841 | 31868 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 31842 | 31869 | } |
| 31843 | 31870 | return sqlite3_os_type==2; |
| 31844 | 31871 | } |
| 31845 | 31872 | #endif |
| | @@ -31860,11 +31887,11 @@ |
| 31860 | 31887 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 31861 | 31888 | #endif |
| 31862 | 31889 | assert( nBytes>=0 ); |
| 31863 | 31890 | p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); |
| 31864 | 31891 | if( !p ){ |
| 31865 | | - sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p", |
| 31892 | + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", |
| 31866 | 31893 | nBytes, osGetLastError(), (void*)hHeap); |
| 31867 | 31894 | } |
| 31868 | 31895 | return p; |
| 31869 | 31896 | } |
| 31870 | 31897 | |
| | @@ -31881,11 +31908,11 @@ |
| 31881 | 31908 | #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 31882 | 31909 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); |
| 31883 | 31910 | #endif |
| 31884 | 31911 | if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ |
| 31885 | 31912 | if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ |
| 31886 | | - sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p", |
| 31913 | + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", |
| 31887 | 31914 | pPrior, osGetLastError(), (void*)hHeap); |
| 31888 | 31915 | } |
| 31889 | 31916 | } |
| 31890 | 31917 | |
| 31891 | 31918 | /* |
| | @@ -31907,11 +31934,11 @@ |
| 31907 | 31934 | p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); |
| 31908 | 31935 | }else{ |
| 31909 | 31936 | p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); |
| 31910 | 31937 | } |
| 31911 | 31938 | if( !p ){ |
| 31912 | | - sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p", |
| 31939 | + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", |
| 31913 | 31940 | pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), |
| 31914 | 31941 | (void*)hHeap); |
| 31915 | 31942 | } |
| 31916 | 31943 | return p; |
| 31917 | 31944 | } |
| | @@ -31931,11 +31958,11 @@ |
| 31931 | 31958 | assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 31932 | 31959 | #endif |
| 31933 | 31960 | if( !p ) return 0; |
| 31934 | 31961 | n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); |
| 31935 | 31962 | if( n==(SIZE_T)-1 ){ |
| 31936 | | - sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p", |
| 31963 | + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", |
| 31937 | 31964 | p, osGetLastError(), (void*)hHeap); |
| 31938 | 31965 | return 0; |
| 31939 | 31966 | } |
| 31940 | 31967 | return (int)n; |
| 31941 | 31968 | } |
| | @@ -31961,11 +31988,11 @@ |
| 31961 | 31988 | pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, |
| 31962 | 31989 | SQLITE_WIN32_HEAP_INIT_SIZE, |
| 31963 | 31990 | SQLITE_WIN32_HEAP_MAX_SIZE); |
| 31964 | 31991 | if( !pWinMemData->hHeap ){ |
| 31965 | 31992 | sqlite3_log(SQLITE_NOMEM, |
| 31966 | | - "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u", |
| 31993 | + "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u", |
| 31967 | 31994 | osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, |
| 31968 | 31995 | SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); |
| 31969 | 31996 | return SQLITE_NOMEM; |
| 31970 | 31997 | } |
| 31971 | 31998 | pWinMemData->bOwned = TRUE; |
| | @@ -31973,11 +32000,11 @@ |
| 31973 | 32000 | } |
| 31974 | 32001 | #else |
| 31975 | 32002 | pWinMemData->hHeap = osGetProcessHeap(); |
| 31976 | 32003 | if( !pWinMemData->hHeap ){ |
| 31977 | 32004 | sqlite3_log(SQLITE_NOMEM, |
| 31978 | | - "failed to GetProcessHeap (%d)", osGetLastError()); |
| 32005 | + "failed to GetProcessHeap (%lu)", osGetLastError()); |
| 31979 | 32006 | return SQLITE_NOMEM; |
| 31980 | 32007 | } |
| 31981 | 32008 | pWinMemData->bOwned = FALSE; |
| 31982 | 32009 | assert( !pWinMemData->bOwned ); |
| 31983 | 32010 | #endif |
| | @@ -32001,11 +32028,11 @@ |
| 32001 | 32028 | #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) |
| 32002 | 32029 | assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); |
| 32003 | 32030 | #endif |
| 32004 | 32031 | if( pWinMemData->bOwned ){ |
| 32005 | 32032 | if( !osHeapDestroy(pWinMemData->hHeap) ){ |
| 32006 | | - sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p", |
| 32033 | + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", |
| 32007 | 32034 | osGetLastError(), (void*)pWinMemData->hHeap); |
| 32008 | 32035 | } |
| 32009 | 32036 | pWinMemData->bOwned = FALSE; |
| 32010 | 32037 | } |
| 32011 | 32038 | pWinMemData->hHeap = NULL; |
| | @@ -33886,26 +33913,27 @@ |
| 33886 | 33913 | ** by VFS shared-memory methods. |
| 33887 | 33914 | */ |
| 33888 | 33915 | static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ |
| 33889 | 33916 | winShmNode **pp; |
| 33890 | 33917 | winShmNode *p; |
| 33891 | | - BOOL bRc; |
| 33892 | 33918 | assert( winShmMutexHeld() ); |
| 33893 | 33919 | OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", |
| 33894 | 33920 | osGetCurrentProcessId(), deleteFlag)); |
| 33895 | 33921 | pp = &winShmNodeList; |
| 33896 | 33922 | while( (p = *pp)!=0 ){ |
| 33897 | 33923 | if( p->nRef==0 ){ |
| 33898 | 33924 | int i; |
| 33899 | 33925 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 33900 | 33926 | for(i=0; i<p->nRegion; i++){ |
| 33901 | | - bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 33927 | + BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 33902 | 33928 | OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", |
| 33903 | 33929 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); |
| 33930 | + UNUSED_VARIABLE_VALUE(bRc); |
| 33904 | 33931 | bRc = osCloseHandle(p->aRegion[i].hMap); |
| 33905 | 33932 | OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", |
| 33906 | 33933 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); |
| 33934 | + UNUSED_VARIABLE_VALUE(bRc); |
| 33907 | 33935 | } |
| 33908 | 33936 | if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ |
| 33909 | 33937 | SimulateIOErrorBenign(1); |
| 33910 | 33938 | winClose((sqlite3_file *)&p->hFile); |
| 33911 | 33939 | SimulateIOErrorBenign(0); |
| | @@ -34620,10 +34648,11 @@ |
| 34620 | 34648 | ** |
| 34621 | 34649 | ** This division contains the implementation of methods on the |
| 34622 | 34650 | ** sqlite3_vfs object. |
| 34623 | 34651 | */ |
| 34624 | 34652 | |
| 34653 | +#if 0 |
| 34625 | 34654 | /* |
| 34626 | 34655 | ** Convert a filename from whatever the underlying operating system |
| 34627 | 34656 | ** supports for filenames into UTF-8. Space to hold the result is |
| 34628 | 34657 | ** obtained from malloc and must be freed by the calling function. |
| 34629 | 34658 | */ |
| | @@ -34638,10 +34667,11 @@ |
| 34638 | 34667 | } |
| 34639 | 34668 | #endif |
| 34640 | 34669 | /* caller will handle out of memory */ |
| 34641 | 34670 | return zConverted; |
| 34642 | 34671 | } |
| 34672 | +#endif |
| 34643 | 34673 | |
| 34644 | 34674 | /* |
| 34645 | 34675 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34646 | 34676 | ** operating system wants filenames in. Space to hold the result |
| 34647 | 34677 | ** is obtained from malloc and must be freed by the calling |
| | @@ -35855,11 +35885,11 @@ |
| 35855 | 35885 | }; |
| 35856 | 35886 | #endif |
| 35857 | 35887 | |
| 35858 | 35888 | /* Double-check that the aSyscall[] array has been constructed |
| 35859 | 35889 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35860 | | - assert( ArraySize(aSyscall)==74 ); |
| 35890 | + assert( ArraySize(aSyscall)==75 ); |
| 35861 | 35891 | |
| 35862 | 35892 | /* get memory map allocation granularity */ |
| 35863 | 35893 | memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); |
| 35864 | 35894 | #if SQLITE_OS_WINRT |
| 35865 | 35895 | osGetNativeSystemInfo(&winSysInfo); |
| | @@ -60404,10 +60434,12 @@ |
| 60404 | 60434 | int iVal, /* Array element to populate */ |
| 60405 | 60435 | int *pbOk /* OUT: True if value was extracted */ |
| 60406 | 60436 | ){ |
| 60407 | 60437 | int rc = SQLITE_OK; |
| 60408 | 60438 | sqlite3_value *pVal = 0; |
| 60439 | + sqlite3 *db = pParse->db; |
| 60440 | + |
| 60409 | 60441 | |
| 60410 | 60442 | struct ValueNewStat4Ctx alloc; |
| 60411 | 60443 | alloc.pParse = pParse; |
| 60412 | 60444 | alloc.pIdx = pIdx; |
| 60413 | 60445 | alloc.ppRec = ppRec; |
| | @@ -60415,11 +60447,11 @@ |
| 60415 | 60447 | |
| 60416 | 60448 | /* Skip over any TK_COLLATE nodes */ |
| 60417 | 60449 | pExpr = sqlite3ExprSkipCollate(pExpr); |
| 60418 | 60450 | |
| 60419 | 60451 | if( !pExpr ){ |
| 60420 | | - pVal = valueNew(pParse->db, &alloc); |
| 60452 | + pVal = valueNew(db, &alloc); |
| 60421 | 60453 | if( pVal ){ |
| 60422 | 60454 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60423 | 60455 | *pbOk = 1; |
| 60424 | 60456 | } |
| 60425 | 60457 | }else if( pExpr->op==TK_VARIABLE |
| | @@ -60427,30 +60459,29 @@ |
| 60427 | 60459 | ){ |
| 60428 | 60460 | Vdbe *v; |
| 60429 | 60461 | int iBindVar = pExpr->iColumn; |
| 60430 | 60462 | sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); |
| 60431 | 60463 | if( (v = pParse->pReprepare)!=0 ){ |
| 60432 | | - pVal = valueNew(pParse->db, &alloc); |
| 60464 | + pVal = valueNew(db, &alloc); |
| 60433 | 60465 | if( pVal ){ |
| 60434 | 60466 | rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); |
| 60435 | 60467 | if( rc==SQLITE_OK ){ |
| 60436 | | - sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 60468 | + sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); |
| 60437 | 60469 | } |
| 60438 | 60470 | pVal->db = pParse->db; |
| 60439 | 60471 | *pbOk = 1; |
| 60440 | 60472 | sqlite3VdbeMemStoreType((Mem*)pVal); |
| 60441 | 60473 | } |
| 60442 | 60474 | }else{ |
| 60443 | 60475 | *pbOk = 0; |
| 60444 | 60476 | } |
| 60445 | 60477 | }else{ |
| 60446 | | - sqlite3 *db = pParse->db; |
| 60447 | 60478 | rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); |
| 60448 | 60479 | *pbOk = (pVal!=0); |
| 60449 | 60480 | } |
| 60450 | 60481 | |
| 60451 | | - assert( pVal==0 || pVal->db==pParse->db ); |
| 60482 | + assert( pVal==0 || pVal->db==db ); |
| 60452 | 60483 | return rc; |
| 60453 | 60484 | } |
| 60454 | 60485 | |
| 60455 | 60486 | /* |
| 60456 | 60487 | ** Unless it is NULL, the argument must be an UnpackedRecord object returned |
| | @@ -61114,11 +61145,11 @@ |
| 61114 | 61145 | /* |
| 61115 | 61146 | ** If the input FuncDef structure is ephemeral, then free it. If |
| 61116 | 61147 | ** the FuncDef is not ephermal, then do nothing. |
| 61117 | 61148 | */ |
| 61118 | 61149 | static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ |
| 61119 | | - if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ |
| 61150 | + if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ |
| 61120 | 61151 | sqlite3DbFree(db, pDef); |
| 61121 | 61152 | } |
| 61122 | 61153 | } |
| 61123 | 61154 | |
| 61124 | 61155 | static void vdbeFreeOpArray(sqlite3 *, Op *, int); |
| | @@ -64341,10 +64372,11 @@ |
| 64341 | 64372 | } |
| 64342 | 64373 | rc = sqlite3ApiExit(db, rc); |
| 64343 | 64374 | sqlite3_mutex_leave(db->mutex); |
| 64344 | 64375 | return rc; |
| 64345 | 64376 | } |
| 64377 | + |
| 64346 | 64378 | |
| 64347 | 64379 | /* |
| 64348 | 64380 | ** Extract the user data from a sqlite3_context structure and return a |
| 64349 | 64381 | ** pointer to it. |
| 64350 | 64382 | */ |
| | @@ -64365,10 +64397,23 @@ |
| 64365 | 64397 | */ |
| 64366 | 64398 | SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ |
| 64367 | 64399 | assert( p && p->pFunc ); |
| 64368 | 64400 | return p->s.db; |
| 64369 | 64401 | } |
| 64402 | + |
| 64403 | +/* |
| 64404 | +** Return the current time for a statement |
| 64405 | +*/ |
| 64406 | +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ |
| 64407 | + Vdbe *v = p->pVdbe; |
| 64408 | + int rc; |
| 64409 | + if( v->iCurrentTime==0 ){ |
| 64410 | + rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime); |
| 64411 | + if( rc ) v->iCurrentTime = 0; |
| 64412 | + } |
| 64413 | + return v->iCurrentTime; |
| 64414 | +} |
| 64370 | 64415 | |
| 64371 | 64416 | /* |
| 64372 | 64417 | ** The following is the implementation of an SQL function that always |
| 64373 | 64418 | ** fails with an error message stating that the function is used in the |
| 64374 | 64419 | ** wrong context. The sqlite3_overload_function() API might construct |
| | @@ -66518,10 +66563,11 @@ |
| 66518 | 66563 | goto no_mem; |
| 66519 | 66564 | } |
| 66520 | 66565 | assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); |
| 66521 | 66566 | assert( p->bIsReader || p->readOnly!=0 ); |
| 66522 | 66567 | p->rc = SQLITE_OK; |
| 66568 | + p->iCurrentTime = 0; |
| 66523 | 66569 | assert( p->explain==0 ); |
| 66524 | 66570 | p->pResultSet = 0; |
| 66525 | 66571 | db->busyHandler.nBusy = 0; |
| 66526 | 66572 | CHECK_FOR_INTERRUPT; |
| 66527 | 66573 | sqlite3VdbeIOTraceSql(p); |
| | @@ -67406,11 +67452,11 @@ |
| 67406 | 67452 | */ |
| 67407 | 67453 | sqlite3VdbeMemMove(&u.ai.ctx.s, pOut); |
| 67408 | 67454 | MemSetTypeFlag(&u.ai.ctx.s, MEM_Null); |
| 67409 | 67455 | |
| 67410 | 67456 | u.ai.ctx.fErrorOrAux = 0; |
| 67411 | | - if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 67457 | + if( u.ai.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 67412 | 67458 | assert( pOp>aOp ); |
| 67413 | 67459 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 67414 | 67460 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 67415 | 67461 | u.ai.ctx.pColl = pOp[-1].p4.pColl; |
| 67416 | 67462 | } |
| | @@ -71506,11 +71552,11 @@ |
| 71506 | 71552 | u.cg.ctx.s.xDel = 0; |
| 71507 | 71553 | u.cg.ctx.s.db = db; |
| 71508 | 71554 | u.cg.ctx.isError = 0; |
| 71509 | 71555 | u.cg.ctx.pColl = 0; |
| 71510 | 71556 | u.cg.ctx.skipFlag = 0; |
| 71511 | | - if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 71557 | + if( u.cg.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 71512 | 71558 | assert( pOp>p->aOp ); |
| 71513 | 71559 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 71514 | 71560 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 71515 | 71561 | u.cg.ctx.pColl = pOp[-1].p4.pColl; |
| 71516 | 71562 | } |
| | @@ -74434,11 +74480,11 @@ |
| 74434 | 74480 | if( pExpr==0 ) return WRC_Continue; |
| 74435 | 74481 | testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); |
| 74436 | 74482 | testcase( ExprHasProperty(pExpr, EP_Reduced) ); |
| 74437 | 74483 | rc = pWalker->xExprCallback(pWalker, pExpr); |
| 74438 | 74484 | if( rc==WRC_Continue |
| 74439 | | - && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){ |
| 74485 | + && !ExprHasProperty(pExpr,EP_TokenOnly) ){ |
| 74440 | 74486 | if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; |
| 74441 | 74487 | if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; |
| 74442 | 74488 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 74443 | 74489 | if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; |
| 74444 | 74490 | }else{ |
| | @@ -74653,10 +74699,11 @@ |
| 74653 | 74699 | if( pDup==0 ) return; |
| 74654 | 74700 | if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ |
| 74655 | 74701 | incrAggFunctionDepth(pDup, nSubquery); |
| 74656 | 74702 | pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); |
| 74657 | 74703 | if( pDup==0 ) return; |
| 74704 | + ExprSetProperty(pDup, EP_Skip); |
| 74658 | 74705 | if( pEList->a[iCol].iAlias==0 ){ |
| 74659 | 74706 | pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); |
| 74660 | 74707 | } |
| 74661 | 74708 | pDup->iTable = pEList->a[iCol].iAlias; |
| 74662 | 74709 | } |
| | @@ -74675,11 +74722,11 @@ |
| 74675 | 74722 | sqlite3ExprDelete(db, pExpr); |
| 74676 | 74723 | memcpy(pExpr, pDup, sizeof(*pExpr)); |
| 74677 | 74724 | if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ |
| 74678 | 74725 | assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); |
| 74679 | 74726 | pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); |
| 74680 | | - pExpr->flags2 |= EP2_MallocedToken; |
| 74727 | + pExpr->flags |= EP_MemToken; |
| 74681 | 74728 | } |
| 74682 | 74729 | sqlite3DbFree(db, pDup); |
| 74683 | 74730 | } |
| 74684 | 74731 | |
| 74685 | 74732 | |
| | @@ -74775,16 +74822,16 @@ |
| 74775 | 74822 | Schema *pSchema = 0; /* Schema of the expression */ |
| 74776 | 74823 | int isTrigger = 0; |
| 74777 | 74824 | |
| 74778 | 74825 | assert( pNC ); /* the name context cannot be NULL. */ |
| 74779 | 74826 | assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ |
| 74780 | | - assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 74827 | + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 74781 | 74828 | |
| 74782 | 74829 | /* Initialize the node to no-match */ |
| 74783 | 74830 | pExpr->iTable = -1; |
| 74784 | 74831 | pExpr->pTab = 0; |
| 74785 | | - ExprSetIrreducible(pExpr); |
| 74832 | + ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 74786 | 74833 | |
| 74787 | 74834 | /* Translate the schema name in zDb into a pointer to the corresponding |
| 74788 | 74835 | ** schema. If not found, pSchema will remain NULL and nothing will match |
| 74789 | 74836 | ** resulting in an appropriate error message toward the end of this routine |
| 74790 | 74837 | */ |
| | @@ -75116,10 +75163,23 @@ |
| 75116 | 75163 | } |
| 75117 | 75164 | #else |
| 75118 | 75165 | # define notValidCheckConstraint(P,N,M) |
| 75119 | 75166 | #endif |
| 75120 | 75167 | |
| 75168 | +/* |
| 75169 | +** Expression p should encode a floating point value between 1.0 and 0.0. |
| 75170 | +** Return 1024 times this value. Or return -1 if p is not a floating point |
| 75171 | +** value between 1.0 and 0.0. |
| 75172 | +*/ |
| 75173 | +static int exprProbability(Expr *p){ |
| 75174 | + double r = -1.0; |
| 75175 | + if( p->op!=TK_FLOAT ) return -1; |
| 75176 | + sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); |
| 75177 | + assert( r>=0.0 ); |
| 75178 | + if( r>1.0 ) return -1; |
| 75179 | + return (int)(r*1000.0); |
| 75180 | +} |
| 75121 | 75181 | |
| 75122 | 75182 | /* |
| 75123 | 75183 | ** This routine is callback for sqlite3WalkExpr(). |
| 75124 | 75184 | ** |
| 75125 | 75185 | ** Resolve symbolic names into TK_COLUMN operators for the current |
| | @@ -75137,11 +75197,11 @@ |
| 75137 | 75197 | pNC = pWalker->u.pNC; |
| 75138 | 75198 | assert( pNC!=0 ); |
| 75139 | 75199 | pParse = pNC->pParse; |
| 75140 | 75200 | assert( pParse==pWalker->pParse ); |
| 75141 | 75201 | |
| 75142 | | - if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune; |
| 75202 | + if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune; |
| 75143 | 75203 | ExprSetProperty(pExpr, EP_Resolved); |
| 75144 | 75204 | #ifndef NDEBUG |
| 75145 | 75205 | if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ |
| 75146 | 75206 | SrcList *pSrcList = pNC->pSrcList; |
| 75147 | 75207 | int i; |
| | @@ -75229,10 +75289,23 @@ |
| 75229 | 75289 | }else{ |
| 75230 | 75290 | wrong_num_args = 1; |
| 75231 | 75291 | } |
| 75232 | 75292 | }else{ |
| 75233 | 75293 | is_agg = pDef->xFunc==0; |
| 75294 | + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ |
| 75295 | + ExprSetProperty(pExpr, EP_Unlikely|EP_Skip); |
| 75296 | + if( n==2 ){ |
| 75297 | + pExpr->iTable = exprProbability(pList->a[1].pExpr); |
| 75298 | + if( pExpr->iTable<0 ){ |
| 75299 | + sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a " |
| 75300 | + "constant between 0.0 and 1.0"); |
| 75301 | + pNC->nErr++; |
| 75302 | + } |
| 75303 | + }else{ |
| 75304 | + pExpr->iTable = 62; /* TUNING: Default 2nd arg to unlikely() is 0.0625 */ |
| 75305 | + } |
| 75306 | + } |
| 75234 | 75307 | } |
| 75235 | 75308 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 75236 | 75309 | if( pDef ){ |
| 75237 | 75310 | auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); |
| 75238 | 75311 | if( auth!=SQLITE_OK ){ |
| | @@ -76038,11 +76111,11 @@ |
| 76038 | 76111 | SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){ |
| 76039 | 76112 | if( pCollName->n>0 ){ |
| 76040 | 76113 | Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); |
| 76041 | 76114 | if( pNew ){ |
| 76042 | 76115 | pNew->pLeft = pExpr; |
| 76043 | | - pNew->flags |= EP_Collate; |
| 76116 | + pNew->flags |= EP_Collate|EP_Skip; |
| 76044 | 76117 | pExpr = pNew; |
| 76045 | 76118 | } |
| 76046 | 76119 | } |
| 76047 | 76120 | return pExpr; |
| 76048 | 76121 | } |
| | @@ -76053,17 +76126,25 @@ |
| 76053 | 76126 | s.n = sqlite3Strlen30(s.z); |
| 76054 | 76127 | return sqlite3ExprAddCollateToken(pParse, pExpr, &s); |
| 76055 | 76128 | } |
| 76056 | 76129 | |
| 76057 | 76130 | /* |
| 76058 | | -** Skip over any TK_COLLATE and/or TK_AS operators at the root of |
| 76059 | | -** an expression. |
| 76131 | +** Skip over any TK_COLLATE or TK_AS operators and any unlikely() |
| 76132 | +** or likelihood() function at the root of an expression. |
| 76060 | 76133 | */ |
| 76061 | 76134 | SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ |
| 76062 | | - while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){ |
| 76063 | | - pExpr = pExpr->pLeft; |
| 76064 | | - } |
| 76135 | + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ |
| 76136 | + if( ExprHasProperty(pExpr, EP_Unlikely) ){ |
| 76137 | + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 76138 | + assert( pExpr->x.pList->nExpr>0 ); |
| 76139 | + assert( pExpr->op==TK_FUNCTION ); |
| 76140 | + pExpr = pExpr->x.pList->a[0].pExpr; |
| 76141 | + }else{ |
| 76142 | + assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS ); |
| 76143 | + pExpr = pExpr->pLeft; |
| 76144 | + } |
| 76145 | + } |
| 76065 | 76146 | return pExpr; |
| 76066 | 76147 | } |
| 76067 | 76148 | |
| 76068 | 76149 | /* |
| 76069 | 76150 | ** Return the collation sequence for the expression pExpr. If |
| | @@ -76564,11 +76645,11 @@ |
| 76564 | 76645 | SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ |
| 76565 | 76646 | sqlite3 *db = pParse->db; |
| 76566 | 76647 | const char *z; |
| 76567 | 76648 | |
| 76568 | 76649 | if( pExpr==0 ) return; |
| 76569 | | - assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); |
| 76650 | + assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); |
| 76570 | 76651 | z = pExpr->u.zToken; |
| 76571 | 76652 | assert( z!=0 ); |
| 76572 | 76653 | assert( z[0]!=0 ); |
| 76573 | 76654 | if( z[1]==0 ){ |
| 76574 | 76655 | /* Wildcard of the form "?". Assign the next variable number */ |
| | @@ -76634,16 +76715,16 @@ |
| 76634 | 76715 | */ |
| 76635 | 76716 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| 76636 | 76717 | if( p==0 ) return; |
| 76637 | 76718 | /* Sanity check: Assert that the IntValue is non-negative if it exists */ |
| 76638 | 76719 | assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); |
| 76639 | | - if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ |
| 76720 | + if( !ExprHasProperty(p, EP_TokenOnly) ){ |
| 76721 | + /* The Expr.x union is never used at the same time as Expr.pRight */ |
| 76722 | + assert( p->x.pList==0 || p->pRight==0 ); |
| 76640 | 76723 | sqlite3ExprDelete(db, p->pLeft); |
| 76641 | 76724 | sqlite3ExprDelete(db, p->pRight); |
| 76642 | | - if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){ |
| 76643 | | - sqlite3DbFree(db, p->u.zToken); |
| 76644 | | - } |
| 76725 | + if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); |
| 76645 | 76726 | if( ExprHasProperty(p, EP_xIsSelect) ){ |
| 76646 | 76727 | sqlite3SelectDelete(db, p->x.pSelect); |
| 76647 | 76728 | }else{ |
| 76648 | 76729 | sqlite3ExprListDelete(db, p->x.pList); |
| 76649 | 76730 | } |
| | @@ -76699,20 +76780,23 @@ |
| 76699 | 76780 | ** to enforce this constraint. |
| 76700 | 76781 | */ |
| 76701 | 76782 | static int dupedExprStructSize(Expr *p, int flags){ |
| 76702 | 76783 | int nSize; |
| 76703 | 76784 | assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ |
| 76785 | + assert( EXPR_FULLSIZE<=0xfff ); |
| 76786 | + assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); |
| 76704 | 76787 | if( 0==(flags&EXPRDUP_REDUCE) ){ |
| 76705 | 76788 | nSize = EXPR_FULLSIZE; |
| 76706 | 76789 | }else{ |
| 76707 | | - assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) ); |
| 76790 | + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); |
| 76708 | 76791 | assert( !ExprHasProperty(p, EP_FromJoin) ); |
| 76709 | | - assert( (p->flags2 & EP2_MallocedToken)==0 ); |
| 76710 | | - assert( (p->flags2 & EP2_Irreducible)==0 ); |
| 76711 | | - if( p->pLeft || p->pRight || p->x.pList ){ |
| 76792 | + assert( !ExprHasProperty(p, EP_MemToken) ); |
| 76793 | + assert( !ExprHasProperty(p, EP_NoReduce) ); |
| 76794 | + if( p->pLeft || p->x.pList ){ |
| 76712 | 76795 | nSize = EXPR_REDUCEDSIZE | EP_Reduced; |
| 76713 | 76796 | }else{ |
| 76797 | + assert( p->pRight==0 ); |
| 76714 | 76798 | nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; |
| 76715 | 76799 | } |
| 76716 | 76800 | } |
| 76717 | 76801 | return nSize; |
| 76718 | 76802 | } |
| | @@ -76802,11 +76886,11 @@ |
| 76802 | 76886 | memcpy(zAlloc, p, nSize); |
| 76803 | 76887 | memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); |
| 76804 | 76888 | } |
| 76805 | 76889 | |
| 76806 | 76890 | /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ |
| 76807 | | - pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); |
| 76891 | + pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); |
| 76808 | 76892 | pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); |
| 76809 | 76893 | pNew->flags |= staticFlag; |
| 76810 | 76894 | |
| 76811 | 76895 | /* Copy the p->u.zToken string, if any. */ |
| 76812 | 76896 | if( nToken ){ |
| | @@ -76822,22 +76906,21 @@ |
| 76822 | 76906 | pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced); |
| 76823 | 76907 | } |
| 76824 | 76908 | } |
| 76825 | 76909 | |
| 76826 | 76910 | /* Fill in pNew->pLeft and pNew->pRight. */ |
| 76827 | | - if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){ |
| 76911 | + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ |
| 76828 | 76912 | zAlloc += dupedExprNodeSize(p, flags); |
| 76829 | 76913 | if( ExprHasProperty(pNew, EP_Reduced) ){ |
| 76830 | 76914 | pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc); |
| 76831 | 76915 | pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc); |
| 76832 | 76916 | } |
| 76833 | 76917 | if( pzBuffer ){ |
| 76834 | 76918 | *pzBuffer = zAlloc; |
| 76835 | 76919 | } |
| 76836 | 76920 | }else{ |
| 76837 | | - pNew->flags2 = 0; |
| 76838 | | - if( !ExprHasAnyProperty(p, EP_TokenOnly) ){ |
| 76921 | + if( !ExprHasProperty(p, EP_TokenOnly) ){ |
| 76839 | 76922 | pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); |
| 76840 | 76923 | pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); |
| 76841 | 76924 | } |
| 76842 | 76925 | } |
| 76843 | 76926 | |
| | @@ -77143,11 +77226,11 @@ |
| 77143 | 77226 | static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ |
| 77144 | 77227 | |
| 77145 | 77228 | /* If pWalker->u.i is 3 then any term of the expression that comes from |
| 77146 | 77229 | ** the ON or USING clauses of a join disqualifies the expression |
| 77147 | 77230 | ** from being considered constant. */ |
| 77148 | | - if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){ |
| 77231 | + if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){ |
| 77149 | 77232 | pWalker->u.i = 0; |
| 77150 | 77233 | return WRC_Abort; |
| 77151 | 77234 | } |
| 77152 | 77235 | |
| 77153 | 77236 | switch( pExpr->op ){ |
| | @@ -77574,11 +77657,11 @@ |
| 77574 | 77657 | *prNotFound = rMayHaveNull = ++pParse->nMem; |
| 77575 | 77658 | sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); |
| 77576 | 77659 | }else{ |
| 77577 | 77660 | testcase( pParse->nQueryLoop>0 ); |
| 77578 | 77661 | pParse->nQueryLoop = 0; |
| 77579 | | - if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ |
| 77662 | + if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ |
| 77580 | 77663 | eType = IN_INDEX_ROWID; |
| 77581 | 77664 | } |
| 77582 | 77665 | } |
| 77583 | 77666 | sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); |
| 77584 | 77667 | pParse->nQueryLoop = savedNQueryLoop; |
| | @@ -77643,11 +77726,11 @@ |
| 77643 | 77726 | ** * We are inside a trigger |
| 77644 | 77727 | ** |
| 77645 | 77728 | ** If all of the above are false, then we can run this code just once |
| 77646 | 77729 | ** save the results, and reuse the same result on subsequent invocations. |
| 77647 | 77730 | */ |
| 77648 | | - if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){ |
| 77731 | + if( !ExprHasProperty(pExpr, EP_VarSelect) ){ |
| 77649 | 77732 | testAddr = sqlite3CodeOnce(pParse); |
| 77650 | 77733 | } |
| 77651 | 77734 | |
| 77652 | 77735 | #ifndef SQLITE_OMIT_EXPLAIN |
| 77653 | 77736 | if( pParse->explain==2 ){ |
| | @@ -77812,11 +77895,11 @@ |
| 77812 | 77895 | pSel->iLimit = 0; |
| 77813 | 77896 | if( sqlite3Select(pParse, pSel, &dest) ){ |
| 77814 | 77897 | return 0; |
| 77815 | 77898 | } |
| 77816 | 77899 | rReg = dest.iSDParm; |
| 77817 | | - ExprSetIrreducible(pExpr); |
| 77900 | + ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 77818 | 77901 | break; |
| 77819 | 77902 | } |
| 77820 | 77903 | } |
| 77821 | 77904 | |
| 77822 | 77905 | if( testAddr>=0 ){ |
| | @@ -78283,10 +78366,20 @@ |
| 78283 | 78366 | if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ |
| 78284 | 78367 | } |
| 78285 | 78368 | return 0; |
| 78286 | 78369 | } |
| 78287 | 78370 | #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ |
| 78371 | + |
| 78372 | +/* |
| 78373 | +** Convert an expression node to a TK_REGISTER |
| 78374 | +*/ |
| 78375 | +static void exprToRegister(Expr *p, int iReg){ |
| 78376 | + p->op2 = p->op; |
| 78377 | + p->op = TK_REGISTER; |
| 78378 | + p->iTable = iReg; |
| 78379 | + ExprClearProperty(p, EP_Skip); |
| 78380 | +} |
| 78288 | 78381 | |
| 78289 | 78382 | /* |
| 78290 | 78383 | ** Generate code into the current Vdbe to evaluate the given |
| 78291 | 78384 | ** expression. Attempt to store the results in register "target". |
| 78292 | 78385 | ** Return the register where results are stored. |
| | @@ -78583,11 +78676,11 @@ |
| 78583 | 78676 | CollSeq *pColl = 0; /* A collating sequence */ |
| 78584 | 78677 | |
| 78585 | 78678 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 78586 | 78679 | testcase( op==TK_CONST_FUNC ); |
| 78587 | 78680 | testcase( op==TK_FUNCTION ); |
| 78588 | | - if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ |
| 78681 | + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ |
| 78589 | 78682 | pFarg = 0; |
| 78590 | 78683 | }else{ |
| 78591 | 78684 | pFarg = pExpr->x.pList; |
| 78592 | 78685 | } |
| 78593 | 78686 | nFarg = pFarg ? pFarg->nExpr : 0; |
| | @@ -78602,11 +78695,11 @@ |
| 78602 | 78695 | |
| 78603 | 78696 | /* Attempt a direct implementation of the built-in COALESCE() and |
| 78604 | 78697 | ** IFNULL() functions. This avoids unnecessary evalation of |
| 78605 | 78698 | ** arguments past the first non-NULL argument. |
| 78606 | 78699 | */ |
| 78607 | | - if( pDef->flags & SQLITE_FUNC_COALESCE ){ |
| 78700 | + if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ |
| 78608 | 78701 | int endCoalesce = sqlite3VdbeMakeLabel(v); |
| 78609 | 78702 | assert( nFarg>=2 ); |
| 78610 | 78703 | sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); |
| 78611 | 78704 | for(i=1; i<nFarg; i++){ |
| 78612 | 78705 | sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce); |
| | @@ -78617,29 +78710,38 @@ |
| 78617 | 78710 | } |
| 78618 | 78711 | sqlite3VdbeResolveLabel(v, endCoalesce); |
| 78619 | 78712 | break; |
| 78620 | 78713 | } |
| 78621 | 78714 | |
| 78715 | + /* The UNLIKELY() function is a no-op. The result is the value |
| 78716 | + ** of the first argument. |
| 78717 | + */ |
| 78718 | + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ |
| 78719 | + assert( nFarg>=1 ); |
| 78720 | + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); |
| 78721 | + break; |
| 78722 | + } |
| 78622 | 78723 | |
| 78623 | 78724 | if( pFarg ){ |
| 78624 | 78725 | r1 = sqlite3GetTempRange(pParse, nFarg); |
| 78625 | 78726 | |
| 78626 | 78727 | /* For length() and typeof() functions with a column argument, |
| 78627 | 78728 | ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG |
| 78628 | 78729 | ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data |
| 78629 | 78730 | ** loading. |
| 78630 | 78731 | */ |
| 78631 | | - if( (pDef->flags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ |
| 78732 | + if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ |
| 78632 | 78733 | u8 exprOp; |
| 78633 | 78734 | assert( nFarg==1 ); |
| 78634 | 78735 | assert( pFarg->a[0].pExpr!=0 ); |
| 78635 | 78736 | exprOp = pFarg->a[0].pExpr->op; |
| 78636 | 78737 | if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ |
| 78637 | 78738 | assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); |
| 78638 | 78739 | assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); |
| 78639 | | - testcase( pDef->flags==SQLITE_FUNC_LENGTH ); |
| 78640 | | - pFarg->a[0].pExpr->op2 = pDef->flags; |
| 78740 | + testcase( (pDef->funcFlags&~SQLITE_FUNC_ENCMASK) |
| 78741 | + ==SQLITE_FUNC_LENGTH ); |
| 78742 | + pFarg->a[0].pExpr->op2 = pDef->funcFlags&~SQLITE_FUNC_ENCMASK; |
| 78641 | 78743 | } |
| 78642 | 78744 | } |
| 78643 | 78745 | |
| 78644 | 78746 | sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ |
| 78645 | 78747 | sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); |
| | @@ -78668,15 +78770,15 @@ |
| 78668 | 78770 | #endif |
| 78669 | 78771 | for(i=0; i<nFarg; i++){ |
| 78670 | 78772 | if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ |
| 78671 | 78773 | constMask |= (1<<i); |
| 78672 | 78774 | } |
| 78673 | | - if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ |
| 78775 | + if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ |
| 78674 | 78776 | pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); |
| 78675 | 78777 | } |
| 78676 | 78778 | } |
| 78677 | | - if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 78779 | + if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 78678 | 78780 | if( !pColl ) pColl = db->pDfltColl; |
| 78679 | 78781 | sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); |
| 78680 | 78782 | } |
| 78681 | 78783 | sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, |
| 78682 | 78784 | (char*)pDef, P4_FUNCDEF); |
| | @@ -78813,13 +78915,13 @@ |
| 78813 | 78915 | ** Form A is can be transformed into the equivalent form B as follows: |
| 78814 | 78916 | ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... |
| 78815 | 78917 | ** WHEN x=eN THEN rN ELSE y END |
| 78816 | 78918 | ** |
| 78817 | 78919 | ** X (if it exists) is in pExpr->pLeft. |
| 78818 | | - ** Y is in pExpr->pRight. The Y is also optional. If there is no |
| 78819 | | - ** ELSE clause and no other term matches, then the result of the |
| 78820 | | - ** exprssion is NULL. |
| 78920 | + ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is |
| 78921 | + ** odd. The Y is also optional. If the number of elements in x.pList |
| 78922 | + ** is even, then Y is omitted and the "otherwise" result is NULL. |
| 78821 | 78923 | ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. |
| 78822 | 78924 | ** |
| 78823 | 78925 | ** The result of the expression is the Ri for the first matching Ei, |
| 78824 | 78926 | ** or if there is no matching Ei, the ELSE term Y, or if there is |
| 78825 | 78927 | ** no ELSE term, NULL. |
| | @@ -78836,33 +78938,31 @@ |
| 78836 | 78938 | Expr *pX; /* The X expression */ |
| 78837 | 78939 | Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ |
| 78838 | 78940 | VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) |
| 78839 | 78941 | |
| 78840 | 78942 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); |
| 78841 | | - assert((pExpr->x.pList->nExpr % 2) == 0); |
| 78842 | 78943 | assert(pExpr->x.pList->nExpr > 0); |
| 78843 | 78944 | pEList = pExpr->x.pList; |
| 78844 | 78945 | aListelem = pEList->a; |
| 78845 | 78946 | nExpr = pEList->nExpr; |
| 78846 | 78947 | endLabel = sqlite3VdbeMakeLabel(v); |
| 78847 | 78948 | if( (pX = pExpr->pLeft)!=0 ){ |
| 78848 | 78949 | cacheX = *pX; |
| 78849 | 78950 | testcase( pX->op==TK_COLUMN ); |
| 78850 | 78951 | testcase( pX->op==TK_REGISTER ); |
| 78851 | | - cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); |
| 78952 | + exprToRegister(&cacheX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); |
| 78852 | 78953 | testcase( regFree1==0 ); |
| 78853 | | - cacheX.op = TK_REGISTER; |
| 78854 | 78954 | opCompare.op = TK_EQ; |
| 78855 | 78955 | opCompare.pLeft = &cacheX; |
| 78856 | 78956 | pTest = &opCompare; |
| 78857 | 78957 | /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: |
| 78858 | 78958 | ** The value in regFree1 might get SCopy-ed into the file result. |
| 78859 | 78959 | ** So make sure that the regFree1 register is not reused for other |
| 78860 | 78960 | ** purposes and possibly overwritten. */ |
| 78861 | 78961 | regFree1 = 0; |
| 78862 | 78962 | } |
| 78863 | | - for(i=0; i<nExpr; i=i+2){ |
| 78963 | + for(i=0; i<nExpr-1; i=i+2){ |
| 78864 | 78964 | sqlite3ExprCachePush(pParse); |
| 78865 | 78965 | if( pX ){ |
| 78866 | 78966 | assert( pTest!=0 ); |
| 78867 | 78967 | opCompare.pRight = aListelem[i].pExpr; |
| 78868 | 78968 | }else{ |
| | @@ -78876,13 +78976,13 @@ |
| 78876 | 78976 | sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); |
| 78877 | 78977 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); |
| 78878 | 78978 | sqlite3ExprCachePop(pParse, 1); |
| 78879 | 78979 | sqlite3VdbeResolveLabel(v, nextCase); |
| 78880 | 78980 | } |
| 78881 | | - if( pExpr->pRight ){ |
| 78981 | + if( (nExpr&1)!=0 ){ |
| 78882 | 78982 | sqlite3ExprCachePush(pParse); |
| 78883 | | - sqlite3ExprCode(pParse, pExpr->pRight, target); |
| 78983 | + sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); |
| 78884 | 78984 | sqlite3ExprCachePop(pParse, 1); |
| 78885 | 78985 | }else{ |
| 78886 | 78986 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| 78887 | 78987 | } |
| 78888 | 78988 | assert( db->mallocFailed || pParse->nErr>0 |
| | @@ -78990,13 +79090,11 @@ |
| 78990 | 79090 | ** modifications or enhancements. */ |
| 78991 | 79091 | if( ALWAYS(pExpr->op!=TK_REGISTER) ){ |
| 78992 | 79092 | int iMem; |
| 78993 | 79093 | iMem = ++pParse->nMem; |
| 78994 | 79094 | sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); |
| 78995 | | - pExpr->iTable = iMem; |
| 78996 | | - pExpr->op2 = pExpr->op; |
| 78997 | | - pExpr->op = TK_REGISTER; |
| 79095 | + exprToRegister(pExpr, iMem); |
| 78998 | 79096 | } |
| 78999 | 79097 | return inReg; |
| 79000 | 79098 | } |
| 79001 | 79099 | |
| 79002 | 79100 | #if defined(SQLITE_ENABLE_TREE_EXPLAIN) |
| | @@ -79122,11 +79220,11 @@ |
| 79122 | 79220 | |
| 79123 | 79221 | case TK_AGG_FUNCTION: |
| 79124 | 79222 | case TK_CONST_FUNC: |
| 79125 | 79223 | case TK_FUNCTION: { |
| 79126 | 79224 | ExprList *pFarg; /* List of function arguments */ |
| 79127 | | - if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){ |
| 79225 | + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ |
| 79128 | 79226 | pFarg = 0; |
| 79129 | 79227 | }else{ |
| 79130 | 79228 | pFarg = pExpr->x.pList; |
| 79131 | 79229 | } |
| 79132 | 79230 | if( op==TK_AGG_FUNCTION ){ |
| | @@ -79371,13 +79469,11 @@ |
| 79371 | 79469 | int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); |
| 79372 | 79470 | /* If r2!=r1, it means that register r1 is never used. That is harmless |
| 79373 | 79471 | ** but suboptimal, so we want to know about the situation to fix it. |
| 79374 | 79472 | ** Hence the following assert: */ |
| 79375 | 79473 | assert( r2==r1 ); |
| 79376 | | - pExpr->op2 = pExpr->op; |
| 79377 | | - pExpr->op = TK_REGISTER; |
| 79378 | | - pExpr->iTable = r2; |
| 79474 | + exprToRegister(pExpr, r2); |
| 79379 | 79475 | return WRC_Prune; |
| 79380 | 79476 | } |
| 79381 | 79477 | return WRC_Continue; |
| 79382 | 79478 | } |
| 79383 | 79479 | |
| | @@ -79471,13 +79567,11 @@ |
| 79471 | 79567 | compLeft.pLeft = &exprX; |
| 79472 | 79568 | compLeft.pRight = pExpr->x.pList->a[0].pExpr; |
| 79473 | 79569 | compRight.op = TK_LE; |
| 79474 | 79570 | compRight.pLeft = &exprX; |
| 79475 | 79571 | compRight.pRight = pExpr->x.pList->a[1].pExpr; |
| 79476 | | - exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); |
| 79477 | | - exprX.op2 = exprX.op; |
| 79478 | | - exprX.op = TK_REGISTER; |
| 79572 | + exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); |
| 79479 | 79573 | if( jumpIfTrue ){ |
| 79480 | 79574 | sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); |
| 79481 | 79575 | }else{ |
| 79482 | 79576 | sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); |
| 79483 | 79577 | } |
| | @@ -79788,12 +79882,12 @@ |
| 79788 | 79882 | */ |
| 79789 | 79883 | SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ |
| 79790 | 79884 | if( pA==0||pB==0 ){ |
| 79791 | 79885 | return pB==pA ? 0 : 2; |
| 79792 | 79886 | } |
| 79793 | | - assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) ); |
| 79794 | | - assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) ); |
| 79887 | + assert( !ExprHasProperty(pA, EP_TokenOnly|EP_Reduced) ); |
| 79888 | + assert( !ExprHasProperty(pB, EP_TokenOnly|EP_Reduced) ); |
| 79795 | 79889 | if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){ |
| 79796 | 79890 | return 2; |
| 79797 | 79891 | } |
| 79798 | 79892 | if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; |
| 79799 | 79893 | if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){ |
| | @@ -80003,11 +80097,11 @@ |
| 80003 | 80097 | ** clause of the aggregate query */ |
| 80004 | 80098 | if( ALWAYS(pSrcList!=0) ){ |
| 80005 | 80099 | struct SrcList_item *pItem = pSrcList->a; |
| 80006 | 80100 | for(i=0; i<pSrcList->nSrc; i++, pItem++){ |
| 80007 | 80101 | struct AggInfo_col *pCol; |
| 80008 | | - assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 80102 | + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 80009 | 80103 | if( pExpr->iTable==pItem->iCursor ){ |
| 80010 | 80104 | /* If we reach this point, it means that pExpr refers to a table |
| 80011 | 80105 | ** that is in the FROM clause of the aggregate query. |
| 80012 | 80106 | ** |
| 80013 | 80107 | ** Make an entry for the column in pAggInfo->aCol[] if there |
| | @@ -80052,11 +80146,11 @@ |
| 80052 | 80146 | /* There is now an entry for pExpr in pAggInfo->aCol[] (either |
| 80053 | 80147 | ** because it was there before or because we just created it). |
| 80054 | 80148 | ** Convert the pExpr to be a TK_AGG_COLUMN referring to that |
| 80055 | 80149 | ** pAggInfo->aCol[] entry. |
| 80056 | 80150 | */ |
| 80057 | | - ExprSetIrreducible(pExpr); |
| 80151 | + ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 80058 | 80152 | pExpr->pAggInfo = pAggInfo; |
| 80059 | 80153 | pExpr->op = TK_AGG_COLUMN; |
| 80060 | 80154 | pExpr->iAgg = (i16)k; |
| 80061 | 80155 | break; |
| 80062 | 80156 | } /* endif pExpr->iTable==pItem->iCursor */ |
| | @@ -80098,12 +80192,12 @@ |
| 80098 | 80192 | } |
| 80099 | 80193 | } |
| 80100 | 80194 | } |
| 80101 | 80195 | /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry |
| 80102 | 80196 | */ |
| 80103 | | - assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 80104 | | - ExprSetIrreducible(pExpr); |
| 80197 | + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 80198 | + ExprSetVVAProperty(pExpr, EP_NoReduce); |
| 80105 | 80199 | pExpr->iAgg = (i16)i; |
| 80106 | 80200 | pExpr->pAggInfo = pAggInfo; |
| 80107 | 80201 | return WRC_Prune; |
| 80108 | 80202 | }else{ |
| 80109 | 80203 | return WRC_Continue; |
| | @@ -81394,11 +81488,11 @@ |
| 81394 | 81488 | |
| 81395 | 81489 | p->iGet = -1; |
| 81396 | 81490 | p->mxSample = mxSample; |
| 81397 | 81491 | p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1); |
| 81398 | 81492 | p->current.anLt = &p->current.anEq[nColUp]; |
| 81399 | | - sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81493 | + p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[1])*0xd0944565; |
| 81400 | 81494 | |
| 81401 | 81495 | /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81402 | 81496 | p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| 81403 | 81497 | p->aBest = &p->a[mxSample]; |
| 81404 | 81498 | pSpace = (u8*)(&p->a[mxSample+nCol]); |
| | @@ -81418,12 +81512,11 @@ |
| 81418 | 81512 | /* Return a pointer to the allocated object to the caller */ |
| 81419 | 81513 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 81420 | 81514 | } |
| 81421 | 81515 | static const FuncDef statInitFuncdef = { |
| 81422 | 81516 | 1+IsStat34, /* nArg */ |
| 81423 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 81424 | | - 0, /* flags */ |
| 81517 | + SQLITE_UTF8, /* funcFlags */ |
| 81425 | 81518 | 0, /* pUserData */ |
| 81426 | 81519 | 0, /* pNext */ |
| 81427 | 81520 | statInit, /* xFunc */ |
| 81428 | 81521 | 0, /* xStep */ |
| 81429 | 81522 | 0, /* xFinalize */ |
| | @@ -81715,12 +81808,11 @@ |
| 81715 | 81808 | } |
| 81716 | 81809 | #endif |
| 81717 | 81810 | } |
| 81718 | 81811 | static const FuncDef statPushFuncdef = { |
| 81719 | 81812 | 2+IsStat34, /* nArg */ |
| 81720 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 81721 | | - 0, /* flags */ |
| 81813 | + SQLITE_UTF8, /* funcFlags */ |
| 81722 | 81814 | 0, /* pUserData */ |
| 81723 | 81815 | 0, /* pNext */ |
| 81724 | 81816 | statPush, /* xFunc */ |
| 81725 | 81817 | 0, /* xStep */ |
| 81726 | 81818 | 0, /* xFinalize */ |
| | @@ -81851,12 +81943,11 @@ |
| 81851 | 81943 | } |
| 81852 | 81944 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81853 | 81945 | } |
| 81854 | 81946 | static const FuncDef statGetFuncdef = { |
| 81855 | 81947 | 1+IsStat34, /* nArg */ |
| 81856 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 81857 | | - 0, /* flags */ |
| 81948 | + SQLITE_UTF8, /* funcFlags */ |
| 81858 | 81949 | 0, /* pUserData */ |
| 81859 | 81950 | 0, /* pNext */ |
| 81860 | 81951 | statGet, /* xFunc */ |
| 81861 | 81952 | 0, /* xStep */ |
| 81862 | 81953 | 0, /* xFinalize */ |
| | @@ -83056,12 +83147,11 @@ |
| 83056 | 83147 | ** DETACH pDbname |
| 83057 | 83148 | */ |
| 83058 | 83149 | SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ |
| 83059 | 83150 | static const FuncDef detach_func = { |
| 83060 | 83151 | 1, /* nArg */ |
| 83061 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 83062 | | - 0, /* flags */ |
| 83152 | + SQLITE_UTF8, /* funcFlags */ |
| 83063 | 83153 | 0, /* pUserData */ |
| 83064 | 83154 | 0, /* pNext */ |
| 83065 | 83155 | detachFunc, /* xFunc */ |
| 83066 | 83156 | 0, /* xStep */ |
| 83067 | 83157 | 0, /* xFinalize */ |
| | @@ -83078,12 +83168,11 @@ |
| 83078 | 83168 | ** ATTACH p AS pDbname KEY pKey |
| 83079 | 83169 | */ |
| 83080 | 83170 | SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ |
| 83081 | 83171 | static const FuncDef attach_func = { |
| 83082 | 83172 | 3, /* nArg */ |
| 83083 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 83084 | | - 0, /* flags */ |
| 83173 | + SQLITE_UTF8, /* funcFlags */ |
| 83085 | 83174 | 0, /* pUserData */ |
| 83086 | 83175 | 0, /* pNext */ |
| 83087 | 83176 | attachFunc, /* xFunc */ |
| 83088 | 83177 | 0, /* xStep */ |
| 83089 | 83178 | 0, /* xFinalize */ |
| | @@ -83188,11 +83277,11 @@ |
| 83188 | 83277 | SQLITE_PRIVATE int sqlite3FixExpr( |
| 83189 | 83278 | DbFixer *pFix, /* Context of the fixation */ |
| 83190 | 83279 | Expr *pExpr /* The expression to be fixed to one database */ |
| 83191 | 83280 | ){ |
| 83192 | 83281 | while( pExpr ){ |
| 83193 | | - if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break; |
| 83282 | + if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; |
| 83194 | 83283 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 83195 | 83284 | if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; |
| 83196 | 83285 | }else{ |
| 83197 | 83286 | if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; |
| 83198 | 83287 | } |
| | @@ -87589,13 +87678,13 @@ |
| 87589 | 87678 | }else{ |
| 87590 | 87679 | match = 1; |
| 87591 | 87680 | } |
| 87592 | 87681 | |
| 87593 | 87682 | /* Bonus points if the text encoding matches */ |
| 87594 | | - if( enc==p->iPrefEnc ){ |
| 87683 | + if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ |
| 87595 | 87684 | match += 2; /* Exact encoding match */ |
| 87596 | | - }else if( (enc & p->iPrefEnc & 2)!=0 ){ |
| 87685 | + }else if( (enc & p->funcFlags & 2)!=0 ){ |
| 87597 | 87686 | match += 1; /* Both are UTF16, but with different byte orders */ |
| 87598 | 87687 | } |
| 87599 | 87688 | |
| 87600 | 87689 | return match; |
| 87601 | 87690 | } |
| | @@ -87725,11 +87814,11 @@ |
| 87725 | 87814 | */ |
| 87726 | 87815 | if( createFlag && bestScore<FUNC_PERFECT_MATCH && |
| 87727 | 87816 | (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ |
| 87728 | 87817 | pBest->zName = (char *)&pBest[1]; |
| 87729 | 87818 | pBest->nArg = (u16)nArg; |
| 87730 | | - pBest->iPrefEnc = enc; |
| 87819 | + pBest->funcFlags = enc; |
| 87731 | 87820 | memcpy(pBest->zName, zName, nName); |
| 87732 | 87821 | pBest->zName[nName] = 0; |
| 87733 | 87822 | sqlite3FuncDefInsert(&db->aFunc, pBest); |
| 87734 | 87823 | } |
| 87735 | 87824 | |
| | @@ -88335,11 +88424,11 @@ |
| 88335 | 88424 | sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid); |
| 88336 | 88425 | |
| 88337 | 88426 | /* Do FK processing. This call checks that any FK constraints that |
| 88338 | 88427 | ** refer to this table (i.e. constraints attached to other tables) |
| 88339 | 88428 | ** are not violated by deleting this row. */ |
| 88340 | | - sqlite3FkCheck(pParse, pTab, iOld, 0); |
| 88429 | + sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); |
| 88341 | 88430 | } |
| 88342 | 88431 | |
| 88343 | 88432 | /* Delete the index and table entries. Skip this step if pTab is really |
| 88344 | 88433 | ** a view (in which case the only effect of the DELETE statement is to |
| 88345 | 88434 | ** fire the INSTEAD OF triggers). */ |
| | @@ -88352,11 +88441,11 @@ |
| 88352 | 88441 | } |
| 88353 | 88442 | |
| 88354 | 88443 | /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to |
| 88355 | 88444 | ** handle rows (possibly in other tables) that refer via a foreign key |
| 88356 | 88445 | ** to the row just deleted. */ |
| 88357 | | - sqlite3FkActions(pParse, pTab, 0, iOld); |
| 88446 | + sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); |
| 88358 | 88447 | |
| 88359 | 88448 | /* Invoke AFTER DELETE trigger programs. */ |
| 88360 | 88449 | sqlite3CodeRowTrigger(pParse, pTrigger, |
| 88361 | 88450 | TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel |
| 88362 | 88451 | ); |
| | @@ -88891,18 +88980,18 @@ |
| 88891 | 88980 | } |
| 88892 | 88981 | } |
| 88893 | 88982 | } |
| 88894 | 88983 | |
| 88895 | 88984 | /* |
| 88896 | | -** The COALESCE() and IFNULL() functions are implemented as VDBE code so |
| 88897 | | -** that unused argument values do not have to be computed. However, we |
| 88898 | | -** still need some kind of function implementation for this routines in |
| 88899 | | -** the function table. That function implementation will never be called |
| 88900 | | -** so it doesn't matter what the implementation is. We might as well use |
| 88901 | | -** the "version()" function as a substitute. |
| 88985 | +** Some functions like COALESCE() and IFNULL() and UNLIKELY() are implemented |
| 88986 | +** as VDBE code so that unused argument values do not have to be computed. |
| 88987 | +** However, we still need some kind of function implementation for this |
| 88988 | +** routines in the function table. The noopFunc macro provides this. |
| 88989 | +** noopFunc will never be called so it doesn't matter what the implementation |
| 88990 | +** is. We might as well use the "version()" function as a substitute. |
| 88902 | 88991 | */ |
| 88903 | | -#define ifnullFunc versionFunc /* Substitute function - never called */ |
| 88992 | +#define noopFunc versionFunc /* Substitute function - never called */ |
| 88904 | 88993 | |
| 88905 | 88994 | /* |
| 88906 | 88995 | ** Implementation of random(). Return a random integer. |
| 88907 | 88996 | */ |
| 88908 | 88997 | static void randomFunc( |
| | @@ -89017,13 +89106,13 @@ |
| 89017 | 89106 | ** able to participate in upper-case-to-lower-case mappings in EBCDIC |
| 89018 | 89107 | ** whereas only characters less than 0x80 do in ASCII. |
| 89019 | 89108 | */ |
| 89020 | 89109 | #if defined(SQLITE_EBCDIC) |
| 89021 | 89110 | # define sqlite3Utf8Read(A) (*((*A)++)) |
| 89022 | | -# define GlogUpperToLower(A) A = sqlite3UpperToLower[A] |
| 89111 | +# define GlobUpperToLower(A) A = sqlite3UpperToLower[A] |
| 89023 | 89112 | #else |
| 89024 | | -# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; } |
| 89113 | +# define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; } |
| 89025 | 89114 | #endif |
| 89026 | 89115 | |
| 89027 | 89116 | static const struct compareInfo globInfo = { '*', '?', '[', 0 }; |
| 89028 | 89117 | /* The correct SQL-92 behavior is for the LIKE operator to ignore |
| 89029 | 89118 | ** case. Thus 'a' LIKE 'A' would be true. */ |
| | @@ -89098,15 +89187,15 @@ |
| 89098 | 89187 | } |
| 89099 | 89188 | return *zString!=0; |
| 89100 | 89189 | } |
| 89101 | 89190 | while( (c2 = sqlite3Utf8Read(&zString))!=0 ){ |
| 89102 | 89191 | if( noCase ){ |
| 89103 | | - GlogUpperToLower(c2); |
| 89104 | | - GlogUpperToLower(c); |
| 89192 | + GlobUpperToLower(c2); |
| 89193 | + GlobUpperToLower(c); |
| 89105 | 89194 | while( c2 != 0 && c2 != c ){ |
| 89106 | 89195 | c2 = sqlite3Utf8Read(&zString); |
| 89107 | | - GlogUpperToLower(c2); |
| 89196 | + GlobUpperToLower(c2); |
| 89108 | 89197 | } |
| 89109 | 89198 | }else{ |
| 89110 | 89199 | while( c2 != 0 && c2 != c ){ |
| 89111 | 89200 | c2 = sqlite3Utf8Read(&zString); |
| 89112 | 89201 | } |
| | @@ -89154,12 +89243,12 @@ |
| 89154 | 89243 | }else if( esc==c && !prevEscape ){ |
| 89155 | 89244 | prevEscape = 1; |
| 89156 | 89245 | }else{ |
| 89157 | 89246 | c2 = sqlite3Utf8Read(&zString); |
| 89158 | 89247 | if( noCase ){ |
| 89159 | | - GlogUpperToLower(c); |
| 89160 | | - GlogUpperToLower(c2); |
| 89248 | + GlobUpperToLower(c); |
| 89249 | + GlobUpperToLower(c2); |
| 89161 | 89250 | } |
| 89162 | 89251 | if( c!=c2 ){ |
| 89163 | 89252 | return 0; |
| 89164 | 89253 | } |
| 89165 | 89254 | prevEscape = 0; |
| | @@ -90027,11 +90116,11 @@ |
| 90027 | 90116 | static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ |
| 90028 | 90117 | FuncDef *pDef; |
| 90029 | 90118 | pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName), |
| 90030 | 90119 | 2, SQLITE_UTF8, 0); |
| 90031 | 90120 | if( ALWAYS(pDef) ){ |
| 90032 | | - pDef->flags = flagVal; |
| 90121 | + pDef->funcFlags |= flagVal; |
| 90033 | 90122 | } |
| 90034 | 90123 | } |
| 90035 | 90124 | |
| 90036 | 90125 | /* |
| 90037 | 90126 | ** Register the built-in LIKE and GLOB functions. The caseSensitive |
| | @@ -90071,11 +90160,11 @@ |
| 90071 | 90160 | } |
| 90072 | 90161 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 90073 | 90162 | pDef = sqlite3FindFunction(db, pExpr->u.zToken, |
| 90074 | 90163 | sqlite3Strlen30(pExpr->u.zToken), |
| 90075 | 90164 | 2, SQLITE_UTF8, 0); |
| 90076 | | - if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){ |
| 90165 | + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ |
| 90077 | 90166 | return 0; |
| 90078 | 90167 | } |
| 90079 | 90168 | |
| 90080 | 90169 | /* The memcpy() statement assumes that the wildcard characters are |
| 90081 | 90170 | ** the first three statements in the compareInfo structure. The |
| | @@ -90083,11 +90172,11 @@ |
| 90083 | 90172 | */ |
| 90084 | 90173 | memcpy(aWc, pDef->pUserData, 3); |
| 90085 | 90174 | assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); |
| 90086 | 90175 | assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); |
| 90087 | 90176 | assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); |
| 90088 | | - *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0; |
| 90177 | + *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0; |
| 90089 | 90178 | return 1; |
| 90090 | 90179 | } |
| 90091 | 90180 | |
| 90092 | 90181 | /* |
| 90093 | 90182 | ** All all of the FuncDef structures in the aBuiltinFunc[] array above |
| | @@ -90132,13 +90221,15 @@ |
| 90132 | 90221 | #endif |
| 90133 | 90222 | FUNCTION(upper, 1, 0, 0, upperFunc ), |
| 90134 | 90223 | FUNCTION(lower, 1, 0, 0, lowerFunc ), |
| 90135 | 90224 | FUNCTION(coalesce, 1, 0, 0, 0 ), |
| 90136 | 90225 | FUNCTION(coalesce, 0, 0, 0, 0 ), |
| 90137 | | - FUNCTION2(coalesce, -1, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE), |
| 90226 | + FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), |
| 90138 | 90227 | FUNCTION(hex, 1, 0, 0, hexFunc ), |
| 90139 | | - FUNCTION2(ifnull, 2, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE), |
| 90228 | + FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), |
| 90229 | + FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), |
| 90230 | + FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), |
| 90140 | 90231 | FUNCTION(random, 0, 0, 0, randomFunc ), |
| 90141 | 90232 | FUNCTION(randomblob, 1, 0, 0, randomBlob ), |
| 90142 | 90233 | FUNCTION(nullif, 2, 0, 1, nullifFunc ), |
| 90143 | 90234 | FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), |
| 90144 | 90235 | FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), |
| | @@ -90162,11 +90253,11 @@ |
| 90162 | 90253 | #endif |
| 90163 | 90254 | AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), |
| 90164 | 90255 | AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), |
| 90165 | 90256 | AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), |
| 90166 | 90257 | /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */ |
| 90167 | | - {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0}, |
| 90258 | + {0,SQLITE_UTF8|SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0}, |
| 90168 | 90259 | AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), |
| 90169 | 90260 | AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), |
| 90170 | 90261 | AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), |
| 90171 | 90262 | |
| 90172 | 90263 | LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), |
| | @@ -90878,10 +90969,74 @@ |
| 90878 | 90969 | sqlite3VdbeResolveLabel(v, iSkip); |
| 90879 | 90970 | } |
| 90880 | 90971 | } |
| 90881 | 90972 | } |
| 90882 | 90973 | |
| 90974 | + |
| 90975 | +/* |
| 90976 | +** The second argument points to an FKey object representing a foreign key |
| 90977 | +** for which pTab is the child table. An UPDATE statement against pTab |
| 90978 | +** is currently being processed. For each column of the table that is |
| 90979 | +** actually updated, the corresponding element in the aChange[] array |
| 90980 | +** is zero or greater (if a column is unmodified the corresponding element |
| 90981 | +** is set to -1). If the rowid column is modified by the UPDATE statement |
| 90982 | +** the bChngRowid argument is non-zero. |
| 90983 | +** |
| 90984 | +** This function returns true if any of the columns that are part of the |
| 90985 | +** child key for FK constraint *p are modified. |
| 90986 | +*/ |
| 90987 | +static int fkChildIsModified( |
| 90988 | + Table *pTab, /* Table being updated */ |
| 90989 | + FKey *p, /* Foreign key for which pTab is the child */ |
| 90990 | + int *aChange, /* Array indicating modified columns */ |
| 90991 | + int bChngRowid /* True if rowid is modified by this update */ |
| 90992 | +){ |
| 90993 | + int i; |
| 90994 | + for(i=0; i<p->nCol; i++){ |
| 90995 | + int iChildKey = p->aCol[i].iFrom; |
| 90996 | + if( aChange[iChildKey]>=0 ) return 1; |
| 90997 | + if( iChildKey==pTab->iPKey && bChngRowid ) return 1; |
| 90998 | + } |
| 90999 | + return 0; |
| 91000 | +} |
| 91001 | + |
| 91002 | +/* |
| 91003 | +** The second argument points to an FKey object representing a foreign key |
| 91004 | +** for which pTab is the parent table. An UPDATE statement against pTab |
| 91005 | +** is currently being processed. For each column of the table that is |
| 91006 | +** actually updated, the corresponding element in the aChange[] array |
| 91007 | +** is zero or greater (if a column is unmodified the corresponding element |
| 91008 | +** is set to -1). If the rowid column is modified by the UPDATE statement |
| 91009 | +** the bChngRowid argument is non-zero. |
| 91010 | +** |
| 91011 | +** This function returns true if any of the columns that are part of the |
| 91012 | +** parent key for FK constraint *p are modified. |
| 91013 | +*/ |
| 91014 | +static int fkParentIsModified( |
| 91015 | + Table *pTab, |
| 91016 | + FKey *p, |
| 91017 | + int *aChange, |
| 91018 | + int bChngRowid |
| 91019 | +){ |
| 91020 | + int i; |
| 91021 | + for(i=0; i<p->nCol; i++){ |
| 91022 | + char *zKey = p->aCol[i].zCol; |
| 91023 | + int iKey; |
| 91024 | + for(iKey=0; iKey<pTab->nCol; iKey++){ |
| 91025 | + if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ |
| 91026 | + Column *pCol = &pTab->aCol[iKey]; |
| 91027 | + if( zKey ){ |
| 91028 | + if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; |
| 91029 | + }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ |
| 91030 | + return 1; |
| 91031 | + } |
| 91032 | + } |
| 91033 | + } |
| 91034 | + } |
| 91035 | + return 0; |
| 91036 | +} |
| 91037 | + |
| 90883 | 91038 | /* |
| 90884 | 91039 | ** This function is called when inserting, deleting or updating a row of |
| 90885 | 91040 | ** table pTab to generate VDBE code to perform foreign key constraint |
| 90886 | 91041 | ** processing for the operation. |
| 90887 | 91042 | ** |
| | @@ -90902,11 +91057,13 @@ |
| 90902 | 91057 | */ |
| 90903 | 91058 | SQLITE_PRIVATE void sqlite3FkCheck( |
| 90904 | 91059 | Parse *pParse, /* Parse context */ |
| 90905 | 91060 | Table *pTab, /* Row is being deleted from this table */ |
| 90906 | 91061 | int regOld, /* Previous row data is stored here */ |
| 90907 | | - int regNew /* New row data is stored here */ |
| 91062 | + int regNew, /* New row data is stored here */ |
| 91063 | + int *aChange, /* Array indicating UPDATEd columns (or 0) */ |
| 91064 | + int bChngRowid /* True if rowid is UPDATEd */ |
| 90908 | 91065 | ){ |
| 90909 | 91066 | sqlite3 *db = pParse->db; /* Database handle */ |
| 90910 | 91067 | FKey *pFKey; /* Used to iterate through FKs */ |
| 90911 | 91068 | int iDb; /* Index of database containing pTab */ |
| 90912 | 91069 | const char *zDb; /* Name of database containing pTab */ |
| | @@ -90929,10 +91086,17 @@ |
| 90929 | 91086 | int *aiFree = 0; |
| 90930 | 91087 | int *aiCol; |
| 90931 | 91088 | int iCol; |
| 90932 | 91089 | int i; |
| 90933 | 91090 | int isIgnore = 0; |
| 91091 | + |
| 91092 | + if( aChange |
| 91093 | + && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 |
| 91094 | + && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 |
| 91095 | + ){ |
| 91096 | + continue; |
| 91097 | + } |
| 90934 | 91098 | |
| 90935 | 91099 | /* Find the parent table of this foreign key. Also find a unique index |
| 90936 | 91100 | ** on the parent key columns in the parent table. If either of these |
| 90937 | 91101 | ** schema items cannot be located, set an error in pParse and return |
| 90938 | 91102 | ** early. */ |
| | @@ -91011,10 +91175,14 @@ |
| 91011 | 91175 | /* Loop through all the foreign key constraints that refer to this table */ |
| 91012 | 91176 | for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ |
| 91013 | 91177 | Index *pIdx = 0; /* Foreign key index for pFKey */ |
| 91014 | 91178 | SrcList *pSrc; |
| 91015 | 91179 | int *aiCol = 0; |
| 91180 | + |
| 91181 | + if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ |
| 91182 | + continue; |
| 91183 | + } |
| 91016 | 91184 | |
| 91017 | 91185 | if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) |
| 91018 | 91186 | && !pParse->pToplevel && !pParse->isMultiWrite |
| 91019 | 91187 | ){ |
| 91020 | 91188 | assert( regOld==0 && regNew!=0 ); |
| | @@ -91084,10 +91252,11 @@ |
| 91084 | 91252 | } |
| 91085 | 91253 | } |
| 91086 | 91254 | } |
| 91087 | 91255 | return mask; |
| 91088 | 91256 | } |
| 91257 | + |
| 91089 | 91258 | |
| 91090 | 91259 | /* |
| 91091 | 91260 | ** This function is called before generating code to update or delete a |
| 91092 | 91261 | ** row contained in table pTab. If the operation is a DELETE, then |
| 91093 | 91262 | ** parameter aChange is passed a NULL value. For an UPDATE, aChange points |
| | @@ -91114,36 +91283,20 @@ |
| 91114 | 91283 | ** foreign key constraint. */ |
| 91115 | 91284 | return (sqlite3FkReferences(pTab) || pTab->pFKey); |
| 91116 | 91285 | }else{ |
| 91117 | 91286 | /* This is an UPDATE. Foreign key processing is only required if the |
| 91118 | 91287 | ** operation modifies one or more child or parent key columns. */ |
| 91119 | | - int i; |
| 91120 | 91288 | FKey *p; |
| 91121 | 91289 | |
| 91122 | 91290 | /* Check if any child key columns are being modified. */ |
| 91123 | 91291 | for(p=pTab->pFKey; p; p=p->pNextFrom){ |
| 91124 | | - for(i=0; i<p->nCol; i++){ |
| 91125 | | - int iChildKey = p->aCol[i].iFrom; |
| 91126 | | - if( aChange[iChildKey]>=0 ) return 1; |
| 91127 | | - if( iChildKey==pTab->iPKey && chngRowid ) return 1; |
| 91128 | | - } |
| 91292 | + if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1; |
| 91129 | 91293 | } |
| 91130 | 91294 | |
| 91131 | 91295 | /* Check if any parent key columns are being modified. */ |
| 91132 | 91296 | for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ |
| 91133 | | - for(i=0; i<p->nCol; i++){ |
| 91134 | | - char *zKey = p->aCol[i].zCol; |
| 91135 | | - int iKey; |
| 91136 | | - for(iKey=0; iKey<pTab->nCol; iKey++){ |
| 91137 | | - Column *pCol = &pTab->aCol[iKey]; |
| 91138 | | - if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) |
| 91139 | | - : (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){ |
| 91140 | | - if( aChange[iKey]>=0 ) return 1; |
| 91141 | | - if( iKey==pTab->iPKey && chngRowid ) return 1; |
| 91142 | | - } |
| 91143 | | - } |
| 91144 | | - } |
| 91297 | + if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1; |
| 91145 | 91298 | } |
| 91146 | 91299 | } |
| 91147 | 91300 | } |
| 91148 | 91301 | return 0; |
| 91149 | 91302 | } |
| | @@ -91365,22 +91518,26 @@ |
| 91365 | 91518 | */ |
| 91366 | 91519 | SQLITE_PRIVATE void sqlite3FkActions( |
| 91367 | 91520 | Parse *pParse, /* Parse context */ |
| 91368 | 91521 | Table *pTab, /* Table being updated or deleted from */ |
| 91369 | 91522 | ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ |
| 91370 | | - int regOld /* Address of array containing old row */ |
| 91523 | + int regOld, /* Address of array containing old row */ |
| 91524 | + int *aChange, /* Array indicating UPDATEd columns (or 0) */ |
| 91525 | + int bChngRowid /* True if rowid is UPDATEd */ |
| 91371 | 91526 | ){ |
| 91372 | 91527 | /* If foreign-key support is enabled, iterate through all FKs that |
| 91373 | 91528 | ** refer to table pTab. If there is an action associated with the FK |
| 91374 | 91529 | ** for this operation (either update or delete), invoke the associated |
| 91375 | 91530 | ** trigger sub-program. */ |
| 91376 | 91531 | if( pParse->db->flags&SQLITE_ForeignKeys ){ |
| 91377 | 91532 | FKey *pFKey; /* Iterator variable */ |
| 91378 | 91533 | for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ |
| 91379 | | - Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges); |
| 91380 | | - if( pAction ){ |
| 91381 | | - sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0); |
| 91534 | + if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ |
| 91535 | + Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); |
| 91536 | + if( pAct ){ |
| 91537 | + sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); |
| 91538 | + } |
| 91382 | 91539 | } |
| 91383 | 91540 | } |
| 91384 | 91541 | } |
| 91385 | 91542 | } |
| 91386 | 91543 | |
| | @@ -92461,11 +92618,11 @@ |
| 92461 | 92618 | { |
| 92462 | 92619 | int isReplace; /* Set to true if constraints may cause a replace */ |
| 92463 | 92620 | sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx, |
| 92464 | 92621 | keyColumn>=0, 0, onError, endOfLoop, &isReplace |
| 92465 | 92622 | ); |
| 92466 | | - sqlite3FkCheck(pParse, pTab, 0, regIns); |
| 92623 | + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); |
| 92467 | 92624 | sqlite3CompleteInsertion( |
| 92468 | 92625 | pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0 |
| 92469 | 92626 | ); |
| 92470 | 92627 | } |
| 92471 | 92628 | } |
| | @@ -94762,10 +94919,239 @@ |
| 94762 | 94919 | ** |
| 94763 | 94920 | ************************************************************************* |
| 94764 | 94921 | ** This file contains code used to implement the PRAGMA command. |
| 94765 | 94922 | */ |
| 94766 | 94923 | |
| 94924 | +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) |
| 94925 | +# if defined(__APPLE__) |
| 94926 | +# define SQLITE_ENABLE_LOCKING_STYLE 1 |
| 94927 | +# else |
| 94928 | +# define SQLITE_ENABLE_LOCKING_STYLE 0 |
| 94929 | +# endif |
| 94930 | +#endif |
| 94931 | + |
| 94932 | +/*************************************************************************** |
| 94933 | +** The next block of code, including the PragTyp_XXXX macro definitions and |
| 94934 | +** the aPragmaName[] object is composed of generated code. DO NOT EDIT. |
| 94935 | +** |
| 94936 | +** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun |
| 94937 | +** that script. Then copy/paste the output in place of the following: |
| 94938 | +*/ |
| 94939 | +#define PragTyp_HEADER_VALUE 0 |
| 94940 | +#define PragTyp_AUTO_VACUUM 1 |
| 94941 | +#define PragTyp_FLAG 2 |
| 94942 | +#define PragTyp_BUSY_TIMEOUT 3 |
| 94943 | +#define PragTyp_CACHE_SIZE 4 |
| 94944 | +#define PragTyp_CASE_SENSITIVE_LIKE 5 |
| 94945 | +#define PragTyp_COLLATION_LIST 6 |
| 94946 | +#define PragTyp_COMPILE_OPTIONS 7 |
| 94947 | +#define PragTyp_DATA_STORE_DIRECTORY 8 |
| 94948 | +#define PragTyp_DATABASE_LIST 9 |
| 94949 | +#define PragTyp_DEFAULT_CACHE_SIZE 10 |
| 94950 | +#define PragTyp_ENCODING 11 |
| 94951 | +#define PragTyp_FOREIGN_KEY_CHECK 12 |
| 94952 | +#define PragTyp_FOREIGN_KEY_LIST 13 |
| 94953 | +#define PragTyp_INCREMENTAL_VACUUM 14 |
| 94954 | +#define PragTyp_INDEX_INFO 15 |
| 94955 | +#define PragTyp_INDEX_LIST 16 |
| 94956 | +#define PragTyp_INTEGRITY_CHECK 17 |
| 94957 | +#define PragTyp_JOURNAL_MODE 18 |
| 94958 | +#define PragTyp_JOURNAL_SIZE_LIMIT 19 |
| 94959 | +#define PragTyp_LOCK_PROXY_FILE 20 |
| 94960 | +#define PragTyp_LOCKING_MODE 21 |
| 94961 | +#define PragTyp_PAGE_COUNT 22 |
| 94962 | +#define PragTyp_MMAP_SIZE 23 |
| 94963 | +#define PragTyp_PAGE_SIZE 24 |
| 94964 | +#define PragTyp_SECURE_DELETE 25 |
| 94965 | +#define PragTyp_SHRINK_MEMORY 26 |
| 94966 | +#define PragTyp_SOFT_HEAP_LIMIT 27 |
| 94967 | +#define PragTyp_SYNCHRONOUS 28 |
| 94968 | +#define PragTyp_TABLE_INFO 29 |
| 94969 | +#define PragTyp_TEMP_STORE 30 |
| 94970 | +#define PragTyp_TEMP_STORE_DIRECTORY 31 |
| 94971 | +#define PragTyp_WAL_AUTOCHECKPOINT 32 |
| 94972 | +#define PragTyp_WAL_CHECKPOINT 33 |
| 94973 | +#define PragTyp_ACTIVATE_EXTENSIONS 34 |
| 94974 | +#define PragTyp_HEXKEY 35 |
| 94975 | +#define PragTyp_KEY 36 |
| 94976 | +#define PragTyp_REKEY 37 |
| 94977 | +#define PragTyp_LOCK_STATUS 38 |
| 94978 | +#define PragTyp_PARSER_TRACE 39 |
| 94979 | +static const struct sPragmaNames { |
| 94980 | + const char *const zName; /* Name of pragma */ |
| 94981 | + u8 ePragTyp; /* PragTyp_XXX value */ |
| 94982 | + u32 iArg; /* Extra argument */ |
| 94983 | +} aPragmaNames[] = { |
| 94984 | +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 94985 | + { "activate_extensions", PragTyp_ACTIVATE_EXTENSIONS, 0 }, |
| 94986 | +#endif |
| 94987 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 94988 | + { "application_id", PragTyp_HEADER_VALUE, 0 }, |
| 94989 | +#endif |
| 94990 | +#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 94991 | + { "auto_vacuum", PragTyp_AUTO_VACUUM, 0 }, |
| 94992 | +#endif |
| 94993 | +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) |
| 94994 | + { "automatic_index", PragTyp_FLAG, |
| 94995 | + SQLITE_AutoIndex }, |
| 94996 | +#endif |
| 94997 | + { "busy_timeout", PragTyp_BUSY_TIMEOUT, 0 }, |
| 94998 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 94999 | + { "cache_size", PragTyp_CACHE_SIZE, 0 }, |
| 95000 | +#endif |
| 95001 | + { "cache_spill", PragTyp_FLAG, |
| 95002 | + SQLITE_CacheSpill }, |
| 95003 | + { "case_sensitive_like", PragTyp_CASE_SENSITIVE_LIKE, 0 }, |
| 95004 | + { "checkpoint_fullfsync", PragTyp_FLAG, |
| 95005 | + SQLITE_CkptFullFSync }, |
| 95006 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95007 | + { "collation_list", PragTyp_COLLATION_LIST, 0 }, |
| 95008 | +#endif |
| 95009 | +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) |
| 95010 | + { "compile_options", PragTyp_COMPILE_OPTIONS, 0 }, |
| 95011 | +#endif |
| 95012 | + { "count_changes", PragTyp_FLAG, |
| 95013 | + SQLITE_CountRows }, |
| 95014 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 95015 | + { "data_store_directory", PragTyp_DATA_STORE_DIRECTORY, 0 }, |
| 95016 | +#endif |
| 95017 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95018 | + { "database_list", PragTyp_DATABASE_LIST, 0 }, |
| 95019 | +#endif |
| 95020 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 95021 | + { "default_cache_size", PragTyp_DEFAULT_CACHE_SIZE, 0 }, |
| 95022 | +#endif |
| 95023 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95024 | + { "defer_foreign_keys", PragTyp_FLAG, |
| 95025 | + SQLITE_DeferFKs }, |
| 95026 | +#endif |
| 95027 | + { "empty_result_callbacks", PragTyp_FLAG, |
| 95028 | + SQLITE_NullCallback }, |
| 95029 | +#if !defined(SQLITE_OMIT_UTF16) |
| 95030 | + { "encoding", PragTyp_ENCODING, 0 }, |
| 95031 | +#endif |
| 95032 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95033 | + { "foreign_key_check", PragTyp_FOREIGN_KEY_CHECK, 0 }, |
| 95034 | +#endif |
| 95035 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) |
| 95036 | + { "foreign_key_list", PragTyp_FOREIGN_KEY_LIST, 0 }, |
| 95037 | +#endif |
| 95038 | +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 95039 | + { "foreign_keys", PragTyp_FLAG, |
| 95040 | + SQLITE_ForeignKeys }, |
| 95041 | +#endif |
| 95042 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95043 | + { "freelist_count", PragTyp_HEADER_VALUE, 0 }, |
| 95044 | +#endif |
| 95045 | + { "full_column_names", PragTyp_FLAG, |
| 95046 | + SQLITE_FullColNames }, |
| 95047 | + { "fullfsync", PragTyp_FLAG, |
| 95048 | + SQLITE_FullFSync }, |
| 95049 | +#if defined(SQLITE_HAS_CODEC) |
| 95050 | + { "hexkey", PragTyp_HEXKEY, 0 }, |
| 95051 | +#endif |
| 95052 | +#if !defined(SQLITE_OMIT_CHECK) |
| 95053 | + { "ignore_check_constraints", PragTyp_FLAG, |
| 95054 | + SQLITE_IgnoreChecks }, |
| 95055 | +#endif |
| 95056 | +#if !defined(SQLITE_OMIT_AUTOVACUUM) |
| 95057 | + { "incremental_vacuum", PragTyp_INCREMENTAL_VACUUM, 0 }, |
| 95058 | +#endif |
| 95059 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95060 | + { "index_info", PragTyp_INDEX_INFO, 0 }, |
| 95061 | + { "index_list", PragTyp_INDEX_LIST, 0 }, |
| 95062 | +#endif |
| 95063 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95064 | + { "integrity_check", PragTyp_INTEGRITY_CHECK, 0 }, |
| 95065 | +#endif |
| 95066 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95067 | + { "journal_mode", PragTyp_JOURNAL_MODE, 0 }, |
| 95068 | + { "journal_size_limit", PragTyp_JOURNAL_SIZE_LIMIT, 0 }, |
| 95069 | +#endif |
| 95070 | +#if defined(SQLITE_HAS_CODEC) |
| 95071 | + { "key", PragTyp_KEY, 0 }, |
| 95072 | +#endif |
| 95073 | + { "legacy_file_format", PragTyp_FLAG, |
| 95074 | + SQLITE_LegacyFileFmt }, |
| 95075 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE |
| 95076 | + { "lock_proxy_file", PragTyp_LOCK_PROXY_FILE, 0 }, |
| 95077 | +#endif |
| 95078 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 95079 | + { "lock_status", PragTyp_LOCK_STATUS, 0 }, |
| 95080 | +#endif |
| 95081 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95082 | + { "locking_mode", PragTyp_LOCKING_MODE, 0 }, |
| 95083 | + { "max_page_count", PragTyp_PAGE_COUNT, 0 }, |
| 95084 | + { "mmap_size", PragTyp_MMAP_SIZE, 0 }, |
| 95085 | + { "page_count", PragTyp_PAGE_COUNT, 0 }, |
| 95086 | + { "page_size", PragTyp_PAGE_SIZE, 0 }, |
| 95087 | +#endif |
| 95088 | +#if defined(SQLITE_DEBUG) |
| 95089 | + { "parser_trace", PragTyp_PARSER_TRACE, 0 }, |
| 95090 | +#endif |
| 95091 | + { "query_only", PragTyp_FLAG, |
| 95092 | + SQLITE_QueryOnly }, |
| 95093 | +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) |
| 95094 | + { "quick_check", PragTyp_INTEGRITY_CHECK, 0 }, |
| 95095 | +#endif |
| 95096 | + { "read_uncommitted", PragTyp_FLAG, |
| 95097 | + SQLITE_ReadUncommitted }, |
| 95098 | + { "recursive_triggers", PragTyp_FLAG, |
| 95099 | + SQLITE_RecTriggers }, |
| 95100 | +#if defined(SQLITE_HAS_CODEC) |
| 95101 | + { "rekey", PragTyp_REKEY, 0 }, |
| 95102 | +#endif |
| 95103 | + { "reverse_unordered_selects", PragTyp_FLAG, |
| 95104 | + SQLITE_ReverseOrder }, |
| 95105 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95106 | + { "schema_version", PragTyp_HEADER_VALUE, 0 }, |
| 95107 | +#endif |
| 95108 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95109 | + { "secure_delete", PragTyp_SECURE_DELETE, 0 }, |
| 95110 | +#endif |
| 95111 | + { "short_column_names", PragTyp_FLAG, |
| 95112 | + SQLITE_ShortColNames }, |
| 95113 | + { "shrink_memory", PragTyp_SHRINK_MEMORY, 0 }, |
| 95114 | + { "soft_heap_limit", PragTyp_SOFT_HEAP_LIMIT, 0 }, |
| 95115 | +#if defined(SQLITE_DEBUG) |
| 95116 | + { "sql_trace", PragTyp_FLAG, |
| 95117 | + SQLITE_SqlTrace }, |
| 95118 | +#endif |
| 95119 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95120 | + { "synchronous", PragTyp_SYNCHRONOUS, 0 }, |
| 95121 | +#endif |
| 95122 | +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) |
| 95123 | + { "table_info", PragTyp_TABLE_INFO, 0 }, |
| 95124 | +#endif |
| 95125 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95126 | + { "temp_store", PragTyp_TEMP_STORE, 0 }, |
| 95127 | + { "temp_store_directory", PragTyp_TEMP_STORE_DIRECTORY, 0 }, |
| 95128 | +#endif |
| 95129 | +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) |
| 95130 | + { "user_version", PragTyp_HEADER_VALUE, 0 }, |
| 95131 | +#endif |
| 95132 | +#if defined(SQLITE_DEBUG) |
| 95133 | + { "vdbe_addoptrace", PragTyp_FLAG, |
| 95134 | + SQLITE_VdbeAddopTrace }, |
| 95135 | + { "vdbe_debug", PragTyp_FLAG, |
| 95136 | + SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 95137 | + { "vdbe_listing", PragTyp_FLAG, |
| 95138 | + SQLITE_VdbeListing }, |
| 95139 | + { "vdbe_trace", PragTyp_FLAG, |
| 95140 | + SQLITE_VdbeTrace }, |
| 95141 | +#endif |
| 95142 | +#if !defined(SQLITE_OMIT_WAL) |
| 95143 | + { "wal_autocheckpoint", PragTyp_WAL_AUTOCHECKPOINT, 0 }, |
| 95144 | + { "wal_checkpoint", PragTyp_WAL_CHECKPOINT, 0 }, |
| 95145 | +#endif |
| 95146 | + { "writable_schema", PragTyp_FLAG, |
| 95147 | + SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 95148 | +}; |
| 95149 | +/* Number of pragmas: 55 on by default, 66 total. */ |
| 95150 | +/* End of the automatically generated pragma table. |
| 95151 | +***************************************************************************/ |
| 95152 | + |
| 94767 | 95153 | /* |
| 94768 | 95154 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 94769 | 95155 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or |
| 94770 | 95156 | ** unrecognized string argument. The FULL option is disallowed |
| 94771 | 95157 | ** if the omitFull parameter it 1. |
| | @@ -94937,101 +95323,10 @@ |
| 94937 | 95323 | #else |
| 94938 | 95324 | # define setAllPagerFlags(X) /* no-op */ |
| 94939 | 95325 | #endif |
| 94940 | 95326 | |
| 94941 | 95327 | |
| 94942 | | -#ifndef SQLITE_OMIT_FLAG_PRAGMAS |
| 94943 | | -/* |
| 94944 | | -** Check to see if zRight and zLeft refer to a pragma that queries |
| 94945 | | -** or changes one of the flags in db->flags. Return 1 if so and 0 if not. |
| 94946 | | -** Also, implement the pragma. |
| 94947 | | -*/ |
| 94948 | | -static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ |
| 94949 | | - static const struct sPragmaType { |
| 94950 | | - const char *zName; /* Name of the pragma */ |
| 94951 | | - int mask; /* Mask for the db->flags value */ |
| 94952 | | - } aPragma[] = { |
| 94953 | | - { "full_column_names", SQLITE_FullColNames }, |
| 94954 | | - { "short_column_names", SQLITE_ShortColNames }, |
| 94955 | | - { "count_changes", SQLITE_CountRows }, |
| 94956 | | - { "empty_result_callbacks", SQLITE_NullCallback }, |
| 94957 | | - { "legacy_file_format", SQLITE_LegacyFileFmt }, |
| 94958 | | - { "fullfsync", SQLITE_FullFSync }, |
| 94959 | | - { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, |
| 94960 | | - { "cache_spill", SQLITE_CacheSpill }, |
| 94961 | | - { "reverse_unordered_selects", SQLITE_ReverseOrder }, |
| 94962 | | - { "query_only", SQLITE_QueryOnly }, |
| 94963 | | -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 94964 | | - { "automatic_index", SQLITE_AutoIndex }, |
| 94965 | | -#endif |
| 94966 | | -#ifdef SQLITE_DEBUG |
| 94967 | | - { "sql_trace", SQLITE_SqlTrace }, |
| 94968 | | - { "vdbe_listing", SQLITE_VdbeListing }, |
| 94969 | | - { "vdbe_trace", SQLITE_VdbeTrace }, |
| 94970 | | - { "vdbe_addoptrace", SQLITE_VdbeAddopTrace}, |
| 94971 | | - { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing |
| 94972 | | - | SQLITE_VdbeTrace }, |
| 94973 | | -#endif |
| 94974 | | -#ifndef SQLITE_OMIT_CHECK |
| 94975 | | - { "ignore_check_constraints", SQLITE_IgnoreChecks }, |
| 94976 | | -#endif |
| 94977 | | - /* The following is VERY experimental */ |
| 94978 | | - { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 94979 | | - |
| 94980 | | - /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted |
| 94981 | | - ** flag if there are any active statements. */ |
| 94982 | | - { "read_uncommitted", SQLITE_ReadUncommitted }, |
| 94983 | | - { "recursive_triggers", SQLITE_RecTriggers }, |
| 94984 | | - |
| 94985 | | - /* This flag may only be set if both foreign-key and trigger support |
| 94986 | | - ** are present in the build. */ |
| 94987 | | -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) |
| 94988 | | - { "foreign_keys", SQLITE_ForeignKeys }, |
| 94989 | | - { "defer_foreign_keys", SQLITE_DeferFKs }, |
| 94990 | | -#endif |
| 94991 | | - }; |
| 94992 | | - int i; |
| 94993 | | - const struct sPragmaType *p; |
| 94994 | | - for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){ |
| 94995 | | - if( sqlite3StrICmp(zLeft, p->zName)==0 ){ |
| 94996 | | - sqlite3 *db = pParse->db; |
| 94997 | | - Vdbe *v; |
| 94998 | | - v = sqlite3GetVdbe(pParse); |
| 94999 | | - assert( v!=0 ); /* Already allocated by sqlite3Pragma() */ |
| 95000 | | - if( ALWAYS(v) ){ |
| 95001 | | - if( zRight==0 ){ |
| 95002 | | - returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); |
| 95003 | | - }else{ |
| 95004 | | - int mask = p->mask; /* Mask of bits to set or clear. */ |
| 95005 | | - if( db->autoCommit==0 ){ |
| 95006 | | - /* Foreign key support may not be enabled or disabled while not |
| 95007 | | - ** in auto-commit mode. */ |
| 95008 | | - mask &= ~(SQLITE_ForeignKeys); |
| 95009 | | - } |
| 95010 | | - |
| 95011 | | - if( sqlite3GetBoolean(zRight, 0) ){ |
| 95012 | | - db->flags |= mask; |
| 95013 | | - }else{ |
| 95014 | | - db->flags &= ~mask; |
| 95015 | | - if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; |
| 95016 | | - } |
| 95017 | | - |
| 95018 | | - /* Many of the flag-pragmas modify the code generated by the SQL |
| 95019 | | - ** compiler (eg. count_changes). So add an opcode to expire all |
| 95020 | | - ** compiled SQL statements after modifying a pragma value. |
| 95021 | | - */ |
| 95022 | | - sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); |
| 95023 | | - } |
| 95024 | | - } |
| 95025 | | - |
| 95026 | | - return 1; |
| 95027 | | - } |
| 95028 | | - } |
| 95029 | | - return 0; |
| 95030 | | -} |
| 95031 | | -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ |
| 95032 | | - |
| 95033 | 95328 | /* |
| 95034 | 95329 | ** Return a human-readable name for a constraint resolution action. |
| 95035 | 95330 | */ |
| 95036 | 95331 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 95037 | 95332 | static const char *actionName(u8 action){ |
| | @@ -95097,12 +95392,13 @@ |
| 95097 | 95392 | ){ |
| 95098 | 95393 | char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */ |
| 95099 | 95394 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ |
| 95100 | 95395 | const char *zDb = 0; /* The database name */ |
| 95101 | 95396 | Token *pId; /* Pointer to <id> token */ |
| 95102 | | - int iDb; /* Database index for <database> */ |
| 95103 | 95397 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 95398 | + int iDb; /* Database index for <database> */ |
| 95399 | + int lwr, upr, mid; /* Binary search bounds */ |
| 95104 | 95400 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 95105 | 95401 | sqlite3 *db = pParse->db; /* The database connection */ |
| 95106 | 95402 | Db *pDb; /* The specific database being pragmaed */ |
| 95107 | 95403 | Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 95108 | 95404 | |
| | @@ -95154,20 +95450,40 @@ |
| 95154 | 95450 | sqlite3VdbeSetNumCols(v, 1); |
| 95155 | 95451 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC); |
| 95156 | 95452 | sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); |
| 95157 | 95453 | sqlite3_free(aFcntl[0]); |
| 95158 | 95454 | } |
| 95159 | | - }else if( rc!=SQLITE_NOTFOUND ){ |
| 95455 | + goto pragma_out; |
| 95456 | + } |
| 95457 | + if( rc!=SQLITE_NOTFOUND ){ |
| 95160 | 95458 | if( aFcntl[0] ){ |
| 95161 | 95459 | sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); |
| 95162 | 95460 | sqlite3_free(aFcntl[0]); |
| 95163 | 95461 | } |
| 95164 | 95462 | pParse->nErr++; |
| 95165 | 95463 | pParse->rc = rc; |
| 95166 | | - }else |
| 95167 | | - |
| 95168 | | - |
| 95464 | + goto pragma_out; |
| 95465 | + } |
| 95466 | + |
| 95467 | + /* Locate the pragma in the lookup table */ |
| 95468 | + lwr = 0; |
| 95469 | + upr = ArraySize(aPragmaNames)-1; |
| 95470 | + while( lwr<=upr ){ |
| 95471 | + mid = (lwr+upr)/2; |
| 95472 | + rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); |
| 95473 | + if( rc==0 ) break; |
| 95474 | + if( rc<0 ){ |
| 95475 | + upr = mid - 1; |
| 95476 | + }else{ |
| 95477 | + lwr = mid + 1; |
| 95478 | + } |
| 95479 | + } |
| 95480 | + if( lwr>upr ) goto pragma_out; |
| 95481 | + |
| 95482 | + /* Jump to the appropriate pragma handler */ |
| 95483 | + switch( aPragmaNames[mid].ePragTyp ){ |
| 95484 | + |
| 95169 | 95485 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) |
| 95170 | 95486 | /* |
| 95171 | 95487 | ** PRAGMA [database.]default_cache_size |
| 95172 | 95488 | ** PRAGMA [database.]default_cache_size=N |
| 95173 | 95489 | ** |
| | @@ -95181,11 +95497,11 @@ |
| 95181 | 95497 | ** negative number to indicate synchronous=OFF. These days, synchronous |
| 95182 | 95498 | ** is always on by default regardless of the sign of the default cache |
| 95183 | 95499 | ** size. But continue to take the absolute value of the default cache |
| 95184 | 95500 | ** size of historical compatibility. |
| 95185 | 95501 | */ |
| 95186 | | - if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ |
| 95502 | + case PragTyp_DEFAULT_CACHE_SIZE: { |
| 95187 | 95503 | static const VdbeOpList getCacheSize[] = { |
| 95188 | 95504 | { OP_Transaction, 0, 0, 0}, /* 0 */ |
| 95189 | 95505 | { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ |
| 95190 | 95506 | { OP_IfPos, 1, 8, 0}, |
| 95191 | 95507 | { OP_Integer, 0, 2, 0}, |
| | @@ -95213,11 +95529,12 @@ |
| 95213 | 95529 | sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); |
| 95214 | 95530 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95215 | 95531 | pDb->pSchema->cache_size = size; |
| 95216 | 95532 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 95217 | 95533 | } |
| 95218 | | - }else |
| 95534 | + break; |
| 95535 | + } |
| 95219 | 95536 | #endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ |
| 95220 | 95537 | |
| 95221 | 95538 | #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) |
| 95222 | 95539 | /* |
| 95223 | 95540 | ** PRAGMA [database.]page_size |
| | @@ -95226,11 +95543,11 @@ |
| 95226 | 95543 | ** The first form reports the current setting for the |
| 95227 | 95544 | ** database page size in bytes. The second form sets the |
| 95228 | 95545 | ** database page size value. The value can only be set if |
| 95229 | 95546 | ** the database has not yet been created. |
| 95230 | 95547 | */ |
| 95231 | | - if( sqlite3StrICmp(zLeft,"page_size")==0 ){ |
| 95548 | + case PragTyp_PAGE_SIZE: { |
| 95232 | 95549 | Btree *pBt = pDb->pBt; |
| 95233 | 95550 | assert( pBt!=0 ); |
| 95234 | 95551 | if( !zRight ){ |
| 95235 | 95552 | int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; |
| 95236 | 95553 | returnSingleInt(pParse, "page_size", size); |
| | @@ -95241,21 +95558,22 @@ |
| 95241 | 95558 | db->nextPagesize = sqlite3Atoi(zRight); |
| 95242 | 95559 | if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ |
| 95243 | 95560 | db->mallocFailed = 1; |
| 95244 | 95561 | } |
| 95245 | 95562 | } |
| 95246 | | - }else |
| 95563 | + break; |
| 95564 | + } |
| 95247 | 95565 | |
| 95248 | 95566 | /* |
| 95249 | 95567 | ** PRAGMA [database.]secure_delete |
| 95250 | 95568 | ** PRAGMA [database.]secure_delete=ON/OFF |
| 95251 | 95569 | ** |
| 95252 | 95570 | ** The first form reports the current setting for the |
| 95253 | 95571 | ** secure_delete flag. The second form changes the secure_delete |
| 95254 | 95572 | ** flag setting and reports thenew value. |
| 95255 | 95573 | */ |
| 95256 | | - if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){ |
| 95574 | + case PragTyp_SECURE_DELETE: { |
| 95257 | 95575 | Btree *pBt = pDb->pBt; |
| 95258 | 95576 | int b = -1; |
| 95259 | 95577 | assert( pBt!=0 ); |
| 95260 | 95578 | if( zRight ){ |
| 95261 | 95579 | b = sqlite3GetBoolean(zRight, 0); |
| | @@ -95266,11 +95584,12 @@ |
| 95266 | 95584 | sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); |
| 95267 | 95585 | } |
| 95268 | 95586 | } |
| 95269 | 95587 | b = sqlite3BtreeSecureDelete(pBt, b); |
| 95270 | 95588 | returnSingleInt(pParse, "secure_delete", b); |
| 95271 | | - }else |
| 95589 | + break; |
| 95590 | + } |
| 95272 | 95591 | |
| 95273 | 95592 | /* |
| 95274 | 95593 | ** PRAGMA [database.]max_page_count |
| 95275 | 95594 | ** PRAGMA [database.]max_page_count=N |
| 95276 | 95595 | ** |
| | @@ -95285,13 +95604,11 @@ |
| 95285 | 95604 | ** |
| 95286 | 95605 | ** PRAGMA [database.]page_count |
| 95287 | 95606 | ** |
| 95288 | 95607 | ** Return the number of pages in the specified database. |
| 95289 | 95608 | */ |
| 95290 | | - if( sqlite3StrICmp(zLeft,"page_count")==0 |
| 95291 | | - || sqlite3StrICmp(zLeft,"max_page_count")==0 |
| 95292 | | - ){ |
| 95609 | + case PragTyp_PAGE_COUNT: { |
| 95293 | 95610 | int iReg; |
| 95294 | 95611 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95295 | 95612 | sqlite3CodeVerifySchema(pParse, iDb); |
| 95296 | 95613 | iReg = ++pParse->nMem; |
| 95297 | 95614 | if( sqlite3Tolower(zLeft[0])=='p' ){ |
| | @@ -95301,17 +95618,18 @@ |
| 95301 | 95618 | sqlite3AbsInt32(sqlite3Atoi(zRight))); |
| 95302 | 95619 | } |
| 95303 | 95620 | sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); |
| 95304 | 95621 | sqlite3VdbeSetNumCols(v, 1); |
| 95305 | 95622 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); |
| 95306 | | - }else |
| 95623 | + break; |
| 95624 | + } |
| 95307 | 95625 | |
| 95308 | 95626 | /* |
| 95309 | 95627 | ** PRAGMA [database.]locking_mode |
| 95310 | 95628 | ** PRAGMA [database.]locking_mode = (normal|exclusive) |
| 95311 | 95629 | */ |
| 95312 | | - if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ |
| 95630 | + case PragTyp_LOCKING_MODE: { |
| 95313 | 95631 | const char *zRet = "normal"; |
| 95314 | 95632 | int eMode = getLockingMode(zRight); |
| 95315 | 95633 | |
| 95316 | 95634 | if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ |
| 95317 | 95635 | /* Simple "PRAGMA locking_mode;" statement. This is a query for |
| | @@ -95340,26 +95658,28 @@ |
| 95340 | 95658 | } |
| 95341 | 95659 | pPager = sqlite3BtreePager(pDb->pBt); |
| 95342 | 95660 | eMode = sqlite3PagerLockingMode(pPager, eMode); |
| 95343 | 95661 | } |
| 95344 | 95662 | |
| 95345 | | - assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); |
| 95663 | + assert( eMode==PAGER_LOCKINGMODE_NORMAL |
| 95664 | + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); |
| 95346 | 95665 | if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ |
| 95347 | 95666 | zRet = "exclusive"; |
| 95348 | 95667 | } |
| 95349 | 95668 | sqlite3VdbeSetNumCols(v, 1); |
| 95350 | 95669 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC); |
| 95351 | 95670 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0); |
| 95352 | 95671 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 95353 | | - }else |
| 95672 | + break; |
| 95673 | + } |
| 95354 | 95674 | |
| 95355 | 95675 | /* |
| 95356 | 95676 | ** PRAGMA [database.]journal_mode |
| 95357 | 95677 | ** PRAGMA [database.]journal_mode = |
| 95358 | 95678 | ** (delete|persist|off|truncate|memory|wal|off) |
| 95359 | 95679 | */ |
| 95360 | | - if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ |
| 95680 | + case PragTyp_JOURNAL_MODE: { |
| 95361 | 95681 | int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 95362 | 95682 | int ii; /* Loop counter */ |
| 95363 | 95683 | |
| 95364 | 95684 | /* Force the schema to be loaded on all databases. This causes all |
| 95365 | 95685 | ** database files to be opened and the journal_modes set. This is |
| | @@ -95398,28 +95718,30 @@ |
| 95398 | 95718 | sqlite3VdbeUsesBtree(v, ii); |
| 95399 | 95719 | sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); |
| 95400 | 95720 | } |
| 95401 | 95721 | } |
| 95402 | 95722 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 95403 | | - }else |
| 95723 | + break; |
| 95724 | + } |
| 95404 | 95725 | |
| 95405 | 95726 | /* |
| 95406 | 95727 | ** PRAGMA [database.]journal_size_limit |
| 95407 | 95728 | ** PRAGMA [database.]journal_size_limit=N |
| 95408 | 95729 | ** |
| 95409 | 95730 | ** Get or set the size limit on rollback journal files. |
| 95410 | 95731 | */ |
| 95411 | | - if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 95732 | + case PragTyp_JOURNAL_SIZE_LIMIT: { |
| 95412 | 95733 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 95413 | 95734 | i64 iLimit = -2; |
| 95414 | 95735 | if( zRight ){ |
| 95415 | 95736 | sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 95416 | 95737 | if( iLimit<-1 ) iLimit = -1; |
| 95417 | 95738 | } |
| 95418 | 95739 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 95419 | 95740 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 95420 | | - }else |
| 95741 | + break; |
| 95742 | + } |
| 95421 | 95743 | |
| 95422 | 95744 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
| 95423 | 95745 | |
| 95424 | 95746 | /* |
| 95425 | 95747 | ** PRAGMA [database.]auto_vacuum |
| | @@ -95427,11 +95749,11 @@ |
| 95427 | 95749 | ** |
| 95428 | 95750 | ** Get or set the value of the database 'auto-vacuum' parameter. |
| 95429 | 95751 | ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL |
| 95430 | 95752 | */ |
| 95431 | 95753 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95432 | | - if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ |
| 95754 | + case PragTyp_AUTO_VACUUM: { |
| 95433 | 95755 | Btree *pBt = pDb->pBt; |
| 95434 | 95756 | assert( pBt!=0 ); |
| 95435 | 95757 | if( sqlite3ReadSchema(pParse) ){ |
| 95436 | 95758 | goto pragma_out; |
| 95437 | 95759 | } |
| | @@ -95477,20 +95799,21 @@ |
| 95477 | 95799 | sqlite3VdbeChangeP1(v, iAddr+5, iDb); |
| 95478 | 95800 | sqlite3VdbeUsesBtree(v, iDb); |
| 95479 | 95801 | } |
| 95480 | 95802 | } |
| 95481 | 95803 | } |
| 95482 | | - }else |
| 95804 | + break; |
| 95805 | + } |
| 95483 | 95806 | #endif |
| 95484 | 95807 | |
| 95485 | 95808 | /* |
| 95486 | 95809 | ** PRAGMA [database.]incremental_vacuum(N) |
| 95487 | 95810 | ** |
| 95488 | 95811 | ** Do N steps of incremental vacuuming on a database. |
| 95489 | 95812 | */ |
| 95490 | 95813 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 95491 | | - if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){ |
| 95814 | + case PragTyp_INCREMENTAL_VACUUM: { |
| 95492 | 95815 | int iLimit, addr; |
| 95493 | 95816 | if( sqlite3ReadSchema(pParse) ){ |
| 95494 | 95817 | goto pragma_out; |
| 95495 | 95818 | } |
| 95496 | 95819 | if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ |
| | @@ -95501,11 +95824,12 @@ |
| 95501 | 95824 | addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); |
| 95502 | 95825 | sqlite3VdbeAddOp1(v, OP_ResultRow, 1); |
| 95503 | 95826 | sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); |
| 95504 | 95827 | sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); |
| 95505 | 95828 | sqlite3VdbeJumpHere(v, addr); |
| 95506 | | - }else |
| 95829 | + break; |
| 95830 | + } |
| 95507 | 95831 | #endif |
| 95508 | 95832 | |
| 95509 | 95833 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 95510 | 95834 | /* |
| 95511 | 95835 | ** PRAGMA [database.]cache_size |
| | @@ -95516,21 +95840,22 @@ |
| 95516 | 95840 | ** page cache size value. If N is positive then that is the |
| 95517 | 95841 | ** number of pages in the cache. If N is negative, then the |
| 95518 | 95842 | ** number of pages is adjusted so that the cache uses -N kibibytes |
| 95519 | 95843 | ** of memory. |
| 95520 | 95844 | */ |
| 95521 | | - if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ |
| 95845 | + case PragTyp_CACHE_SIZE: { |
| 95522 | 95846 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95523 | 95847 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95524 | 95848 | if( !zRight ){ |
| 95525 | 95849 | returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); |
| 95526 | 95850 | }else{ |
| 95527 | 95851 | int size = sqlite3Atoi(zRight); |
| 95528 | 95852 | pDb->pSchema->cache_size = size; |
| 95529 | 95853 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
| 95530 | 95854 | } |
| 95531 | | - }else |
| 95855 | + break; |
| 95856 | + } |
| 95532 | 95857 | |
| 95533 | 95858 | /* |
| 95534 | 95859 | ** PRAGMA [database.]mmap_size(N) |
| 95535 | 95860 | ** |
| 95536 | 95861 | ** Used to set mapping size limit. The mapping size limit is |
| | @@ -95542,11 +95867,11 @@ |
| 95542 | 95867 | ** |
| 95543 | 95868 | ** This value is advisory. The underlying VFS is free to memory map |
| 95544 | 95869 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 95545 | 95870 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 95546 | 95871 | */ |
| 95547 | | - if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 95872 | + case PragTyp_MMAP_SIZE: { |
| 95548 | 95873 | sqlite3_int64 sz; |
| 95549 | 95874 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 95550 | 95875 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95551 | 95876 | if( zRight ){ |
| 95552 | 95877 | int ii; |
| | @@ -95569,11 +95894,12 @@ |
| 95569 | 95894 | returnSingleInt(pParse, "mmap_size", sz); |
| 95570 | 95895 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 95571 | 95896 | pParse->nErr++; |
| 95572 | 95897 | pParse->rc = rc; |
| 95573 | 95898 | } |
| 95574 | | - }else |
| 95899 | + break; |
| 95900 | + } |
| 95575 | 95901 | |
| 95576 | 95902 | /* |
| 95577 | 95903 | ** PRAGMA temp_store |
| 95578 | 95904 | ** PRAGMA temp_store = "default"|"memory"|"file" |
| 95579 | 95905 | ** |
| | @@ -95582,17 +95908,18 @@ |
| 95582 | 95908 | ** value will be restored the next time the database is opened. |
| 95583 | 95909 | ** |
| 95584 | 95910 | ** Note that it is possible for the library compile-time options to |
| 95585 | 95911 | ** override this setting |
| 95586 | 95912 | */ |
| 95587 | | - if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ |
| 95913 | + case PragTyp_TEMP_STORE: { |
| 95588 | 95914 | if( !zRight ){ |
| 95589 | 95915 | returnSingleInt(pParse, "temp_store", db->temp_store); |
| 95590 | 95916 | }else{ |
| 95591 | 95917 | changeTempStorage(pParse, zRight); |
| 95592 | 95918 | } |
| 95593 | | - }else |
| 95919 | + break; |
| 95920 | + } |
| 95594 | 95921 | |
| 95595 | 95922 | /* |
| 95596 | 95923 | ** PRAGMA temp_store_directory |
| 95597 | 95924 | ** PRAGMA temp_store_directory = ""|"directory_name" |
| 95598 | 95925 | ** |
| | @@ -95600,11 +95927,11 @@ |
| 95600 | 95927 | ** the value sets a specific directory to be used for temporary files. |
| 95601 | 95928 | ** Setting to a null string reverts to the default temporary directory search. |
| 95602 | 95929 | ** If temporary directory is changed, then invalidateTempStorage. |
| 95603 | 95930 | ** |
| 95604 | 95931 | */ |
| 95605 | | - if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ |
| 95932 | + case PragTyp_TEMP_STORE_DIRECTORY: { |
| 95606 | 95933 | if( !zRight ){ |
| 95607 | 95934 | if( sqlite3_temp_directory ){ |
| 95608 | 95935 | sqlite3VdbeSetNumCols(v, 1); |
| 95609 | 95936 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, |
| 95610 | 95937 | "temp_store_directory", SQLITE_STATIC); |
| | @@ -95633,11 +95960,12 @@ |
| 95633 | 95960 | }else{ |
| 95634 | 95961 | sqlite3_temp_directory = 0; |
| 95635 | 95962 | } |
| 95636 | 95963 | #endif /* SQLITE_OMIT_WSD */ |
| 95637 | 95964 | } |
| 95638 | | - }else |
| 95965 | + break; |
| 95966 | + } |
| 95639 | 95967 | |
| 95640 | 95968 | #if SQLITE_OS_WIN |
| 95641 | 95969 | /* |
| 95642 | 95970 | ** PRAGMA data_store_directory |
| 95643 | 95971 | ** PRAGMA data_store_directory = ""|"directory_name" |
| | @@ -95649,11 +95977,11 @@ |
| 95649 | 95977 | ** a relative path will probably be based on the current directory for the |
| 95650 | 95978 | ** process. Database file specified with an absolute path are not impacted |
| 95651 | 95979 | ** by this setting, regardless of its value. |
| 95652 | 95980 | ** |
| 95653 | 95981 | */ |
| 95654 | | - if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){ |
| 95982 | + case PragTyp_DATA_STORE_DIRECTORY: { |
| 95655 | 95983 | if( !zRight ){ |
| 95656 | 95984 | if( sqlite3_data_directory ){ |
| 95657 | 95985 | sqlite3VdbeSetNumCols(v, 1); |
| 95658 | 95986 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, |
| 95659 | 95987 | "data_store_directory", SQLITE_STATIC); |
| | @@ -95676,30 +96004,24 @@ |
| 95676 | 96004 | }else{ |
| 95677 | 96005 | sqlite3_data_directory = 0; |
| 95678 | 96006 | } |
| 95679 | 96007 | #endif /* SQLITE_OMIT_WSD */ |
| 95680 | 96008 | } |
| 95681 | | - }else |
| 96009 | + break; |
| 96010 | + } |
| 95682 | 96011 | #endif |
| 95683 | 96012 | |
| 95684 | | -#if !defined(SQLITE_ENABLE_LOCKING_STYLE) |
| 95685 | | -# if defined(__APPLE__) |
| 95686 | | -# define SQLITE_ENABLE_LOCKING_STYLE 1 |
| 95687 | | -# else |
| 95688 | | -# define SQLITE_ENABLE_LOCKING_STYLE 0 |
| 95689 | | -# endif |
| 95690 | | -#endif |
| 95691 | 96013 | #if SQLITE_ENABLE_LOCKING_STYLE |
| 95692 | 96014 | /* |
| 95693 | | - ** PRAGMA [database.]lock_proxy_file |
| 95694 | | - ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" |
| 95695 | | - ** |
| 95696 | | - ** Return or set the value of the lock_proxy_file flag. Changing |
| 95697 | | - ** the value sets a specific file to be used for database access locks. |
| 95698 | | - ** |
| 95699 | | - */ |
| 95700 | | - if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){ |
| 96015 | + ** PRAGMA [database.]lock_proxy_file |
| 96016 | + ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path" |
| 96017 | + ** |
| 96018 | + ** Return or set the value of the lock_proxy_file flag. Changing |
| 96019 | + ** the value sets a specific file to be used for database access locks. |
| 96020 | + ** |
| 96021 | + */ |
| 96022 | + case PragTyp_LOCK_PROXY_FILE: { |
| 95701 | 96023 | if( !zRight ){ |
| 95702 | 96024 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 95703 | 96025 | char *proxy_file_path = NULL; |
| 95704 | 96026 | sqlite3_file *pFile = sqlite3PagerFile(pPager); |
| 95705 | 96027 | sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, |
| | @@ -95726,11 +96048,12 @@ |
| 95726 | 96048 | if( res!=SQLITE_OK ){ |
| 95727 | 96049 | sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); |
| 95728 | 96050 | goto pragma_out; |
| 95729 | 96051 | } |
| 95730 | 96052 | } |
| 95731 | | - }else |
| 96053 | + break; |
| 96054 | + } |
| 95732 | 96055 | #endif /* SQLITE_ENABLE_LOCKING_STYLE */ |
| 95733 | 96056 | |
| 95734 | 96057 | /* |
| 95735 | 96058 | ** PRAGMA [database.]synchronous |
| 95736 | 96059 | ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL |
| | @@ -95738,11 +96061,11 @@ |
| 95738 | 96061 | ** Return or set the local value of the synchronous flag. Changing |
| 95739 | 96062 | ** the local value does not make changes to the disk file and the |
| 95740 | 96063 | ** default value will be restored the next time the database is |
| 95741 | 96064 | ** opened. |
| 95742 | 96065 | */ |
| 95743 | | - if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ |
| 96066 | + case PragTyp_SYNCHRONOUS: { |
| 95744 | 96067 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95745 | 96068 | if( !zRight ){ |
| 95746 | 96069 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); |
| 95747 | 96070 | }else{ |
| 95748 | 96071 | if( !db->autoCommit ){ |
| | @@ -95751,17 +96074,43 @@ |
| 95751 | 96074 | }else{ |
| 95752 | 96075 | pDb->safety_level = getSafetyLevel(zRight,0,1)+1; |
| 95753 | 96076 | setAllPagerFlags(db); |
| 95754 | 96077 | } |
| 95755 | 96078 | } |
| 95756 | | - }else |
| 96079 | + break; |
| 96080 | + } |
| 95757 | 96081 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
| 95758 | 96082 | |
| 95759 | 96083 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS |
| 95760 | | - if( flagPragma(pParse, zLeft, zRight) ){ |
| 95761 | | - setAllPagerFlags(db); |
| 95762 | | - }else |
| 96084 | + case PragTyp_FLAG: { |
| 96085 | + if( zRight==0 ){ |
| 96086 | + returnSingleInt(pParse, aPragmaNames[mid].zName, |
| 96087 | + (db->flags & aPragmaNames[mid].iArg)!=0 ); |
| 96088 | + }else{ |
| 96089 | + int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */ |
| 96090 | + if( db->autoCommit==0 ){ |
| 96091 | + /* Foreign key support may not be enabled or disabled while not |
| 96092 | + ** in auto-commit mode. */ |
| 96093 | + mask &= ~(SQLITE_ForeignKeys); |
| 96094 | + } |
| 96095 | + |
| 96096 | + if( sqlite3GetBoolean(zRight, 0) ){ |
| 96097 | + db->flags |= mask; |
| 96098 | + }else{ |
| 96099 | + db->flags &= ~mask; |
| 96100 | + if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; |
| 96101 | + } |
| 96102 | + |
| 96103 | + /* Many of the flag-pragmas modify the code generated by the SQL |
| 96104 | + ** compiler (eg. count_changes). So add an opcode to expire all |
| 96105 | + ** compiled SQL statements after modifying a pragma value. |
| 96106 | + */ |
| 96107 | + sqlite3VdbeAddOp2(v, OP_Expire, 0, 0); |
| 96108 | + setAllPagerFlags(db); |
| 96109 | + } |
| 96110 | + break; |
| 96111 | + } |
| 95763 | 96112 | #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ |
| 95764 | 96113 | |
| 95765 | 96114 | #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS |
| 95766 | 96115 | /* |
| 95767 | 96116 | ** PRAGMA table_info(<table>) |
| | @@ -95773,11 +96122,11 @@ |
| 95773 | 96122 | ** name: Column name |
| 95774 | 96123 | ** type: Column declaration type. |
| 95775 | 96124 | ** notnull: True if 'NOT NULL' is part of column declaration |
| 95776 | 96125 | ** dflt_value: The default value for the column, if any. |
| 95777 | 96126 | */ |
| 95778 | | - if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ |
| 96127 | + case PragTyp_TABLE_INFO: if( zRight ){ |
| 95779 | 96128 | Table *pTab; |
| 95780 | 96129 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95781 | 96130 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 95782 | 96131 | if( pTab ){ |
| 95783 | 96132 | int i, k; |
| | @@ -95819,13 +96168,14 @@ |
| 95819 | 96168 | } |
| 95820 | 96169 | sqlite3VdbeAddOp2(v, OP_Integer, k, 6); |
| 95821 | 96170 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); |
| 95822 | 96171 | } |
| 95823 | 96172 | } |
| 95824 | | - }else |
| 96173 | + } |
| 96174 | + break; |
| 95825 | 96175 | |
| 95826 | | - if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ |
| 96176 | + case PragTyp_INDEX_INFO: if( zRight ){ |
| 95827 | 96177 | Index *pIdx; |
| 95828 | 96178 | Table *pTab; |
| 95829 | 96179 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95830 | 96180 | pIdx = sqlite3FindIndex(db, zRight, zDb); |
| 95831 | 96181 | if( pIdx ){ |
| | @@ -95844,13 +96194,14 @@ |
| 95844 | 96194 | assert( pTab->nCol>cnum ); |
| 95845 | 96195 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0); |
| 95846 | 96196 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 95847 | 96197 | } |
| 95848 | 96198 | } |
| 95849 | | - }else |
| 96199 | + } |
| 96200 | + break; |
| 95850 | 96201 | |
| 95851 | | - if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ |
| 96202 | + case PragTyp_INDEX_LIST: if( zRight ){ |
| 95852 | 96203 | Index *pIdx; |
| 95853 | 96204 | Table *pTab; |
| 95854 | 96205 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95855 | 96206 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 95856 | 96207 | if( pTab ){ |
| | @@ -95872,13 +96223,14 @@ |
| 95872 | 96223 | ++i; |
| 95873 | 96224 | pIdx = pIdx->pNext; |
| 95874 | 96225 | } |
| 95875 | 96226 | } |
| 95876 | 96227 | } |
| 95877 | | - }else |
| 96228 | + } |
| 96229 | + break; |
| 95878 | 96230 | |
| 95879 | | - if( sqlite3StrICmp(zLeft, "database_list")==0 ){ |
| 96231 | + case PragTyp_DATABASE_LIST: { |
| 95880 | 96232 | int i; |
| 95881 | 96233 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95882 | 96234 | sqlite3VdbeSetNumCols(v, 3); |
| 95883 | 96235 | pParse->nMem = 3; |
| 95884 | 96236 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| | @@ -95891,13 +96243,14 @@ |
| 95891 | 96243 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0); |
| 95892 | 96244 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| 95893 | 96245 | sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); |
| 95894 | 96246 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 95895 | 96247 | } |
| 95896 | | - }else |
| 96248 | + } |
| 96249 | + break; |
| 95897 | 96250 | |
| 95898 | | - if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ |
| 96251 | + case PragTyp_COLLATION_LIST: { |
| 95899 | 96252 | int i = 0; |
| 95900 | 96253 | HashElem *p; |
| 95901 | 96254 | sqlite3VdbeSetNumCols(v, 2); |
| 95902 | 96255 | pParse->nMem = 2; |
| 95903 | 96256 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); |
| | @@ -95906,15 +96259,16 @@ |
| 95906 | 96259 | CollSeq *pColl = (CollSeq *)sqliteHashData(p); |
| 95907 | 96260 | sqlite3VdbeAddOp2(v, OP_Integer, i++, 1); |
| 95908 | 96261 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0); |
| 95909 | 96262 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); |
| 95910 | 96263 | } |
| 95911 | | - }else |
| 96264 | + } |
| 96265 | + break; |
| 95912 | 96266 | #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ |
| 95913 | 96267 | |
| 95914 | 96268 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 95915 | | - if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ |
| 96269 | + case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ |
| 95916 | 96270 | FKey *pFK; |
| 95917 | 96271 | Table *pTab; |
| 95918 | 96272 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 95919 | 96273 | pTab = sqlite3FindTable(db, zRight, zDb); |
| 95920 | 96274 | if( pTab ){ |
| | @@ -95953,16 +96307,17 @@ |
| 95953 | 96307 | ++i; |
| 95954 | 96308 | pFK = pFK->pNextFrom; |
| 95955 | 96309 | } |
| 95956 | 96310 | } |
| 95957 | 96311 | } |
| 95958 | | - }else |
| 96312 | + } |
| 96313 | + break; |
| 95959 | 96314 | #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ |
| 95960 | 96315 | |
| 95961 | 96316 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 95962 | 96317 | #ifndef SQLITE_OMIT_TRIGGER |
| 95963 | | - if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){ |
| 96318 | + case PragTyp_FOREIGN_KEY_CHECK: { |
| 95964 | 96319 | FKey *pFK; /* A foreign key constraint */ |
| 95965 | 96320 | Table *pTab; /* Child table contain "REFERENCES" keyword */ |
| 95966 | 96321 | Table *pParent; /* Parent table that child points to */ |
| 95967 | 96322 | Index *pIdx; /* Index in the parent table */ |
| 95968 | 96323 | int i; /* Loop counter: Foreign key number for pTab */ |
| | @@ -96068,34 +96423,37 @@ |
| 96068 | 96423 | sqlite3DbFree(db, aiCols); |
| 96069 | 96424 | } |
| 96070 | 96425 | sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); |
| 96071 | 96426 | sqlite3VdbeJumpHere(v, addrTop); |
| 96072 | 96427 | } |
| 96073 | | - }else |
| 96428 | + } |
| 96429 | + break; |
| 96074 | 96430 | #endif /* !defined(SQLITE_OMIT_TRIGGER) */ |
| 96075 | 96431 | #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ |
| 96076 | 96432 | |
| 96077 | 96433 | #ifndef NDEBUG |
| 96078 | | - if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ |
| 96434 | + case PragTyp_PARSER_TRACE: { |
| 96079 | 96435 | if( zRight ){ |
| 96080 | 96436 | if( sqlite3GetBoolean(zRight, 0) ){ |
| 96081 | 96437 | sqlite3ParserTrace(stderr, "parser: "); |
| 96082 | 96438 | }else{ |
| 96083 | 96439 | sqlite3ParserTrace(0, 0); |
| 96084 | 96440 | } |
| 96085 | 96441 | } |
| 96086 | | - }else |
| 96442 | + } |
| 96443 | + break; |
| 96087 | 96444 | #endif |
| 96088 | 96445 | |
| 96089 | 96446 | /* Reinstall the LIKE and GLOB functions. The variant of LIKE |
| 96090 | 96447 | ** used will be case sensitive or not depending on the RHS. |
| 96091 | 96448 | */ |
| 96092 | | - if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ |
| 96449 | + case PragTyp_CASE_SENSITIVE_LIKE: { |
| 96093 | 96450 | if( zRight ){ |
| 96094 | 96451 | sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); |
| 96095 | 96452 | } |
| 96096 | | - }else |
| 96453 | + } |
| 96454 | + break; |
| 96097 | 96455 | |
| 96098 | 96456 | #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX |
| 96099 | 96457 | # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 |
| 96100 | 96458 | #endif |
| 96101 | 96459 | |
| | @@ -96102,13 +96460,11 @@ |
| 96102 | 96460 | #ifndef SQLITE_OMIT_INTEGRITY_CHECK |
| 96103 | 96461 | /* Pragma "quick_check" is reduced version of |
| 96104 | 96462 | ** integrity_check designed to detect most database corruption |
| 96105 | 96463 | ** without most of the overhead of a full integrity-check. |
| 96106 | 96464 | */ |
| 96107 | | - if( sqlite3StrICmp(zLeft, "integrity_check")==0 |
| 96108 | | - || sqlite3StrICmp(zLeft, "quick_check")==0 |
| 96109 | | - ){ |
| 96465 | + case PragTyp_INTEGRITY_CHECK: { |
| 96110 | 96466 | int i, j, addr, mxErr; |
| 96111 | 96467 | |
| 96112 | 96468 | /* Code that appears at the end of the integrity check. If no error |
| 96113 | 96469 | ** messages have been generated, output OK. Otherwise output the |
| 96114 | 96470 | ** error message |
| | @@ -96264,11 +96620,12 @@ |
| 96264 | 96620 | } |
| 96265 | 96621 | addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); |
| 96266 | 96622 | sqlite3VdbeChangeP2(v, addr, -mxErr); |
| 96267 | 96623 | sqlite3VdbeJumpHere(v, addr+1); |
| 96268 | 96624 | sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); |
| 96269 | | - }else |
| 96625 | + } |
| 96626 | + break; |
| 96270 | 96627 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 96271 | 96628 | |
| 96272 | 96629 | #ifndef SQLITE_OMIT_UTF16 |
| 96273 | 96630 | /* |
| 96274 | 96631 | ** PRAGMA encoding |
| | @@ -96290,11 +96647,11 @@ |
| 96290 | 96647 | ** |
| 96291 | 96648 | ** In the second form this pragma sets the text encoding to be used in |
| 96292 | 96649 | ** new database files created using this database handle. It is only |
| 96293 | 96650 | ** useful if invoked immediately after the main database i |
| 96294 | 96651 | */ |
| 96295 | | - if( sqlite3StrICmp(zLeft, "encoding")==0 ){ |
| 96652 | + case PragTyp_ENCODING: { |
| 96296 | 96653 | static const struct EncName { |
| 96297 | 96654 | char *zName; |
| 96298 | 96655 | u8 enc; |
| 96299 | 96656 | } encnames[] = { |
| 96300 | 96657 | { "UTF8", SQLITE_UTF8 }, |
| | @@ -96337,11 +96694,12 @@ |
| 96337 | 96694 | if( !pEnc->zName ){ |
| 96338 | 96695 | sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); |
| 96339 | 96696 | } |
| 96340 | 96697 | } |
| 96341 | 96698 | } |
| 96342 | | - }else |
| 96699 | + } |
| 96700 | + break; |
| 96343 | 96701 | #endif /* SQLITE_OMIT_UTF16 */ |
| 96344 | 96702 | |
| 96345 | 96703 | #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS |
| 96346 | 96704 | /* |
| 96347 | 96705 | ** PRAGMA [database.]schema_version |
| | @@ -96371,15 +96729,11 @@ |
| 96371 | 96729 | ** crashes or database corruption. Use with caution! |
| 96372 | 96730 | ** |
| 96373 | 96731 | ** The user-version is not used internally by SQLite. It may be used by |
| 96374 | 96732 | ** applications for any purpose. |
| 96375 | 96733 | */ |
| 96376 | | - if( sqlite3StrICmp(zLeft, "schema_version")==0 |
| 96377 | | - || sqlite3StrICmp(zLeft, "user_version")==0 |
| 96378 | | - || sqlite3StrICmp(zLeft, "freelist_count")==0 |
| 96379 | | - || sqlite3StrICmp(zLeft, "application_id")==0 |
| 96380 | | - ){ |
| 96734 | + case PragTyp_HEADER_VALUE: { |
| 96381 | 96735 | int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */ |
| 96382 | 96736 | sqlite3VdbeUsesBtree(v, iDb); |
| 96383 | 96737 | switch( zLeft[0] ){ |
| 96384 | 96738 | case 'a': case 'A': |
| 96385 | 96739 | iCookie = BTREE_APPLICATION_ID; |
| | @@ -96419,40 +96773,42 @@ |
| 96419 | 96773 | sqlite3VdbeChangeP1(v, addr+1, iDb); |
| 96420 | 96774 | sqlite3VdbeChangeP3(v, addr+1, iCookie); |
| 96421 | 96775 | sqlite3VdbeSetNumCols(v, 1); |
| 96422 | 96776 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); |
| 96423 | 96777 | } |
| 96424 | | - }else |
| 96778 | + } |
| 96779 | + break; |
| 96425 | 96780 | #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ |
| 96426 | 96781 | |
| 96427 | 96782 | #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS |
| 96428 | 96783 | /* |
| 96429 | 96784 | ** PRAGMA compile_options |
| 96430 | 96785 | ** |
| 96431 | 96786 | ** Return the names of all compile-time options used in this build, |
| 96432 | 96787 | ** one option per row. |
| 96433 | 96788 | */ |
| 96434 | | - if( sqlite3StrICmp(zLeft, "compile_options")==0 ){ |
| 96789 | + case PragTyp_COMPILE_OPTIONS: { |
| 96435 | 96790 | int i = 0; |
| 96436 | 96791 | const char *zOpt; |
| 96437 | 96792 | sqlite3VdbeSetNumCols(v, 1); |
| 96438 | 96793 | pParse->nMem = 1; |
| 96439 | 96794 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC); |
| 96440 | 96795 | while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ |
| 96441 | 96796 | sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0); |
| 96442 | 96797 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 96443 | 96798 | } |
| 96444 | | - }else |
| 96799 | + } |
| 96800 | + break; |
| 96445 | 96801 | #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ |
| 96446 | 96802 | |
| 96447 | 96803 | #ifndef SQLITE_OMIT_WAL |
| 96448 | 96804 | /* |
| 96449 | 96805 | ** PRAGMA [database.]wal_checkpoint = passive|full|restart |
| 96450 | 96806 | ** |
| 96451 | 96807 | ** Checkpoint the database. |
| 96452 | 96808 | */ |
| 96453 | | - if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){ |
| 96809 | + case PragTyp_WAL_CHECKPOINT: { |
| 96454 | 96810 | int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); |
| 96455 | 96811 | int eMode = SQLITE_CHECKPOINT_PASSIVE; |
| 96456 | 96812 | if( zRight ){ |
| 96457 | 96813 | if( sqlite3StrICmp(zRight, "full")==0 ){ |
| 96458 | 96814 | eMode = SQLITE_CHECKPOINT_FULL; |
| | @@ -96467,39 +96823,42 @@ |
| 96467 | 96823 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC); |
| 96468 | 96824 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC); |
| 96469 | 96825 | |
| 96470 | 96826 | sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); |
| 96471 | 96827 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); |
| 96472 | | - }else |
| 96828 | + } |
| 96829 | + break; |
| 96473 | 96830 | |
| 96474 | 96831 | /* |
| 96475 | 96832 | ** PRAGMA wal_autocheckpoint |
| 96476 | 96833 | ** PRAGMA wal_autocheckpoint = N |
| 96477 | 96834 | ** |
| 96478 | 96835 | ** Configure a database connection to automatically checkpoint a database |
| 96479 | 96836 | ** after accumulating N frames in the log. Or query for the current value |
| 96480 | 96837 | ** of N. |
| 96481 | 96838 | */ |
| 96482 | | - if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){ |
| 96839 | + case PragTyp_WAL_AUTOCHECKPOINT: { |
| 96483 | 96840 | if( zRight ){ |
| 96484 | 96841 | sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); |
| 96485 | 96842 | } |
| 96486 | 96843 | returnSingleInt(pParse, "wal_autocheckpoint", |
| 96487 | 96844 | db->xWalCallback==sqlite3WalDefaultHook ? |
| 96488 | 96845 | SQLITE_PTR_TO_INT(db->pWalArg) : 0); |
| 96489 | | - }else |
| 96846 | + } |
| 96847 | + break; |
| 96490 | 96848 | #endif |
| 96491 | 96849 | |
| 96492 | 96850 | /* |
| 96493 | 96851 | ** PRAGMA shrink_memory |
| 96494 | 96852 | ** |
| 96495 | 96853 | ** This pragma attempts to free as much memory as possible from the |
| 96496 | 96854 | ** current database connection. |
| 96497 | 96855 | */ |
| 96498 | | - if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ |
| 96856 | + case PragTyp_SHRINK_MEMORY: { |
| 96499 | 96857 | sqlite3_db_release_memory(db); |
| 96500 | | - }else |
| 96858 | + break; |
| 96859 | + } |
| 96501 | 96860 | |
| 96502 | 96861 | /* |
| 96503 | 96862 | ** PRAGMA busy_timeout |
| 96504 | 96863 | ** PRAGMA busy_timeout = N |
| 96505 | 96864 | ** |
| | @@ -96506,22 +96865,40 @@ |
| 96506 | 96865 | ** Call sqlite3_busy_timeout(db, N). Return the current timeout value |
| 96507 | 96866 | ** if one is set. If no busy handler or a different busy handler is set |
| 96508 | 96867 | ** then 0 is returned. Setting the busy_timeout to 0 or negative |
| 96509 | 96868 | ** disables the timeout. |
| 96510 | 96869 | */ |
| 96511 | | - if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){ |
| 96870 | + /*case PragTyp_BUSY_TIMEOUT*/ default: { |
| 96871 | + assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT ); |
| 96512 | 96872 | if( zRight ){ |
| 96513 | 96873 | sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); |
| 96514 | 96874 | } |
| 96515 | 96875 | returnSingleInt(pParse, "timeout", db->busyTimeout); |
| 96516 | | - }else |
| 96876 | + break; |
| 96877 | + } |
| 96878 | + |
| 96879 | + /* |
| 96880 | + ** PRAGMA soft_heap_limit |
| 96881 | + ** PRAGMA soft_heap_limit = N |
| 96882 | + ** |
| 96883 | + ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted, |
| 96884 | + ** use -1. |
| 96885 | + */ |
| 96886 | + case PragTyp_SOFT_HEAP_LIMIT: { |
| 96887 | + sqlite3_int64 N; |
| 96888 | + if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ |
| 96889 | + sqlite3_soft_heap_limit64(N); |
| 96890 | + } |
| 96891 | + returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); |
| 96892 | + break; |
| 96893 | + } |
| 96517 | 96894 | |
| 96518 | 96895 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 96519 | 96896 | /* |
| 96520 | 96897 | ** Report the current state of file logs for all databases |
| 96521 | 96898 | */ |
| 96522 | | - if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ |
| 96899 | + case PragTyp_LOCK_STATUS: { |
| 96523 | 96900 | static const char *const azLockName[] = { |
| 96524 | 96901 | "unlocked", "shared", "reserved", "pending", "exclusive" |
| 96525 | 96902 | }; |
| 96526 | 96903 | int i; |
| 96527 | 96904 | sqlite3VdbeSetNumCols(v, 2); |
| | @@ -96542,39 +96919,43 @@ |
| 96542 | 96919 | zState = azLockName[j]; |
| 96543 | 96920 | } |
| 96544 | 96921 | sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC); |
| 96545 | 96922 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); |
| 96546 | 96923 | } |
| 96547 | | - |
| 96548 | | - }else |
| 96924 | + break; |
| 96925 | + } |
| 96549 | 96926 | #endif |
| 96550 | 96927 | |
| 96551 | 96928 | #ifdef SQLITE_HAS_CODEC |
| 96552 | | - if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ |
| 96553 | | - sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96554 | | - }else |
| 96555 | | - if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){ |
| 96556 | | - sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96557 | | - }else |
| 96558 | | - if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 || |
| 96559 | | - sqlite3StrICmp(zLeft, "hexrekey")==0) ){ |
| 96560 | | - int i, h1, h2; |
| 96561 | | - char zKey[40]; |
| 96562 | | - for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ |
| 96563 | | - h1 += 9*(1&(h1>>6)); |
| 96564 | | - h2 += 9*(1&(h2>>6)); |
| 96565 | | - zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); |
| 96566 | | - } |
| 96567 | | - if( (zLeft[3] & 0xf)==0xb ){ |
| 96568 | | - sqlite3_key_v2(db, zDb, zKey, i/2); |
| 96569 | | - }else{ |
| 96570 | | - sqlite3_rekey_v2(db, zDb, zKey, i/2); |
| 96571 | | - } |
| 96572 | | - }else |
| 96929 | + case PragTyp_KEY: { |
| 96930 | + if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96931 | + break; |
| 96932 | + } |
| 96933 | + case PragTyp_REKEY: { |
| 96934 | + if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); |
| 96935 | + break; |
| 96936 | + } |
| 96937 | + case PragTyp_HEXKEY: { |
| 96938 | + if( zRight ){ |
| 96939 | + int i, h1, h2; |
| 96940 | + char zKey[40]; |
| 96941 | + for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){ |
| 96942 | + h1 += 9*(1&(h1>>6)); |
| 96943 | + h2 += 9*(1&(h2>>6)); |
| 96944 | + zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4); |
| 96945 | + } |
| 96946 | + if( (zLeft[3] & 0xf)==0xb ){ |
| 96947 | + sqlite3_key_v2(db, zDb, zKey, i/2); |
| 96948 | + }else{ |
| 96949 | + sqlite3_rekey_v2(db, zDb, zKey, i/2); |
| 96950 | + } |
| 96951 | + } |
| 96952 | + break; |
| 96953 | + } |
| 96573 | 96954 | #endif |
| 96574 | 96955 | #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) |
| 96575 | | - if( sqlite3StrICmp(zLeft, "activate_extensions")==0 && zRight ){ |
| 96956 | + case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ |
| 96576 | 96957 | #ifdef SQLITE_HAS_CODEC |
| 96577 | 96958 | if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ |
| 96578 | 96959 | sqlite3_activate_see(&zRight[4]); |
| 96579 | 96960 | } |
| 96580 | 96961 | #endif |
| | @@ -96581,15 +96962,15 @@ |
| 96581 | 96962 | #ifdef SQLITE_ENABLE_CEROD |
| 96582 | 96963 | if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ |
| 96583 | 96964 | sqlite3_activate_cerod(&zRight[6]); |
| 96584 | 96965 | } |
| 96585 | 96966 | #endif |
| 96586 | | - }else |
| 96967 | + } |
| 96968 | + break; |
| 96587 | 96969 | #endif |
| 96588 | 96970 | |
| 96589 | | - |
| 96590 | | - {/* Empty ELSE clause */} |
| 96971 | + } /* End of the PRAGMA switch */ |
| 96591 | 96972 | |
| 96592 | 96973 | pragma_out: |
| 96593 | 96974 | sqlite3DbFree(db, zLeft); |
| 96594 | 96975 | sqlite3DbFree(db, zRight); |
| 96595 | 96976 | } |
| | @@ -97736,12 +98117,12 @@ |
| 97736 | 98117 | pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); |
| 97737 | 98118 | |
| 97738 | 98119 | pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); |
| 97739 | 98120 | if( pEq && isOuterJoin ){ |
| 97740 | 98121 | ExprSetProperty(pEq, EP_FromJoin); |
| 97741 | | - assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) ); |
| 97742 | | - ExprSetIrreducible(pEq); |
| 98122 | + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); |
| 98123 | + ExprSetVVAProperty(pEq, EP_NoReduce); |
| 97743 | 98124 | pEq->iRightJoinTable = (i16)pE2->iTable; |
| 97744 | 98125 | } |
| 97745 | 98126 | *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); |
| 97746 | 98127 | } |
| 97747 | 98128 | |
| | @@ -97772,12 +98153,12 @@ |
| 97772 | 98153 | ** the output, which is incorrect. |
| 97773 | 98154 | */ |
| 97774 | 98155 | static void setJoinExpr(Expr *p, int iTable){ |
| 97775 | 98156 | while( p ){ |
| 97776 | 98157 | ExprSetProperty(p, EP_FromJoin); |
| 97777 | | - assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) ); |
| 97778 | | - ExprSetIrreducible(p); |
| 98158 | + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); |
| 98159 | + ExprSetVVAProperty(p, EP_NoReduce); |
| 97779 | 98160 | p->iRightJoinTable = (i16)iTable; |
| 97780 | 98161 | setJoinExpr(p->pLeft, iTable); |
| 97781 | 98162 | p = p->pRight; |
| 97782 | 98163 | } |
| 97783 | 98164 | } |
| | @@ -100700,11 +101081,11 @@ |
| 100700 | 101081 | assert( pTab && !pTab->pSelect && pExpr ); |
| 100701 | 101082 | |
| 100702 | 101083 | if( IsVirtual(pTab) ) return 0; |
| 100703 | 101084 | if( pExpr->op!=TK_AGG_FUNCTION ) return 0; |
| 100704 | 101085 | if( NEVER(pAggInfo->nFunc==0) ) return 0; |
| 100705 | | - if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; |
| 101086 | + if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; |
| 100706 | 101087 | if( pExpr->flags&EP_Distinct ) return 0; |
| 100707 | 101088 | |
| 100708 | 101089 | return pTab; |
| 100709 | 101090 | } |
| 100710 | 101091 | |
| | @@ -101297,11 +101678,11 @@ |
| 101297 | 101678 | if( pF->iDistinct>=0 ){ |
| 101298 | 101679 | addrNext = sqlite3VdbeMakeLabel(v); |
| 101299 | 101680 | assert( nArg==1 ); |
| 101300 | 101681 | codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); |
| 101301 | 101682 | } |
| 101302 | | - if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 101683 | + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 101303 | 101684 | CollSeq *pColl = 0; |
| 101304 | 101685 | struct ExprList_item *pItem; |
| 101305 | 101686 | int j; |
| 101306 | 101687 | assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ |
| 101307 | 101688 | for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){ |
| | @@ -104140,11 +104521,11 @@ |
| 104140 | 104521 | sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid, |
| 104141 | 104522 | aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0); |
| 104142 | 104523 | |
| 104143 | 104524 | /* Do FK constraint checks. */ |
| 104144 | 104525 | if( hasFK ){ |
| 104145 | | - sqlite3FkCheck(pParse, pTab, regOldRowid, 0); |
| 104526 | + sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngRowid); |
| 104146 | 104527 | } |
| 104147 | 104528 | |
| 104148 | 104529 | /* Delete the index entries associated with the current record. */ |
| 104149 | 104530 | j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid); |
| 104150 | 104531 | sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx); |
| | @@ -104154,21 +104535,21 @@ |
| 104154 | 104535 | sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0); |
| 104155 | 104536 | } |
| 104156 | 104537 | sqlite3VdbeJumpHere(v, j1); |
| 104157 | 104538 | |
| 104158 | 104539 | if( hasFK ){ |
| 104159 | | - sqlite3FkCheck(pParse, pTab, 0, regNewRowid); |
| 104540 | + sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngRowid); |
| 104160 | 104541 | } |
| 104161 | 104542 | |
| 104162 | 104543 | /* Insert the new index entries and the new record. */ |
| 104163 | 104544 | sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0); |
| 104164 | 104545 | |
| 104165 | 104546 | /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to |
| 104166 | 104547 | ** handle rows (possibly in other tables) that refer via a foreign key |
| 104167 | 104548 | ** to the row just updated. */ |
| 104168 | 104549 | if( hasFK ){ |
| 104169 | | - sqlite3FkActions(pParse, pTab, pChanges, regOldRowid); |
| 104550 | + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngRowid); |
| 104170 | 104551 | } |
| 104171 | 104552 | } |
| 104172 | 104553 | |
| 104173 | 104554 | /* Increment the row counter |
| 104174 | 104555 | */ |
| | @@ -105692,11 +106073,11 @@ |
| 105692 | 106073 | *pNew = *pDef; |
| 105693 | 106074 | pNew->zName = (char *)&pNew[1]; |
| 105694 | 106075 | memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1); |
| 105695 | 106076 | pNew->xFunc = xFunc; |
| 105696 | 106077 | pNew->pUserData = pArg; |
| 105697 | | - pNew->flags |= SQLITE_FUNC_EPHEM; |
| 106078 | + pNew->funcFlags |= SQLITE_FUNC_EPHEM; |
| 105698 | 106079 | return pNew; |
| 105699 | 106080 | } |
| 105700 | 106081 | |
| 105701 | 106082 | /* |
| 105702 | 106083 | ** Make sure virtual table pTab is contained in the pParse->apVirtualLock[] |
| | @@ -105829,24 +106210,25 @@ |
| 105829 | 106210 | |
| 105830 | 106211 | /* |
| 105831 | 106212 | ** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The |
| 105832 | 106213 | ** maximum cost for ordinary tables is 64*(2**63) which becomes 6900. |
| 105833 | 106214 | ** (Virtual tables can return a larger cost, but let's assume they do not.) |
| 105834 | | -** So all costs can be stored in a 16-bit unsigned integer without risk |
| 106215 | +** So all costs can be stored in a 16-bit integer without risk |
| 105835 | 106216 | ** of overflow. |
| 105836 | 106217 | ** |
| 105837 | 106218 | ** Costs are estimates, so no effort is made to compute 10*log2(X) exactly. |
| 105838 | | -** Instead, a close estimate is used. Any value of X<=1 is stored as 0. |
| 105839 | | -** X=2 is 10. X=3 is 16. X=1000 is 99. etc. |
| 106219 | +** Instead, a close estimate is used. Any value of X=1 is stored as 0. |
| 106220 | +** X=2 is 10. X=3 is 16. X=1000 is 99. etc. Negative values are allowed. |
| 106221 | +** A WhereCost of -10 means 0.5. WhereCost of -20 means 0.25. And so forth. |
| 105840 | 106222 | ** |
| 105841 | 106223 | ** The tool/wherecosttest.c source file implements a command-line program |
| 105842 | 106224 | ** that will convert WhereCosts to integers, convert integers to WhereCosts |
| 105843 | 106225 | ** and do addition and multiplication on WhereCost values. The wherecosttest |
| 105844 | 106226 | ** command-line program is a useful utility to have around when working with |
| 105845 | 106227 | ** this module. |
| 105846 | 106228 | */ |
| 105847 | | -typedef unsigned short int WhereCost; |
| 106229 | +typedef short int WhereCost; |
| 105848 | 106230 | |
| 105849 | 106231 | /* |
| 105850 | 106232 | ** This object contains information needed to implement a single nested |
| 105851 | 106233 | ** loop in WHERE clause. |
| 105852 | 106234 | ** |
| | @@ -105883,10 +106265,11 @@ |
| 105883 | 106265 | } *aInLoop; /* Information about each nested IN operator */ |
| 105884 | 106266 | } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ |
| 105885 | 106267 | Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ |
| 105886 | 106268 | } u; |
| 105887 | 106269 | struct WhereLoop *pWLoop; /* The selected WhereLoop object */ |
| 106270 | + Bitmask notReady; /* FROM entries not usable at this level */ |
| 105888 | 106271 | }; |
| 105889 | 106272 | |
| 105890 | 106273 | /* |
| 105891 | 106274 | ** Each instance of this object represents an algorithm for evaluating one |
| 105892 | 106275 | ** term of a join. Every term of the FROM clause will have at least |
| | @@ -106045,10 +106428,11 @@ |
| 106045 | 106428 | union { |
| 106046 | 106429 | int leftColumn; /* Column number of X in "X <op> <expr>" */ |
| 106047 | 106430 | WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ |
| 106048 | 106431 | WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ |
| 106049 | 106432 | } u; |
| 106433 | + WhereCost truthProb; /* Probability of truth for this expression */ |
| 106050 | 106434 | u16 eOperator; /* A WO_xx value describing <op> */ |
| 106051 | 106435 | u8 wtFlags; /* TERM_xxx bit flags. See below */ |
| 106052 | 106436 | u8 nChild; /* Number of children that must disable us */ |
| 106053 | 106437 | WhereClause *pWC; /* The clause this term is part of */ |
| 106054 | 106438 | Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ |
| | @@ -106419,10 +106803,13 @@ |
| 106419 | 106803 | if( pWC->a!=pWC->aStatic ){ |
| 106420 | 106804 | sqlite3DbFree(db, pWC->a); |
| 106421 | 106805 | } |
| 106422 | 106806 | } |
| 106423 | 106807 | |
| 106808 | +/* Forward declaration */ |
| 106809 | +static WhereCost whereCost(tRowcnt x); |
| 106810 | + |
| 106424 | 106811 | /* |
| 106425 | 106812 | ** Add a single new WhereTerm entry to the WhereClause object pWC. |
| 106426 | 106813 | ** The new WhereTerm object is constructed from Expr p and with wtFlags. |
| 106427 | 106814 | ** The index in pWC->a[] of the new WhereTerm is returned on success. |
| 106428 | 106815 | ** 0 is returned if the new WhereTerm could not be added due to a memory |
| | @@ -106460,10 +106847,15 @@ |
| 106460 | 106847 | sqlite3DbFree(db, pOld); |
| 106461 | 106848 | } |
| 106462 | 106849 | pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); |
| 106463 | 106850 | } |
| 106464 | 106851 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 106852 | + if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 106853 | + pTerm->truthProb = whereCost(p->iTable) - 99; |
| 106854 | + }else{ |
| 106855 | + pTerm->truthProb = -1; |
| 106856 | + } |
| 106465 | 106857 | pTerm->pExpr = sqlite3ExprSkipCollate(p); |
| 106466 | 106858 | pTerm->wtFlags = wtFlags; |
| 106467 | 106859 | pTerm->pWC = pWC; |
| 106468 | 106860 | pTerm->iParent = -1; |
| 106469 | 106861 | return idx; |
| | @@ -108321,18 +108713,19 @@ |
| 108321 | 108713 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 108322 | 108714 | WhereCost *pnOut /* IN/OUT: Number of rows visited */ |
| 108323 | 108715 | ){ |
| 108324 | 108716 | int rc = SQLITE_OK; |
| 108325 | 108717 | int nOut = (int)*pnOut; |
| 108718 | + WhereCost nNew; |
| 108326 | 108719 | |
| 108327 | 108720 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108328 | 108721 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108329 | 108722 | int nEq = pBuilder->pNew->u.btree.nEq; |
| 108330 | 108723 | |
| 108331 | | - if( nEq==pBuilder->nRecValid |
| 108724 | + if( p->nSample>0 |
| 108725 | + && nEq==pBuilder->nRecValid |
| 108332 | 108726 | && nEq<p->nSampleCol |
| 108333 | | - && p->nSample |
| 108334 | 108727 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108335 | 108728 | ){ |
| 108336 | 108729 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108337 | 108730 | tRowcnt a[2]; |
| 108338 | 108731 | u8 aff; |
| | @@ -108383,10 +108776,11 @@ |
| 108383 | 108776 | if( rc==SQLITE_OK && bOk ){ |
| 108384 | 108777 | tRowcnt iNew; |
| 108385 | 108778 | whereKeyStats(pParse, p, pRec, 0, a); |
| 108386 | 108779 | iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 108387 | 108780 | if( iNew>iLower ) iLower = iNew; |
| 108781 | + nOut--; |
| 108388 | 108782 | } |
| 108389 | 108783 | } |
| 108390 | 108784 | |
| 108391 | 108785 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 108392 | 108786 | if( pUpper ){ |
| | @@ -108397,16 +108791,16 @@ |
| 108397 | 108791 | if( rc==SQLITE_OK && bOk ){ |
| 108398 | 108792 | tRowcnt iNew; |
| 108399 | 108793 | whereKeyStats(pParse, p, pRec, 1, a); |
| 108400 | 108794 | iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 108401 | 108795 | if( iNew<iUpper ) iUpper = iNew; |
| 108796 | + nOut--; |
| 108402 | 108797 | } |
| 108403 | 108798 | } |
| 108404 | 108799 | |
| 108405 | 108800 | pBuilder->pRec = pRec; |
| 108406 | 108801 | if( rc==SQLITE_OK ){ |
| 108407 | | - WhereCost nNew; |
| 108408 | 108802 | if( iUpper>iLower ){ |
| 108409 | 108803 | nNew = whereCost(iUpper - iLower); |
| 108410 | 108804 | }else{ |
| 108411 | 108805 | nNew = 10; assert( 10==whereCost(2) ); |
| 108412 | 108806 | } |
| | @@ -108424,17 +108818,21 @@ |
| 108424 | 108818 | UNUSED_PARAMETER(pBuilder); |
| 108425 | 108819 | #endif |
| 108426 | 108820 | assert( pLower || pUpper ); |
| 108427 | 108821 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 108428 | 108822 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 108823 | + nNew = nOut; |
| 108429 | 108824 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 108430 | | - nOut -= 20; assert( 20==whereCost(4) ); |
| 108825 | + nNew -= 20; assert( 20==whereCost(4) ); |
| 108826 | + nOut--; |
| 108431 | 108827 | } |
| 108432 | 108828 | if( pUpper ){ |
| 108433 | | - nOut -= 20; assert( 20==whereCost(4) ); |
| 108829 | + nNew -= 20; assert( 20==whereCost(4) ); |
| 108830 | + nOut--; |
| 108434 | 108831 | } |
| 108435 | | - if( nOut<10 ) nOut = 10; |
| 108832 | + if( nNew<10 ) nNew = 10; |
| 108833 | + if( nNew<nOut ) nOut = nNew; |
| 108436 | 108834 | *pnOut = (WhereCost)nOut; |
| 108437 | 108835 | return rc; |
| 108438 | 108836 | } |
| 108439 | 108837 | |
| 108440 | 108838 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| | @@ -108576,10 +108974,11 @@ |
| 108576 | 108974 | */ |
| 108577 | 108975 | static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ |
| 108578 | 108976 | if( pTerm |
| 108579 | 108977 | && (pTerm->wtFlags & TERM_CODED)==0 |
| 108580 | 108978 | && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) |
| 108979 | + && (pLevel->notReady & pTerm->prereqAll)==0 |
| 108581 | 108980 | ){ |
| 108582 | 108981 | pTerm->wtFlags |= TERM_CODED; |
| 108583 | 108982 | if( pTerm->iParent>=0 ){ |
| 108584 | 108983 | WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; |
| 108585 | 108984 | if( (--pOther->nChild)==0 ){ |
| | @@ -109001,20 +109400,20 @@ |
| 109001 | 109400 | struct SrcList_item *pTabItem; /* FROM clause term being coded */ |
| 109002 | 109401 | int addrBrk; /* Jump here to break out of the loop */ |
| 109003 | 109402 | int addrCont; /* Jump here to continue with next cycle */ |
| 109004 | 109403 | int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ |
| 109005 | 109404 | int iReleaseReg = 0; /* Temp register to free before returning */ |
| 109006 | | - Bitmask newNotReady; /* Return value */ |
| 109007 | 109405 | |
| 109008 | 109406 | pParse = pWInfo->pParse; |
| 109009 | 109407 | v = pParse->pVdbe; |
| 109010 | 109408 | pWC = &pWInfo->sWC; |
| 109011 | 109409 | db = pParse->db; |
| 109012 | 109410 | pLevel = &pWInfo->a[iLevel]; |
| 109013 | 109411 | pLoop = pLevel->pWLoop; |
| 109014 | 109412 | pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; |
| 109015 | 109413 | iCur = pTabItem->iCursor; |
| 109414 | + pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur); |
| 109016 | 109415 | bRev = (pWInfo->revMask>>iLevel)&1; |
| 109017 | 109416 | omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 |
| 109018 | 109417 | && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; |
| 109019 | 109418 | VdbeNoopComment((v, "Begin Join Loop %d", iLevel)); |
| 109020 | 109419 | |
| | @@ -109663,21 +110062,20 @@ |
| 109663 | 110062 | pLevel->op = aStep[bRev]; |
| 109664 | 110063 | pLevel->p1 = iCur; |
| 109665 | 110064 | pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); |
| 109666 | 110065 | pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; |
| 109667 | 110066 | } |
| 109668 | | - newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur); |
| 109669 | 110067 | |
| 109670 | 110068 | /* Insert code to test every subexpression that can be completely |
| 109671 | 110069 | ** computed using the current set of tables. |
| 109672 | 110070 | */ |
| 109673 | 110071 | for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ |
| 109674 | 110072 | Expr *pE; |
| 109675 | 110073 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 109676 | 110074 | testcase( pTerm->wtFlags & TERM_CODED ); |
| 109677 | 110075 | if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 109678 | | - if( (pTerm->prereqAll & newNotReady)!=0 ){ |
| 110076 | + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ |
| 109679 | 110077 | testcase( pWInfo->untestedTerms==0 |
| 109680 | 110078 | && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ); |
| 109681 | 110079 | pWInfo->untestedTerms = 1; |
| 109682 | 110080 | continue; |
| 109683 | 110081 | } |
| | @@ -109705,11 +110103,11 @@ |
| 109705 | 110103 | if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; |
| 109706 | 110104 | if( pTerm->leftCursor!=iCur ) continue; |
| 109707 | 110105 | if( pLevel->iLeftJoin ) continue; |
| 109708 | 110106 | pE = pTerm->pExpr; |
| 109709 | 110107 | assert( !ExprHasProperty(pE, EP_FromJoin) ); |
| 109710 | | - assert( (pTerm->prereqRight & newNotReady)!=0 ); |
| 110108 | + assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); |
| 109711 | 110109 | pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0); |
| 109712 | 110110 | if( pAlt==0 ) continue; |
| 109713 | 110111 | if( pAlt->wtFlags & (TERM_CODED) ) continue; |
| 109714 | 110112 | testcase( pAlt->eOperator & WO_EQ ); |
| 109715 | 110113 | testcase( pAlt->eOperator & WO_IN ); |
| | @@ -109733,11 +110131,11 @@ |
| 109733 | 110131 | sqlite3ExprCacheClear(pParse); |
| 109734 | 110132 | for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){ |
| 109735 | 110133 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 109736 | 110134 | testcase( pTerm->wtFlags & TERM_CODED ); |
| 109737 | 110135 | if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; |
| 109738 | | - if( (pTerm->prereqAll & newNotReady)!=0 ){ |
| 110136 | + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ |
| 109739 | 110137 | assert( pWInfo->untestedTerms ); |
| 109740 | 110138 | continue; |
| 109741 | 110139 | } |
| 109742 | 110140 | assert( pTerm->pExpr ); |
| 109743 | 110141 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); |
| | @@ -109744,11 +110142,11 @@ |
| 109744 | 110142 | pTerm->wtFlags |= TERM_CODED; |
| 109745 | 110143 | } |
| 109746 | 110144 | } |
| 109747 | 110145 | sqlite3ReleaseTempReg(pParse, iReleaseReg); |
| 109748 | 110146 | |
| 109749 | | - return newNotReady; |
| 110147 | + return pLevel->notReady; |
| 109750 | 110148 | } |
| 109751 | 110149 | |
| 109752 | 110150 | #ifdef WHERETRACE_ENABLED |
| 109753 | 110151 | /* |
| 109754 | 110152 | ** Print a WhereLoop object for debugging purposes |
| | @@ -109845,12 +110243,15 @@ |
| 109845 | 110243 | |
| 109846 | 110244 | /* |
| 109847 | 110245 | ** Transfer content from the second pLoop into the first. |
| 109848 | 110246 | */ |
| 109849 | 110247 | static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ |
| 109850 | | - if( whereLoopResize(db, pTo, pFrom->nLTerm) ) return SQLITE_NOMEM; |
| 109851 | 110248 | whereLoopClearUnion(db, pTo); |
| 110249 | + if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ |
| 110250 | + memset(&pTo->u, 0, sizeof(pTo->u)); |
| 110251 | + return SQLITE_NOMEM; |
| 110252 | + } |
| 109852 | 110253 | memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); |
| 109853 | 110254 | memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); |
| 109854 | 110255 | if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ |
| 109855 | 110256 | pFrom->u.vtab.needFree = 0; |
| 109856 | 110257 | }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| | @@ -109962,13 +110363,13 @@ |
| 109962 | 110363 | ** all of (1) dependencies (2) setup-cost, (3) run-cost, and |
| 109963 | 110364 | ** (4) number of output rows. */ |
| 109964 | 110365 | assert( p->rSetup==pTemplate->rSetup ); |
| 109965 | 110366 | if( p->prereq==pTemplate->prereq |
| 109966 | 110367 | && p->nLTerm<pTemplate->nLTerm |
| 109967 | | - && (p->wsFlags & WHERE_INDEXED)!=0 |
| 109968 | | - && (pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 109969 | | - && p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 110368 | + && (p->wsFlags & pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 110369 | + && (p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 110370 | + || pTemplate->rRun+p->nLTerm<=p->rRun+pTemplate->nLTerm) |
| 109970 | 110371 | ){ |
| 109971 | 110372 | /* Overwrite an existing WhereLoop with an similar one that uses |
| 109972 | 110373 | ** more terms of the index */ |
| 109973 | 110374 | pNext = p->pNextLoop; |
| 109974 | 110375 | break; |
| | @@ -109979,16 +110380,16 @@ |
| 109979 | 110380 | } |
| 109980 | 110381 | } |
| 109981 | 110382 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 109982 | 110383 | && p->rRun>=pTemplate->rRun |
| 109983 | 110384 | && p->nOut>=pTemplate->nOut |
| 109984 | | - && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ |
| 109985 | 110385 | ){ |
| 109986 | 110386 | /* Overwrite an existing WhereLoop with a better one: one that is |
| 109987 | 110387 | ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost |
| 109988 | 110388 | ** or (4) number of output rows, and is no worse in any of those |
| 109989 | 110389 | ** categories. */ |
| 110390 | + assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ |
| 109990 | 110391 | pNext = p->pNextLoop; |
| 109991 | 110392 | break; |
| 109992 | 110393 | } |
| 109993 | 110394 | } |
| 109994 | 110395 | |
| | @@ -110030,10 +110431,40 @@ |
| 110030 | 110431 | whereLoopPrint(pTemplate, pWInfo->pTabList); |
| 110031 | 110432 | } |
| 110032 | 110433 | #endif |
| 110033 | 110434 | return SQLITE_OK; |
| 110034 | 110435 | } |
| 110436 | + |
| 110437 | +/* |
| 110438 | +** Adjust the WhereLoop.nOut value downward to account for terms of the |
| 110439 | +** WHERE clause that reference the loop but which are not used by an |
| 110440 | +** index. |
| 110441 | +** |
| 110442 | +** In the current implementation, the first extra WHERE clause term reduces |
| 110443 | +** the number of output rows by a factor of 10 and each additional term |
| 110444 | +** reduces the number of output rows by sqrt(2). |
| 110445 | +*/ |
| 110446 | +static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop, int iCur){ |
| 110447 | + WhereTerm *pTerm, *pX; |
| 110448 | + Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); |
| 110449 | + int i, j; |
| 110450 | + |
| 110451 | + if( !OptimizationEnabled(pWC->pWInfo->pParse->db, SQLITE_AdjustOutEst) ){ |
| 110452 | + return; |
| 110453 | + } |
| 110454 | + for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ |
| 110455 | + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; |
| 110456 | + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; |
| 110457 | + if( (pTerm->prereqAll & notAllowed)!=0 ) continue; |
| 110458 | + for(j=pLoop->nLTerm-1; j>=0; j--){ |
| 110459 | + pX = pLoop->aLTerm[j]; |
| 110460 | + if( pX==pTerm ) break; |
| 110461 | + if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 110462 | + } |
| 110463 | + if( j<0 ) pLoop->nOut += pTerm->truthProb; |
| 110464 | + } |
| 110465 | +} |
| 110035 | 110466 | |
| 110036 | 110467 | /* |
| 110037 | 110468 | ** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex. |
| 110038 | 110469 | ** Try to match one more. |
| 110039 | 110470 | ** |
| | @@ -110197,11 +110628,11 @@ |
| 110197 | 110628 | ** the main table */ |
| 110198 | 110629 | pNew->rRun = whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10); |
| 110199 | 110630 | } |
| 110200 | 110631 | /* Step cost for each output row */ |
| 110201 | 110632 | pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut); |
| 110202 | | - /* TBD: Adjust nOut for additional constraints */ |
| 110633 | + whereLoopOutputAdjust(pBuilder->pWC, pNew, pSrc->iCursor); |
| 110203 | 110634 | rc = whereLoopInsert(pBuilder, pNew); |
| 110204 | 110635 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 110205 | 110636 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 110206 | 110637 | ){ |
| 110207 | 110638 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| | @@ -110401,11 +110832,13 @@ |
| 110401 | 110832 | ** + The extra 3 factor is to encourage the use of indexed lookups |
| 110402 | 110833 | ** over full scans. A smaller constant 2 is used for covering |
| 110403 | 110834 | ** index scans so that a covering index scan will be favored over |
| 110404 | 110835 | ** a table scan. */ |
| 110405 | 110836 | pNew->rRun = whereCostAdd(rSize,rLogSize) + 16; |
| 110837 | + whereLoopOutputAdjust(pWC, pNew, pSrc->iCursor); |
| 110406 | 110838 | rc = whereLoopInsert(pBuilder, pNew); |
| 110839 | + pNew->nOut = rSize; |
| 110407 | 110840 | if( rc ) break; |
| 110408 | 110841 | }else{ |
| 110409 | 110842 | Bitmask m = pSrc->colUsed & ~columnsInIndex(pProbe); |
| 110410 | 110843 | pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; |
| 110411 | 110844 | |
| | @@ -110433,11 +110866,13 @@ |
| 110433 | 110866 | assert( b!=0 ); |
| 110434 | 110867 | /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N) |
| 110435 | 110868 | ** which we will simplify to just N*log2(N) */ |
| 110436 | 110869 | pNew->rRun = rSize + rLogSize; |
| 110437 | 110870 | } |
| 110871 | + whereLoopOutputAdjust(pWC, pNew, pSrc->iCursor); |
| 110438 | 110872 | rc = whereLoopInsert(pBuilder, pNew); |
| 110873 | + pNew->nOut = rSize; |
| 110439 | 110874 | if( rc ) break; |
| 110440 | 110875 | } |
| 110441 | 110876 | } |
| 110442 | 110877 | |
| 110443 | 110878 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| | @@ -111040,13 +111475,16 @@ |
| 111040 | 111475 | int nLoop; /* Number of terms in the join */ |
| 111041 | 111476 | Parse *pParse; /* Parsing context */ |
| 111042 | 111477 | sqlite3 *db; /* The database connection */ |
| 111043 | 111478 | int iLoop; /* Loop counter over the terms of the join */ |
| 111044 | 111479 | int ii, jj; /* Loop counters */ |
| 111045 | | - WhereCost rCost; /* Cost of a path */ |
| 111046 | | - WhereCost mxCost = 0; /* Maximum cost of a set of paths */ |
| 111047 | | - WhereCost rSortCost; /* Cost to do a sort */ |
| 111480 | + int mxI = 0; /* Index of next entry to replace */ |
| 111481 | + WhereCost rCost; /* Cost of a path */ |
| 111482 | + WhereCost nOut; /* Number of outputs */ |
| 111483 | + WhereCost mxCost = 0; /* Maximum cost of a set of paths */ |
| 111484 | + WhereCost mxOut = 0; /* Maximum nOut value on the set of paths */ |
| 111485 | + WhereCost rSortCost; /* Cost to do a sort */ |
| 111048 | 111486 | int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ |
| 111049 | 111487 | WherePath *aFrom; /* All nFrom paths at the previous level */ |
| 111050 | 111488 | WherePath *aTo; /* The nTo best paths at the current level */ |
| 111051 | 111489 | WherePath *pFrom; /* An element of aFrom[] that we are working on */ |
| 111052 | 111490 | WherePath *pTo; /* An element of aTo[] that we are working on */ |
| | @@ -111111,10 +111549,11 @@ |
| 111111 | 111549 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| 111112 | 111550 | /* At this point, pWLoop is a candidate to be the next loop. |
| 111113 | 111551 | ** Compute its cost */ |
| 111114 | 111552 | rCost = whereCostAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); |
| 111115 | 111553 | rCost = whereCostAdd(rCost, pFrom->rCost); |
| 111554 | + nOut = pFrom->nRow + pWLoop->nOut; |
| 111116 | 111555 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 111117 | 111556 | if( !isOrderedValid ){ |
| 111118 | 111557 | switch( wherePathSatisfiesOrderBy(pWInfo, |
| 111119 | 111558 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 111120 | 111559 | iLoop, pWLoop, &revMask) ){ |
| | @@ -111133,21 +111572,25 @@ |
| 111133 | 111572 | }else{ |
| 111134 | 111573 | revMask = pFrom->revLoop; |
| 111135 | 111574 | } |
| 111136 | 111575 | /* Check to see if pWLoop should be added to the mxChoice best so far */ |
| 111137 | 111576 | for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){ |
| 111138 | | - if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){ |
| 111577 | + if( pTo->maskLoop==maskNew |
| 111578 | + && pTo->isOrderedValid==isOrderedValid |
| 111579 | + && ((pTo->rCost<=rCost && pTo->nRow<=nOut) || |
| 111580 | + (pTo->rCost>=rCost && pTo->nRow>=nOut)) |
| 111581 | + ){ |
| 111139 | 111582 | testcase( jj==nTo-1 ); |
| 111140 | 111583 | break; |
| 111141 | 111584 | } |
| 111142 | 111585 | } |
| 111143 | 111586 | if( jj>=nTo ){ |
| 111144 | 111587 | if( nTo>=mxChoice && rCost>=mxCost ){ |
| 111145 | 111588 | #ifdef WHERETRACE_ENABLED |
| 111146 | 111589 | if( sqlite3WhereTrace&0x4 ){ |
| 111147 | | - sqlite3DebugPrintf("Skip %s cost=%3d order=%c\n", |
| 111148 | | - wherePathName(pFrom, iLoop, pWLoop), rCost, |
| 111590 | + sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n", |
| 111591 | + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 111149 | 111592 | isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 111150 | 111593 | } |
| 111151 | 111594 | #endif |
| 111152 | 111595 | continue; |
| 111153 | 111596 | } |
| | @@ -111155,30 +111598,30 @@ |
| 111155 | 111598 | if( nTo<mxChoice ){ |
| 111156 | 111599 | /* Increase the size of the aTo set by one */ |
| 111157 | 111600 | jj = nTo++; |
| 111158 | 111601 | }else{ |
| 111159 | 111602 | /* New path replaces the prior worst to keep count below mxChoice */ |
| 111160 | | - for(jj=nTo-1; aTo[jj].rCost<mxCost; jj--){ assert(jj>0); } |
| 111603 | + jj = mxI; |
| 111161 | 111604 | } |
| 111162 | 111605 | pTo = &aTo[jj]; |
| 111163 | 111606 | #ifdef WHERETRACE_ENABLED |
| 111164 | 111607 | if( sqlite3WhereTrace&0x4 ){ |
| 111165 | | - sqlite3DebugPrintf("New %s cost=%-3d order=%c\n", |
| 111166 | | - wherePathName(pFrom, iLoop, pWLoop), rCost, |
| 111608 | + sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n", |
| 111609 | + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 111167 | 111610 | isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 111168 | 111611 | } |
| 111169 | 111612 | #endif |
| 111170 | 111613 | }else{ |
| 111171 | | - if( pTo->rCost<=rCost ){ |
| 111614 | + if( pTo->rCost<=rCost && pTo->nRow<=nOut ){ |
| 111172 | 111615 | #ifdef WHERETRACE_ENABLED |
| 111173 | 111616 | if( sqlite3WhereTrace&0x4 ){ |
| 111174 | 111617 | sqlite3DebugPrintf( |
| 111175 | | - "Skip %s cost=%-3d order=%c", |
| 111176 | | - wherePathName(pFrom, iLoop, pWLoop), rCost, |
| 111618 | + "Skip %s cost=%-3d,%3d order=%c", |
| 111619 | + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 111177 | 111620 | isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 111178 | | - sqlite3DebugPrintf(" vs %s cost=%-3d order=%c\n", |
| 111179 | | - wherePathName(pTo, iLoop+1, 0), pTo->rCost, |
| 111621 | + sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n", |
| 111622 | + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 111180 | 111623 | pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 111181 | 111624 | } |
| 111182 | 111625 | #endif |
| 111183 | 111626 | testcase( pTo->rCost==rCost ); |
| 111184 | 111627 | continue; |
| | @@ -111186,32 +111629,38 @@ |
| 111186 | 111629 | testcase( pTo->rCost==rCost+1 ); |
| 111187 | 111630 | /* A new and better score for a previously created equivalent path */ |
| 111188 | 111631 | #ifdef WHERETRACE_ENABLED |
| 111189 | 111632 | if( sqlite3WhereTrace&0x4 ){ |
| 111190 | 111633 | sqlite3DebugPrintf( |
| 111191 | | - "Update %s cost=%-3d order=%c", |
| 111192 | | - wherePathName(pFrom, iLoop, pWLoop), rCost, |
| 111634 | + "Update %s cost=%-3d,%3d order=%c", |
| 111635 | + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, |
| 111193 | 111636 | isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?'); |
| 111194 | | - sqlite3DebugPrintf(" was %s cost=%-3d order=%c\n", |
| 111195 | | - wherePathName(pTo, iLoop+1, 0), pTo->rCost, |
| 111637 | + sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n", |
| 111638 | + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, |
| 111196 | 111639 | pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?'); |
| 111197 | 111640 | } |
| 111198 | 111641 | #endif |
| 111199 | 111642 | } |
| 111200 | 111643 | /* pWLoop is a winner. Add it to the set of best so far */ |
| 111201 | 111644 | pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; |
| 111202 | 111645 | pTo->revLoop = revMask; |
| 111203 | | - pTo->nRow = pFrom->nRow + pWLoop->nOut; |
| 111646 | + pTo->nRow = nOut; |
| 111204 | 111647 | pTo->rCost = rCost; |
| 111205 | 111648 | pTo->isOrderedValid = isOrderedValid; |
| 111206 | 111649 | pTo->isOrdered = isOrdered; |
| 111207 | 111650 | memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); |
| 111208 | 111651 | pTo->aLoop[iLoop] = pWLoop; |
| 111209 | 111652 | if( nTo>=mxChoice ){ |
| 111653 | + mxI = 0; |
| 111210 | 111654 | mxCost = aTo[0].rCost; |
| 111655 | + mxOut = aTo[0].nRow; |
| 111211 | 111656 | for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){ |
| 111212 | | - if( pTo->rCost>mxCost ) mxCost = pTo->rCost; |
| 111657 | + if( pTo->rCost>mxCost || (pTo->rCost==mxCost && pTo->nRow>mxOut) ){ |
| 111658 | + mxCost = pTo->rCost; |
| 111659 | + mxOut = pTo->nRow; |
| 111660 | + mxI = jj; |
| 111661 | + } |
| 111213 | 111662 | } |
| 111214 | 111663 | } |
| 111215 | 111664 | } |
| 111216 | 111665 | } |
| 111217 | 111666 | |
| | @@ -111244,16 +111693,13 @@ |
| 111244 | 111693 | return SQLITE_ERROR; |
| 111245 | 111694 | } |
| 111246 | 111695 | |
| 111247 | 111696 | /* Find the lowest cost path. pFrom will be left pointing to that path */ |
| 111248 | 111697 | pFrom = aFrom; |
| 111249 | | - assert( nFrom==1 ); |
| 111250 | | -#if 0 /* The following is needed if nFrom is ever more than 1 */ |
| 111251 | 111698 | for(ii=1; ii<nFrom; ii++){ |
| 111252 | 111699 | if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii]; |
| 111253 | 111700 | } |
| 111254 | | -#endif |
| 111255 | 111701 | assert( pWInfo->nLevel==nLoop ); |
| 111256 | 111702 | /* Load the lowest cost path into pWInfo */ |
| 111257 | 111703 | for(iLoop=0; iLoop<nLoop; iLoop++){ |
| 111258 | 111704 | WhereLevel *pLevel = pWInfo->a + iLoop; |
| 111259 | 111705 | pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; |
| | @@ -114879,16 +115325,17 @@ |
| 114879 | 115325 | yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; |
| 114880 | 115326 | } |
| 114881 | 115327 | break; |
| 114882 | 115328 | case 231: /* expr ::= CASE case_operand case_exprlist case_else END */ |
| 114883 | 115329 | { |
| 114884 | | - yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0); |
| 115330 | + yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, 0, 0); |
| 114885 | 115331 | if( yygotominor.yy342.pExpr ){ |
| 114886 | | - yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442; |
| 115332 | + yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy122 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[-1].minor.yy122) : yymsp[-2].minor.yy442; |
| 114887 | 115333 | sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr); |
| 114888 | 115334 | }else{ |
| 114889 | 115335 | sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442); |
| 115336 | + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy122); |
| 114890 | 115337 | } |
| 114891 | 115338 | yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z; |
| 114892 | 115339 | yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; |
| 114893 | 115340 | } |
| 114894 | 115341 | break; |
| | @@ -118020,11 +118467,11 @@ |
| 118020 | 118467 | ** and there are active VMs, then return SQLITE_BUSY. If a function |
| 118021 | 118468 | ** is being overridden/deleted but there are no active VMs, allow the |
| 118022 | 118469 | ** operation to continue but invalidate all precompiled statements. |
| 118023 | 118470 | */ |
| 118024 | 118471 | p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); |
| 118025 | | - if( p && p->iPrefEnc==enc && p->nArg==nArg ){ |
| 118472 | + if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ |
| 118026 | 118473 | if( db->nVdbeActive ){ |
| 118027 | 118474 | sqlite3Error(db, SQLITE_BUSY, |
| 118028 | 118475 | "unable to delete/modify user-function due to active statements"); |
| 118029 | 118476 | assert( !db->mallocFailed ); |
| 118030 | 118477 | return SQLITE_BUSY; |
| | @@ -118045,11 +118492,11 @@ |
| 118045 | 118492 | |
| 118046 | 118493 | if( pDestructor ){ |
| 118047 | 118494 | pDestructor->nRef++; |
| 118048 | 118495 | } |
| 118049 | 118496 | p->pDestructor = pDestructor; |
| 118050 | | - p->flags = 0; |
| 118497 | + p->funcFlags &= SQLITE_FUNC_ENCMASK; |
| 118051 | 118498 | p->xFunc = xFunc; |
| 118052 | 118499 | p->xStep = xStep; |
| 118053 | 118500 | p->xFinalize = xFinal; |
| 118054 | 118501 | p->pUserData = pUserData; |
| 118055 | 118502 | p->nArg = (u16)nArg; |
| 118056 | 118503 | |