| | @@ -673,11 +673,11 @@ |
| 673 | 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | 675 | */ |
| 676 | 676 | #define SQLITE_VERSION "3.7.15" |
| 677 | 677 | #define SQLITE_VERSION_NUMBER 3007015 |
| 678 | | -#define SQLITE_SOURCE_ID "2012-09-17 21:24:01 698b2a28004a9a2f0eabaadf36d833da4400b2bf" |
| 678 | +#define SQLITE_SOURCE_ID "2012-09-28 00:44:28 1e874629d7cf568368b912b295bd3001147d0b52" |
| 679 | 679 | |
| 680 | 680 | /* |
| 681 | 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | 683 | ** |
| | @@ -5315,10 +5315,13 @@ |
| 5315 | 5315 | ** successfully. An [error code] is returned otherwise.)^ |
| 5316 | 5316 | ** |
| 5317 | 5317 | ** ^Shared cache is disabled by default. But this might change in |
| 5318 | 5318 | ** future releases of SQLite. Applications that care about shared |
| 5319 | 5319 | ** cache setting should set it explicitly. |
| 5320 | +** |
| 5321 | +** This interface is threadsafe on processors where writing a |
| 5322 | +** 32-bit integer is atomic. |
| 5320 | 5323 | ** |
| 5321 | 5324 | ** See Also: [SQLite Shared-Cache Mode] |
| 5322 | 5325 | */ |
| 5323 | 5326 | SQLITE_API int sqlite3_enable_shared_cache(int); |
| 5324 | 5327 | |
| | @@ -8281,10 +8284,11 @@ |
| 8281 | 8284 | typedef struct NameContext NameContext; |
| 8282 | 8285 | typedef struct Parse Parse; |
| 8283 | 8286 | typedef struct RowSet RowSet; |
| 8284 | 8287 | typedef struct Savepoint Savepoint; |
| 8285 | 8288 | typedef struct Select Select; |
| 8289 | +typedef struct SelectDest SelectDest; |
| 8286 | 8290 | typedef struct SrcList SrcList; |
| 8287 | 8291 | typedef struct StrAccum StrAccum; |
| 8288 | 8292 | typedef struct Table Table; |
| 8289 | 8293 | typedef struct TableLock TableLock; |
| 8290 | 8294 | typedef struct Token Token; |
| | @@ -8887,11 +8891,11 @@ |
| 8887 | 8891 | #define OPFLG_IN3 0x0010 /* in3: P3 is an input */ |
| 8888 | 8892 | #define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ |
| 8889 | 8893 | #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ |
| 8890 | 8894 | #define OPFLG_INITIALIZER {\ |
| 8891 | 8895 | /* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\ |
| 8892 | | -/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ |
| 8896 | +/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\ |
| 8893 | 8897 | /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ |
| 8894 | 8898 | /* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\ |
| 8895 | 8899 | /* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ |
| 8896 | 8900 | /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ |
| 8897 | 8901 | /* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ |
| | @@ -9843,10 +9847,11 @@ |
| 9843 | 9847 | int flags; /* Miscellaneous flags. See below */ |
| 9844 | 9848 | i64 lastRowid; /* ROWID of most recent insert (see above) */ |
| 9845 | 9849 | unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ |
| 9846 | 9850 | int errCode; /* Most recent error code (SQLITE_*) */ |
| 9847 | 9851 | int errMask; /* & result codes with this before returning */ |
| 9852 | + u8 dbOptFlags; /* Flags to enable/disable optimizations */ |
| 9848 | 9853 | u8 autoCommit; /* The auto-commit flag. */ |
| 9849 | 9854 | u8 temp_store; /* 1: file 2: memory 0: default */ |
| 9850 | 9855 | u8 mallocFailed; /* True if we have seen a malloc failure */ |
| 9851 | 9856 | u8 dfltLockMode; /* Default locking-mode for attached dbs */ |
| 9852 | 9857 | signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ |
| | @@ -9947,50 +9952,62 @@ |
| 9947 | 9952 | #define ENC(db) ((db)->aDb[0].pSchema->enc) |
| 9948 | 9953 | |
| 9949 | 9954 | /* |
| 9950 | 9955 | ** Possible values for the sqlite3.flags. |
| 9951 | 9956 | */ |
| 9952 | | -#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */ |
| 9953 | | -#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */ |
| 9954 | | -#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */ |
| 9955 | | -#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */ |
| 9956 | | -#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */ |
| 9957 | +#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ |
| 9958 | +#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ |
| 9959 | +#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ |
| 9960 | +#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */ |
| 9961 | +#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */ |
| 9957 | 9962 | /* DELETE, or UPDATE and return */ |
| 9958 | 9963 | /* the count using a callback. */ |
| 9959 | | -#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */ |
| 9964 | +#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */ |
| 9960 | 9965 | /* result set is empty */ |
| 9961 | | -#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */ |
| 9962 | | -#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */ |
| 9963 | | -#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */ |
| 9964 | | - /* 0x00020000 Unused */ |
| 9965 | | -#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */ |
| 9966 | | -#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */ |
| 9967 | | -#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */ |
| 9968 | | -#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */ |
| 9969 | | -#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */ |
| 9970 | | -#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */ |
| 9971 | | -#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */ |
| 9972 | | -#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */ |
| 9973 | | -#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */ |
| 9974 | | -#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */ |
| 9975 | | -#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */ |
| 9976 | | -#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */ |
| 9977 | | -#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */ |
| 9966 | +#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */ |
| 9967 | +#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */ |
| 9968 | +#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */ |
| 9969 | + /* 0x00000200 Unused */ |
| 9970 | +#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */ |
| 9971 | +#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */ |
| 9972 | +#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */ |
| 9973 | +#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */ |
| 9974 | +#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */ |
| 9975 | +#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */ |
| 9976 | +#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */ |
| 9977 | +#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */ |
| 9978 | +#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */ |
| 9979 | +#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */ |
| 9980 | +#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */ |
| 9981 | +#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */ |
| 9982 | +#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */ |
| 9978 | 9983 | |
| 9979 | 9984 | /* |
| 9980 | | -** Bits of the sqlite3.flags field that are used by the |
| 9981 | | -** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface. |
| 9982 | | -** These must be the low-order bits of the flags field. |
| 9985 | +** Bits of the sqlite3.dbOptFlags field that are used by the |
| 9986 | +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to |
| 9987 | +** selectively disable various optimizations. |
| 9983 | 9988 | */ |
| 9984 | | -#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */ |
| 9985 | | -#define SQLITE_ColumnCache 0x02 /* Disable the column cache */ |
| 9986 | | -#define SQLITE_GroupByOrder 0x04 /* Disable GROUPBY cover of ORDERBY */ |
| 9987 | | -#define SQLITE_FactorOutConst 0x08 /* Disable factoring out constants */ |
| 9988 | | -#define SQLITE_IdxRealAsInt 0x10 /* Store REAL as INT in indices */ |
| 9989 | | -#define SQLITE_DistinctOpt 0x20 /* DISTINCT using indexes */ |
| 9990 | | -#define SQLITE_CoverIdxScan 0x40 /* Disable covering index scans */ |
| 9991 | | -#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ |
| 9989 | +#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ |
| 9990 | +#define SQLITE_ColumnCache 0x0002 /* Column cache */ |
| 9991 | +#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ |
| 9992 | +#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ |
| 9993 | +#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */ |
| 9994 | +#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ |
| 9995 | +#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ |
| 9996 | +#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ |
| 9997 | +#define SQLITE_AllOpts 0x00ff /* All optimizations */ |
| 9998 | + |
| 9999 | +/* |
| 10000 | +** Macros for testing whether or not optimizations are enabled or disabled. |
| 10001 | +*/ |
| 10002 | +#ifndef SQLITE_OMIT_BUILTIN_TEST |
| 10003 | +#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) |
| 10004 | +#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) |
| 10005 | +#else |
| 10006 | +#define OptimizationDisabled(db, mask) 0 |
| 10007 | +#define OptimizationEnabled(db, mask) 1 |
| 10008 | +#endif |
| 9992 | 10009 | |
| 9993 | 10010 | /* |
| 9994 | 10011 | ** Possible values for the sqlite.magic field. |
| 9995 | 10012 | ** The numbers are obtained at random and have no special meaning, other |
| 9996 | 10013 | ** than being distinct from one another. |
| | @@ -10922,11 +10939,12 @@ |
| 10922 | 10939 | ** is only used when wsFlags&WHERE_VIRTUALTABLE is true. It is never the |
| 10923 | 10940 | ** case that more than one of these conditions is true. |
| 10924 | 10941 | */ |
| 10925 | 10942 | struct WherePlan { |
| 10926 | 10943 | u32 wsFlags; /* WHERE_* flags that describe the strategy */ |
| 10927 | | - u32 nEq; /* Number of == constraints */ |
| 10944 | + u16 nEq; /* Number of == constraints */ |
| 10945 | + u16 nOBSat; /* Number of ORDER BY terms satisfied */ |
| 10928 | 10946 | double nRow; /* Estimated number of rows (for EQP) */ |
| 10929 | 10947 | union { |
| 10930 | 10948 | Index *pIdx; /* Index when WHERE_INDEXED is true */ |
| 10931 | 10949 | struct WhereTerm *pTerm; /* WHERE clause term for OR-search */ |
| 10932 | 10950 | sqlite3_index_info *pVtabIdx; /* Virtual table index to use */ |
| | @@ -10998,28 +11016,32 @@ |
| 10998 | 11016 | ** half does the tail of the WHERE loop. An instance of |
| 10999 | 11017 | ** this structure is returned by the first half and passed |
| 11000 | 11018 | ** into the second half to give some continuity. |
| 11001 | 11019 | */ |
| 11002 | 11020 | struct WhereInfo { |
| 11003 | | - Parse *pParse; /* Parsing and code generating context */ |
| 11004 | | - u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 11005 | | - u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */ |
| 11006 | | - u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 11007 | | - u8 eDistinct; |
| 11008 | | - SrcList *pTabList; /* List of tables in the join */ |
| 11009 | | - int iTop; /* The very beginning of the WHERE loop */ |
| 11010 | | - int iContinue; /* Jump here to continue with next record */ |
| 11011 | | - int iBreak; /* Jump here to break out of the loop */ |
| 11012 | | - int nLevel; /* Number of nested loop */ |
| 11013 | | - struct WhereClause *pWC; /* Decomposition of the WHERE clause */ |
| 11014 | | - double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ |
| 11015 | | - double nRowOut; /* Estimated number of output rows */ |
| 11016 | | - WhereLevel a[1]; /* Information about each nest loop in WHERE */ |
| 11021 | + Parse *pParse; /* Parsing and code generating context */ |
| 11022 | + SrcList *pTabList; /* List of tables in the join */ |
| 11023 | + u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */ |
| 11024 | + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ |
| 11025 | + u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ |
| 11026 | + u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ |
| 11027 | + u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ |
| 11028 | + int iTop; /* The very beginning of the WHERE loop */ |
| 11029 | + int iContinue; /* Jump here to continue with next record */ |
| 11030 | + int iBreak; /* Jump here to break out of the loop */ |
| 11031 | + int nLevel; /* Number of nested loop */ |
| 11032 | + struct WhereClause *pWC; /* Decomposition of the WHERE clause */ |
| 11033 | + double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ |
| 11034 | + double nRowOut; /* Estimated number of output rows */ |
| 11035 | + WhereLevel a[1]; /* Information about each nest loop in WHERE */ |
| 11017 | 11036 | }; |
| 11018 | 11037 | |
| 11019 | | -#define WHERE_DISTINCT_UNIQUE 1 |
| 11020 | | -#define WHERE_DISTINCT_ORDERED 2 |
| 11038 | +/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */ |
| 11039 | +#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ |
| 11040 | +#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ |
| 11041 | +#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ |
| 11042 | +#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */ |
| 11021 | 11043 | |
| 11022 | 11044 | /* |
| 11023 | 11045 | ** A NameContext defines a context in which to resolve table and column |
| 11024 | 11046 | ** names. The context consists of a list of tables (the pSrcList) field and |
| 11025 | 11047 | ** a list of named expression (pEList). The named expression list may |
| | @@ -11074,17 +11096,16 @@ |
| 11074 | 11096 | ** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor |
| 11075 | 11097 | ** the number of columns in P2 can be computed at the same time |
| 11076 | 11098 | ** as the OP_OpenEphm instruction is coded because not |
| 11077 | 11099 | ** enough information about the compound query is known at that point. |
| 11078 | 11100 | ** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences |
| 11079 | | -** for the result set. The KeyInfo for addrOpenTran[2] contains collating |
| 11101 | +** for the result set. The KeyInfo for addrOpenEphm[2] contains collating |
| 11080 | 11102 | ** sequences for the ORDER BY clause. |
| 11081 | 11103 | */ |
| 11082 | 11104 | struct Select { |
| 11083 | 11105 | ExprList *pEList; /* The fields of the result */ |
| 11084 | 11106 | u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ |
| 11085 | | - char affinity; /* MakeRecord with this affinity for SRT_Set */ |
| 11086 | 11107 | u16 selFlags; /* Various SF_* values */ |
| 11087 | 11108 | int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ |
| 11088 | 11109 | int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ |
| 11089 | 11110 | double nSelectRow; /* Estimated number of result rows */ |
| 11090 | 11111 | SrcList *pSrc; /* The FROM clause */ |
| | @@ -11131,17 +11152,16 @@ |
| 11131 | 11152 | #define SRT_Table 8 /* Store result as data with an automatic rowid */ |
| 11132 | 11153 | #define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */ |
| 11133 | 11154 | #define SRT_Coroutine 10 /* Generate a single row of result */ |
| 11134 | 11155 | |
| 11135 | 11156 | /* |
| 11136 | | -** A structure used to customize the behavior of sqlite3Select(). See |
| 11137 | | -** comments above sqlite3Select() for details. |
| 11157 | +** An instance of this object describes where to put of the results of |
| 11158 | +** a SELECT statement. |
| 11138 | 11159 | */ |
| 11139 | | -typedef struct SelectDest SelectDest; |
| 11140 | 11160 | struct SelectDest { |
| 11141 | | - u8 eDest; /* How to dispose of the results */ |
| 11142 | | - u8 affSdst; /* Affinity used when eDest==SRT_Set */ |
| 11161 | + u8 eDest; /* How to dispose of the results. On of SRT_* above. */ |
| 11162 | + char affSdst; /* Affinity used when eDest==SRT_Set */ |
| 11143 | 11163 | int iSDParm; /* A parameter used by the eDest disposal method */ |
| 11144 | 11164 | int iSdst; /* Base register where results are written */ |
| 11145 | 11165 | int nSdst; /* Number of registers allocated */ |
| 11146 | 11166 | }; |
| 11147 | 11167 | |
| | @@ -11826,17 +11846,15 @@ |
| 11826 | 11846 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) |
| 11827 | 11847 | SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *); |
| 11828 | 11848 | #endif |
| 11829 | 11849 | SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); |
| 11830 | 11850 | SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); |
| 11831 | | -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 11832 | | - Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int); |
| 11851 | +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); |
| 11833 | 11852 | SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); |
| 11834 | 11853 | SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); |
| 11835 | 11854 | SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); |
| 11836 | 11855 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); |
| 11837 | | -SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int); |
| 11838 | 11856 | SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); |
| 11839 | 11857 | SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); |
| 11840 | 11858 | SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); |
| 11841 | 11859 | SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); |
| 11842 | 11860 | SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); |
| | @@ -13178,11 +13196,13 @@ |
| 13178 | 13196 | #define MEM_Real 0x0008 /* Value is a real number */ |
| 13179 | 13197 | #define MEM_Blob 0x0010 /* Value is a BLOB */ |
| 13180 | 13198 | #define MEM_RowSet 0x0020 /* Value is a RowSet object */ |
| 13181 | 13199 | #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ |
| 13182 | 13200 | #define MEM_Invalid 0x0080 /* Value is undefined */ |
| 13183 | | -#define MEM_TypeMask 0x00ff /* Mask of type bits */ |
| 13201 | +#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ |
| 13202 | +#define MEM_TypeMask 0x01ff /* Mask of type bits */ |
| 13203 | + |
| 13184 | 13204 | |
| 13185 | 13205 | /* Whenever Mem contains a valid string or blob representation, one of |
| 13186 | 13206 | ** the following flags must be set to determine the memory management |
| 13187 | 13207 | ** policy for Mem.z. The MEM_Term flag tells us whether or not the |
| 13188 | 13208 | ** string is \000 or \u0000 terminated |
| | @@ -63693,10 +63713,11 @@ |
| 63693 | 63713 | struct OP_Yield_stack_vars { |
| 63694 | 63714 | int pcDest; |
| 63695 | 63715 | } aa; |
| 63696 | 63716 | struct OP_Null_stack_vars { |
| 63697 | 63717 | int cnt; |
| 63718 | + u16 nullFlag; |
| 63698 | 63719 | } ab; |
| 63699 | 63720 | struct OP_Variable_stack_vars { |
| 63700 | 63721 | Mem *pVar; /* Value being transferred */ |
| 63701 | 63722 | } ac; |
| 63702 | 63723 | struct OP_Move_stack_vars { |
| | @@ -63703,60 +63724,63 @@ |
| 63703 | 63724 | char *zMalloc; /* Holding variable for allocated memory */ |
| 63704 | 63725 | int n; /* Number of registers left to copy */ |
| 63705 | 63726 | int p1; /* Register to copy from */ |
| 63706 | 63727 | int p2; /* Register to copy to */ |
| 63707 | 63728 | } ad; |
| 63729 | + struct OP_Copy_stack_vars { |
| 63730 | + int n; |
| 63731 | + } ae; |
| 63708 | 63732 | struct OP_ResultRow_stack_vars { |
| 63709 | 63733 | Mem *pMem; |
| 63710 | 63734 | int i; |
| 63711 | | - } ae; |
| 63735 | + } af; |
| 63712 | 63736 | struct OP_Concat_stack_vars { |
| 63713 | 63737 | i64 nByte; |
| 63714 | | - } af; |
| 63738 | + } ag; |
| 63715 | 63739 | struct OP_Remainder_stack_vars { |
| 63716 | 63740 | int flags; /* Combined MEM_* flags from both inputs */ |
| 63717 | 63741 | i64 iA; /* Integer value of left operand */ |
| 63718 | 63742 | i64 iB; /* Integer value of right operand */ |
| 63719 | 63743 | double rA; /* Real value of left operand */ |
| 63720 | 63744 | double rB; /* Real value of right operand */ |
| 63721 | | - } ag; |
| 63745 | + } ah; |
| 63722 | 63746 | struct OP_Function_stack_vars { |
| 63723 | 63747 | int i; |
| 63724 | 63748 | Mem *pArg; |
| 63725 | 63749 | sqlite3_context ctx; |
| 63726 | 63750 | sqlite3_value **apVal; |
| 63727 | 63751 | int n; |
| 63728 | | - } ah; |
| 63752 | + } ai; |
| 63729 | 63753 | struct OP_ShiftRight_stack_vars { |
| 63730 | 63754 | i64 iA; |
| 63731 | 63755 | u64 uA; |
| 63732 | 63756 | i64 iB; |
| 63733 | 63757 | u8 op; |
| 63734 | | - } ai; |
| 63758 | + } aj; |
| 63735 | 63759 | struct OP_Ge_stack_vars { |
| 63736 | 63760 | int res; /* Result of the comparison of pIn1 against pIn3 */ |
| 63737 | 63761 | char affinity; /* Affinity to use for comparison */ |
| 63738 | 63762 | u16 flags1; /* Copy of initial value of pIn1->flags */ |
| 63739 | 63763 | u16 flags3; /* Copy of initial value of pIn3->flags */ |
| 63740 | | - } aj; |
| 63764 | + } ak; |
| 63741 | 63765 | struct OP_Compare_stack_vars { |
| 63742 | 63766 | int n; |
| 63743 | 63767 | int i; |
| 63744 | 63768 | int p1; |
| 63745 | 63769 | int p2; |
| 63746 | 63770 | const KeyInfo *pKeyInfo; |
| 63747 | 63771 | int idx; |
| 63748 | 63772 | CollSeq *pColl; /* Collating sequence to use on this term */ |
| 63749 | 63773 | int bRev; /* True for DESCENDING sort order */ |
| 63750 | | - } ak; |
| 63774 | + } al; |
| 63751 | 63775 | struct OP_Or_stack_vars { |
| 63752 | 63776 | int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 63753 | 63777 | int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 63754 | | - } al; |
| 63778 | + } am; |
| 63755 | 63779 | struct OP_IfNot_stack_vars { |
| 63756 | 63780 | int c; |
| 63757 | | - } am; |
| 63781 | + } an; |
| 63758 | 63782 | struct OP_Column_stack_vars { |
| 63759 | 63783 | u32 payloadSize; /* Number of bytes in the record */ |
| 63760 | 63784 | i64 payloadSize64; /* Number of bytes in the record */ |
| 63761 | 63785 | int p1; /* P1 value of the opcode */ |
| 63762 | 63786 | int p2; /* column number to retrieve */ |
| | @@ -63777,15 +63801,15 @@ |
| 63777 | 63801 | u32 szField; /* Number of bytes in the content of a field */ |
| 63778 | 63802 | int szHdr; /* Size of the header size field at start of record */ |
| 63779 | 63803 | int avail; /* Number of bytes of available data */ |
| 63780 | 63804 | u32 t; /* A type code from the record header */ |
| 63781 | 63805 | Mem *pReg; /* PseudoTable input register */ |
| 63782 | | - } an; |
| 63806 | + } ao; |
| 63783 | 63807 | struct OP_Affinity_stack_vars { |
| 63784 | 63808 | const char *zAffinity; /* The affinity to be applied */ |
| 63785 | 63809 | char cAff; /* A single character of affinity */ |
| 63786 | | - } ao; |
| 63810 | + } ap; |
| 63787 | 63811 | struct OP_MakeRecord_stack_vars { |
| 63788 | 63812 | u8 *zNewRecord; /* A buffer to hold the data for the new record */ |
| 63789 | 63813 | Mem *pRec; /* The new record */ |
| 63790 | 63814 | u64 nData; /* Number of bytes of data space */ |
| 63791 | 63815 | int nHdr; /* Number of bytes of header space */ |
| | @@ -63798,108 +63822,108 @@ |
| 63798 | 63822 | int nField; /* Number of fields in the record */ |
| 63799 | 63823 | char *zAffinity; /* The affinity string for the record */ |
| 63800 | 63824 | int file_format; /* File format to use for encoding */ |
| 63801 | 63825 | int i; /* Space used in zNewRecord[] */ |
| 63802 | 63826 | int len; /* Length of a field */ |
| 63803 | | - } ap; |
| 63827 | + } aq; |
| 63804 | 63828 | struct OP_Count_stack_vars { |
| 63805 | 63829 | i64 nEntry; |
| 63806 | 63830 | BtCursor *pCrsr; |
| 63807 | | - } aq; |
| 63831 | + } ar; |
| 63808 | 63832 | struct OP_Savepoint_stack_vars { |
| 63809 | 63833 | int p1; /* Value of P1 operand */ |
| 63810 | 63834 | char *zName; /* Name of savepoint */ |
| 63811 | 63835 | int nName; |
| 63812 | 63836 | Savepoint *pNew; |
| 63813 | 63837 | Savepoint *pSavepoint; |
| 63814 | 63838 | Savepoint *pTmp; |
| 63815 | 63839 | int iSavepoint; |
| 63816 | 63840 | int ii; |
| 63817 | | - } ar; |
| 63841 | + } as; |
| 63818 | 63842 | struct OP_AutoCommit_stack_vars { |
| 63819 | 63843 | int desiredAutoCommit; |
| 63820 | 63844 | int iRollback; |
| 63821 | 63845 | int turnOnAC; |
| 63822 | | - } as; |
| 63846 | + } at; |
| 63823 | 63847 | struct OP_Transaction_stack_vars { |
| 63824 | 63848 | Btree *pBt; |
| 63825 | | - } at; |
| 63849 | + } au; |
| 63826 | 63850 | struct OP_ReadCookie_stack_vars { |
| 63827 | 63851 | int iMeta; |
| 63828 | 63852 | int iDb; |
| 63829 | 63853 | int iCookie; |
| 63830 | | - } au; |
| 63854 | + } av; |
| 63831 | 63855 | struct OP_SetCookie_stack_vars { |
| 63832 | 63856 | Db *pDb; |
| 63833 | | - } av; |
| 63857 | + } aw; |
| 63834 | 63858 | struct OP_VerifyCookie_stack_vars { |
| 63835 | 63859 | int iMeta; |
| 63836 | 63860 | int iGen; |
| 63837 | 63861 | Btree *pBt; |
| 63838 | | - } aw; |
| 63862 | + } ax; |
| 63839 | 63863 | struct OP_OpenWrite_stack_vars { |
| 63840 | 63864 | int nField; |
| 63841 | 63865 | KeyInfo *pKeyInfo; |
| 63842 | 63866 | int p2; |
| 63843 | 63867 | int iDb; |
| 63844 | 63868 | int wrFlag; |
| 63845 | 63869 | Btree *pX; |
| 63846 | 63870 | VdbeCursor *pCur; |
| 63847 | 63871 | Db *pDb; |
| 63848 | | - } ax; |
| 63872 | + } ay; |
| 63849 | 63873 | struct OP_OpenEphemeral_stack_vars { |
| 63850 | 63874 | VdbeCursor *pCx; |
| 63851 | | - } ay; |
| 63875 | + } az; |
| 63852 | 63876 | struct OP_SorterOpen_stack_vars { |
| 63853 | 63877 | VdbeCursor *pCx; |
| 63854 | | - } az; |
| 63878 | + } ba; |
| 63855 | 63879 | struct OP_OpenPseudo_stack_vars { |
| 63856 | 63880 | VdbeCursor *pCx; |
| 63857 | | - } ba; |
| 63881 | + } bb; |
| 63858 | 63882 | struct OP_SeekGt_stack_vars { |
| 63859 | 63883 | int res; |
| 63860 | 63884 | int oc; |
| 63861 | 63885 | VdbeCursor *pC; |
| 63862 | 63886 | UnpackedRecord r; |
| 63863 | 63887 | int nField; |
| 63864 | 63888 | i64 iKey; /* The rowid we are to seek to */ |
| 63865 | | - } bb; |
| 63889 | + } bc; |
| 63866 | 63890 | struct OP_Seek_stack_vars { |
| 63867 | 63891 | VdbeCursor *pC; |
| 63868 | | - } bc; |
| 63892 | + } bd; |
| 63869 | 63893 | struct OP_Found_stack_vars { |
| 63870 | 63894 | int alreadyExists; |
| 63871 | 63895 | VdbeCursor *pC; |
| 63872 | 63896 | int res; |
| 63873 | 63897 | char *pFree; |
| 63874 | 63898 | UnpackedRecord *pIdxKey; |
| 63875 | 63899 | UnpackedRecord r; |
| 63876 | 63900 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 63877 | | - } bd; |
| 63901 | + } be; |
| 63878 | 63902 | struct OP_IsUnique_stack_vars { |
| 63879 | 63903 | u16 ii; |
| 63880 | 63904 | VdbeCursor *pCx; |
| 63881 | 63905 | BtCursor *pCrsr; |
| 63882 | 63906 | u16 nField; |
| 63883 | 63907 | Mem *aMx; |
| 63884 | 63908 | UnpackedRecord r; /* B-Tree index search key */ |
| 63885 | 63909 | i64 R; /* Rowid stored in register P3 */ |
| 63886 | | - } be; |
| 63910 | + } bf; |
| 63887 | 63911 | struct OP_NotExists_stack_vars { |
| 63888 | 63912 | VdbeCursor *pC; |
| 63889 | 63913 | BtCursor *pCrsr; |
| 63890 | 63914 | int res; |
| 63891 | 63915 | u64 iKey; |
| 63892 | | - } bf; |
| 63916 | + } bg; |
| 63893 | 63917 | struct OP_NewRowid_stack_vars { |
| 63894 | 63918 | i64 v; /* The new rowid */ |
| 63895 | 63919 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 63896 | 63920 | int res; /* Result of an sqlite3BtreeLast() */ |
| 63897 | 63921 | int cnt; /* Counter to limit the number of searches */ |
| 63898 | 63922 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 63899 | 63923 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 63900 | | - } bg; |
| 63924 | + } bh; |
| 63901 | 63925 | struct OP_InsertInt_stack_vars { |
| 63902 | 63926 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 63903 | 63927 | Mem *pKey; /* MEM cell holding key for the record */ |
| 63904 | 63928 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 63905 | 63929 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| | @@ -63906,160 +63930,163 @@ |
| 63906 | 63930 | int nZero; /* Number of zero-bytes to append */ |
| 63907 | 63931 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 63908 | 63932 | const char *zDb; /* database name - used by the update hook */ |
| 63909 | 63933 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 63910 | 63934 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 63911 | | - } bh; |
| 63935 | + } bi; |
| 63912 | 63936 | struct OP_Delete_stack_vars { |
| 63913 | 63937 | i64 iKey; |
| 63914 | 63938 | VdbeCursor *pC; |
| 63915 | | - } bi; |
| 63939 | + } bj; |
| 63916 | 63940 | struct OP_SorterCompare_stack_vars { |
| 63917 | 63941 | VdbeCursor *pC; |
| 63918 | 63942 | int res; |
| 63919 | | - } bj; |
| 63943 | + } bk; |
| 63920 | 63944 | struct OP_SorterData_stack_vars { |
| 63921 | 63945 | VdbeCursor *pC; |
| 63922 | | - } bk; |
| 63946 | + } bl; |
| 63923 | 63947 | struct OP_RowData_stack_vars { |
| 63924 | 63948 | VdbeCursor *pC; |
| 63925 | 63949 | BtCursor *pCrsr; |
| 63926 | 63950 | u32 n; |
| 63927 | 63951 | i64 n64; |
| 63928 | | - } bl; |
| 63952 | + } bm; |
| 63929 | 63953 | struct OP_Rowid_stack_vars { |
| 63930 | 63954 | VdbeCursor *pC; |
| 63931 | 63955 | i64 v; |
| 63932 | 63956 | sqlite3_vtab *pVtab; |
| 63933 | 63957 | const sqlite3_module *pModule; |
| 63934 | | - } bm; |
| 63958 | + } bn; |
| 63935 | 63959 | struct OP_NullRow_stack_vars { |
| 63936 | 63960 | VdbeCursor *pC; |
| 63937 | | - } bn; |
| 63961 | + } bo; |
| 63938 | 63962 | struct OP_Last_stack_vars { |
| 63939 | 63963 | VdbeCursor *pC; |
| 63940 | 63964 | BtCursor *pCrsr; |
| 63941 | 63965 | int res; |
| 63942 | | - } bo; |
| 63966 | + } bp; |
| 63943 | 63967 | struct OP_Rewind_stack_vars { |
| 63944 | 63968 | VdbeCursor *pC; |
| 63945 | 63969 | BtCursor *pCrsr; |
| 63946 | 63970 | int res; |
| 63947 | | - } bp; |
| 63971 | + } bq; |
| 63948 | 63972 | struct OP_Next_stack_vars { |
| 63949 | 63973 | VdbeCursor *pC; |
| 63950 | 63974 | int res; |
| 63951 | | - } bq; |
| 63975 | + } br; |
| 63952 | 63976 | struct OP_IdxInsert_stack_vars { |
| 63953 | 63977 | VdbeCursor *pC; |
| 63954 | 63978 | BtCursor *pCrsr; |
| 63955 | 63979 | int nKey; |
| 63956 | 63980 | const char *zKey; |
| 63957 | | - } br; |
| 63981 | + } bs; |
| 63958 | 63982 | struct OP_IdxDelete_stack_vars { |
| 63959 | 63983 | VdbeCursor *pC; |
| 63960 | 63984 | BtCursor *pCrsr; |
| 63961 | 63985 | int res; |
| 63962 | 63986 | UnpackedRecord r; |
| 63963 | | - } bs; |
| 63987 | + } bt; |
| 63964 | 63988 | struct OP_IdxRowid_stack_vars { |
| 63965 | 63989 | BtCursor *pCrsr; |
| 63966 | 63990 | VdbeCursor *pC; |
| 63967 | 63991 | i64 rowid; |
| 63968 | | - } bt; |
| 63992 | + } bu; |
| 63969 | 63993 | struct OP_IdxGE_stack_vars { |
| 63970 | 63994 | VdbeCursor *pC; |
| 63971 | 63995 | int res; |
| 63972 | 63996 | UnpackedRecord r; |
| 63973 | | - } bu; |
| 63997 | + } bv; |
| 63974 | 63998 | struct OP_Destroy_stack_vars { |
| 63975 | 63999 | int iMoved; |
| 63976 | 64000 | int iCnt; |
| 63977 | 64001 | Vdbe *pVdbe; |
| 63978 | 64002 | int iDb; |
| 63979 | | - } bv; |
| 64003 | + } bw; |
| 63980 | 64004 | struct OP_Clear_stack_vars { |
| 63981 | 64005 | int nChange; |
| 63982 | | - } bw; |
| 64006 | + } bx; |
| 63983 | 64007 | struct OP_CreateTable_stack_vars { |
| 63984 | 64008 | int pgno; |
| 63985 | 64009 | int flags; |
| 63986 | 64010 | Db *pDb; |
| 63987 | | - } bx; |
| 64011 | + } by; |
| 63988 | 64012 | struct OP_ParseSchema_stack_vars { |
| 63989 | 64013 | int iDb; |
| 63990 | 64014 | const char *zMaster; |
| 63991 | 64015 | char *zSql; |
| 63992 | 64016 | InitData initData; |
| 63993 | | - } by; |
| 64017 | + } bz; |
| 63994 | 64018 | struct OP_IntegrityCk_stack_vars { |
| 63995 | 64019 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 63996 | 64020 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 63997 | 64021 | int j; /* Loop counter */ |
| 63998 | 64022 | int nErr; /* Number of errors reported */ |
| 63999 | 64023 | char *z; /* Text of the error report */ |
| 64000 | 64024 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 64001 | | - } bz; |
| 64025 | + } ca; |
| 64002 | 64026 | struct OP_RowSetRead_stack_vars { |
| 64003 | 64027 | i64 val; |
| 64004 | | - } ca; |
| 64028 | + } cb; |
| 64005 | 64029 | struct OP_RowSetTest_stack_vars { |
| 64006 | 64030 | int iSet; |
| 64007 | 64031 | int exists; |
| 64008 | | - } cb; |
| 64032 | + } cc; |
| 64009 | 64033 | struct OP_Program_stack_vars { |
| 64010 | 64034 | int nMem; /* Number of memory registers for sub-program */ |
| 64011 | 64035 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 64012 | 64036 | Mem *pRt; /* Register to allocate runtime space */ |
| 64013 | 64037 | Mem *pMem; /* Used to iterate through memory cells */ |
| 64014 | 64038 | Mem *pEnd; /* Last memory cell in new array */ |
| 64015 | 64039 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 64016 | 64040 | SubProgram *pProgram; /* Sub-program to execute */ |
| 64017 | 64041 | void *t; /* Token identifying trigger */ |
| 64018 | | - } cc; |
| 64042 | + } cd; |
| 64019 | 64043 | struct OP_Param_stack_vars { |
| 64020 | 64044 | VdbeFrame *pFrame; |
| 64021 | 64045 | Mem *pIn; |
| 64022 | | - } cd; |
| 64046 | + } ce; |
| 64023 | 64047 | struct OP_MemMax_stack_vars { |
| 64024 | 64048 | Mem *pIn1; |
| 64025 | 64049 | VdbeFrame *pFrame; |
| 64026 | | - } ce; |
| 64050 | + } cf; |
| 64027 | 64051 | struct OP_AggStep_stack_vars { |
| 64028 | 64052 | int n; |
| 64029 | 64053 | int i; |
| 64030 | 64054 | Mem *pMem; |
| 64031 | 64055 | Mem *pRec; |
| 64032 | 64056 | sqlite3_context ctx; |
| 64033 | 64057 | sqlite3_value **apVal; |
| 64034 | | - } cf; |
| 64058 | + } cg; |
| 64035 | 64059 | struct OP_AggFinal_stack_vars { |
| 64036 | 64060 | Mem *pMem; |
| 64037 | | - } cg; |
| 64061 | + } ch; |
| 64038 | 64062 | struct OP_Checkpoint_stack_vars { |
| 64039 | 64063 | int i; /* Loop counter */ |
| 64040 | 64064 | int aRes[3]; /* Results */ |
| 64041 | 64065 | Mem *pMem; /* Write results here */ |
| 64042 | | - } ch; |
| 64066 | + } ci; |
| 64043 | 64067 | struct OP_JournalMode_stack_vars { |
| 64044 | 64068 | Btree *pBt; /* Btree to change journal mode of */ |
| 64045 | 64069 | Pager *pPager; /* Pager associated with pBt */ |
| 64046 | 64070 | int eNew; /* New journal mode */ |
| 64047 | 64071 | int eOld; /* The old journal mode */ |
| 64048 | | - } ci; |
| 64072 | +#ifndef SQLITE_OMIT_WAL |
| 64073 | + const char *zFilename; /* Name of database file for pPager */ |
| 64074 | +#endif |
| 64075 | + } cj; |
| 64049 | 64076 | struct OP_IncrVacuum_stack_vars { |
| 64050 | 64077 | Btree *pBt; |
| 64051 | | - } cj; |
| 64078 | + } ck; |
| 64052 | 64079 | struct OP_VBegin_stack_vars { |
| 64053 | 64080 | VTable *pVTab; |
| 64054 | | - } ck; |
| 64081 | + } cl; |
| 64055 | 64082 | struct OP_VOpen_stack_vars { |
| 64056 | 64083 | VdbeCursor *pCur; |
| 64057 | 64084 | sqlite3_vtab_cursor *pVtabCursor; |
| 64058 | 64085 | sqlite3_vtab *pVtab; |
| 64059 | 64086 | sqlite3_module *pModule; |
| 64060 | | - } cl; |
| 64087 | + } cm; |
| 64061 | 64088 | struct OP_VFilter_stack_vars { |
| 64062 | 64089 | int nArg; |
| 64063 | 64090 | int iQuery; |
| 64064 | 64091 | const sqlite3_module *pModule; |
| 64065 | 64092 | Mem *pQuery; |
| | @@ -64068,40 +64095,40 @@ |
| 64068 | 64095 | sqlite3_vtab *pVtab; |
| 64069 | 64096 | VdbeCursor *pCur; |
| 64070 | 64097 | int res; |
| 64071 | 64098 | int i; |
| 64072 | 64099 | Mem **apArg; |
| 64073 | | - } cm; |
| 64100 | + } cn; |
| 64074 | 64101 | struct OP_VColumn_stack_vars { |
| 64075 | 64102 | sqlite3_vtab *pVtab; |
| 64076 | 64103 | const sqlite3_module *pModule; |
| 64077 | 64104 | Mem *pDest; |
| 64078 | 64105 | sqlite3_context sContext; |
| 64079 | | - } cn; |
| 64106 | + } co; |
| 64080 | 64107 | struct OP_VNext_stack_vars { |
| 64081 | 64108 | sqlite3_vtab *pVtab; |
| 64082 | 64109 | const sqlite3_module *pModule; |
| 64083 | 64110 | int res; |
| 64084 | 64111 | VdbeCursor *pCur; |
| 64085 | | - } co; |
| 64112 | + } cp; |
| 64086 | 64113 | struct OP_VRename_stack_vars { |
| 64087 | 64114 | sqlite3_vtab *pVtab; |
| 64088 | 64115 | Mem *pName; |
| 64089 | | - } cp; |
| 64116 | + } cq; |
| 64090 | 64117 | struct OP_VUpdate_stack_vars { |
| 64091 | 64118 | sqlite3_vtab *pVtab; |
| 64092 | 64119 | sqlite3_module *pModule; |
| 64093 | 64120 | int nArg; |
| 64094 | 64121 | int i; |
| 64095 | 64122 | sqlite_int64 rowid; |
| 64096 | 64123 | Mem **apArg; |
| 64097 | 64124 | Mem *pX; |
| 64098 | | - } cq; |
| 64125 | + } cr; |
| 64099 | 64126 | struct OP_Trace_stack_vars { |
| 64100 | 64127 | char *zTrace; |
| 64101 | 64128 | char *z; |
| 64102 | | - } cr; |
| 64129 | + } cs; |
| 64103 | 64130 | } u; |
| 64104 | 64131 | /* End automatically generated code |
| 64105 | 64132 | ********************************************************************/ |
| 64106 | 64133 | |
| 64107 | 64134 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| | @@ -64488,29 +64515,34 @@ |
| 64488 | 64515 | pOut->enc = encoding; |
| 64489 | 64516 | UPDATE_MAX_BLOBSIZE(pOut); |
| 64490 | 64517 | break; |
| 64491 | 64518 | } |
| 64492 | 64519 | |
| 64493 | | -/* Opcode: Null * P2 P3 * * |
| 64520 | +/* Opcode: Null P1 P2 P3 * * |
| 64494 | 64521 | ** |
| 64495 | 64522 | ** Write a NULL into registers P2. If P3 greater than P2, then also write |
| 64496 | | -** NULL into register P3 and ever register in between P2 and P3. If P3 |
| 64523 | +** NULL into register P3 and every register in between P2 and P3. If P3 |
| 64497 | 64524 | ** is less than P2 (typically P3 is zero) then only register P2 is |
| 64498 | | -** set to NULL |
| 64525 | +** set to NULL. |
| 64526 | +** |
| 64527 | +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that |
| 64528 | +** NULL values will not compare equal even if SQLITE_NULLEQ is set on |
| 64529 | +** OP_Ne or OP_Eq. |
| 64499 | 64530 | */ |
| 64500 | 64531 | case OP_Null: { /* out2-prerelease */ |
| 64501 | 64532 | #if 0 /* local variables moved into u.ab */ |
| 64502 | 64533 | int cnt; |
| 64534 | + u16 nullFlag; |
| 64503 | 64535 | #endif /* local variables moved into u.ab */ |
| 64504 | 64536 | u.ab.cnt = pOp->p3-pOp->p2; |
| 64505 | 64537 | assert( pOp->p3<=p->nMem ); |
| 64506 | | - pOut->flags = MEM_Null; |
| 64538 | + pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 64507 | 64539 | while( u.ab.cnt>0 ){ |
| 64508 | 64540 | pOut++; |
| 64509 | 64541 | memAboutToChange(p, pOut); |
| 64510 | 64542 | VdbeMemRelease(pOut); |
| 64511 | | - pOut->flags = MEM_Null; |
| 64543 | + pOut->flags = u.ab.nullFlag; |
| 64512 | 64544 | u.ab.cnt--; |
| 64513 | 64545 | } |
| 64514 | 64546 | break; |
| 64515 | 64547 | } |
| 64516 | 64548 | |
| | @@ -64551,24 +64583,24 @@ |
| 64551 | 64583 | break; |
| 64552 | 64584 | } |
| 64553 | 64585 | |
| 64554 | 64586 | /* Opcode: Move P1 P2 P3 * * |
| 64555 | 64587 | ** |
| 64556 | | -** Move the values in register P1..P1+P3-1 over into |
| 64557 | | -** registers P2..P2+P3-1. Registers P1..P1+P1-1 are |
| 64588 | +** Move the values in register P1..P1+P3 over into |
| 64589 | +** registers P2..P2+P3. Registers P1..P1+P3 are |
| 64558 | 64590 | ** left holding a NULL. It is an error for register ranges |
| 64559 | | -** P1..P1+P3-1 and P2..P2+P3-1 to overlap. |
| 64591 | +** P1..P1+P3 and P2..P2+P3 to overlap. |
| 64560 | 64592 | */ |
| 64561 | 64593 | case OP_Move: { |
| 64562 | 64594 | #if 0 /* local variables moved into u.ad */ |
| 64563 | 64595 | char *zMalloc; /* Holding variable for allocated memory */ |
| 64564 | 64596 | int n; /* Number of registers left to copy */ |
| 64565 | 64597 | int p1; /* Register to copy from */ |
| 64566 | 64598 | int p2; /* Register to copy to */ |
| 64567 | 64599 | #endif /* local variables moved into u.ad */ |
| 64568 | 64600 | |
| 64569 | | - u.ad.n = pOp->p3; |
| 64601 | + u.ad.n = pOp->p3 + 1; |
| 64570 | 64602 | u.ad.p1 = pOp->p1; |
| 64571 | 64603 | u.ad.p2 = pOp->p2; |
| 64572 | 64604 | assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 ); |
| 64573 | 64605 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 64574 | 64606 | |
| | @@ -64593,24 +64625,34 @@ |
| 64593 | 64625 | pOut++; |
| 64594 | 64626 | } |
| 64595 | 64627 | break; |
| 64596 | 64628 | } |
| 64597 | 64629 | |
| 64598 | | -/* Opcode: Copy P1 P2 * * * |
| 64630 | +/* Opcode: Copy P1 P2 P3 * * |
| 64599 | 64631 | ** |
| 64600 | | -** Make a copy of register P1 into register P2. |
| 64632 | +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. |
| 64601 | 64633 | ** |
| 64602 | 64634 | ** This instruction makes a deep copy of the value. A duplicate |
| 64603 | 64635 | ** is made of any string or blob constant. See also OP_SCopy. |
| 64604 | 64636 | */ |
| 64605 | | -case OP_Copy: { /* in1, out2 */ |
| 64637 | +case OP_Copy: { |
| 64638 | +#if 0 /* local variables moved into u.ae */ |
| 64639 | + int n; |
| 64640 | +#endif /* local variables moved into u.ae */ |
| 64641 | + |
| 64642 | + u.ae.n = pOp->p3; |
| 64606 | 64643 | pIn1 = &aMem[pOp->p1]; |
| 64607 | 64644 | pOut = &aMem[pOp->p2]; |
| 64608 | 64645 | assert( pOut!=pIn1 ); |
| 64609 | | - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); |
| 64610 | | - Deephemeralize(pOut); |
| 64611 | | - REGISTER_TRACE(pOp->p2, pOut); |
| 64646 | + while( 1 ){ |
| 64647 | + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); |
| 64648 | + Deephemeralize(pOut); |
| 64649 | + REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut); |
| 64650 | + if( (u.ae.n--)==0 ) break; |
| 64651 | + pOut++; |
| 64652 | + pIn1++; |
| 64653 | + } |
| 64612 | 64654 | break; |
| 64613 | 64655 | } |
| 64614 | 64656 | |
| 64615 | 64657 | /* Opcode: SCopy P1 P2 * * * |
| 64616 | 64658 | ** |
| | @@ -64643,14 +64685,14 @@ |
| 64643 | 64685 | ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt |
| 64644 | 64686 | ** structure to provide access to the top P1 values as the result |
| 64645 | 64687 | ** row. |
| 64646 | 64688 | */ |
| 64647 | 64689 | case OP_ResultRow: { |
| 64648 | | -#if 0 /* local variables moved into u.ae */ |
| 64690 | +#if 0 /* local variables moved into u.af */ |
| 64649 | 64691 | Mem *pMem; |
| 64650 | 64692 | int i; |
| 64651 | | -#endif /* local variables moved into u.ae */ |
| 64693 | +#endif /* local variables moved into u.af */ |
| 64652 | 64694 | assert( p->nResColumn==pOp->p2 ); |
| 64653 | 64695 | assert( pOp->p1>0 ); |
| 64654 | 64696 | assert( pOp->p1+pOp->p2<=p->nMem+1 ); |
| 64655 | 64697 | |
| 64656 | 64698 | /* If this statement has violated immediate foreign key constraints, do |
| | @@ -64688,19 +64730,19 @@ |
| 64688 | 64730 | |
| 64689 | 64731 | /* Make sure the results of the current row are \000 terminated |
| 64690 | 64732 | ** and have an assigned type. The results are de-ephemeralized as |
| 64691 | 64733 | ** a side effect. |
| 64692 | 64734 | */ |
| 64693 | | - u.ae.pMem = p->pResultSet = &aMem[pOp->p1]; |
| 64694 | | - for(u.ae.i=0; u.ae.i<pOp->p2; u.ae.i++){ |
| 64695 | | - assert( memIsValid(&u.ae.pMem[u.ae.i]) ); |
| 64696 | | - Deephemeralize(&u.ae.pMem[u.ae.i]); |
| 64697 | | - assert( (u.ae.pMem[u.ae.i].flags & MEM_Ephem)==0 |
| 64698 | | - || (u.ae.pMem[u.ae.i].flags & (MEM_Str|MEM_Blob))==0 ); |
| 64699 | | - sqlite3VdbeMemNulTerminate(&u.ae.pMem[u.ae.i]); |
| 64700 | | - sqlite3VdbeMemStoreType(&u.ae.pMem[u.ae.i]); |
| 64701 | | - REGISTER_TRACE(pOp->p1+u.ae.i, &u.ae.pMem[u.ae.i]); |
| 64735 | + u.af.pMem = p->pResultSet = &aMem[pOp->p1]; |
| 64736 | + for(u.af.i=0; u.af.i<pOp->p2; u.af.i++){ |
| 64737 | + assert( memIsValid(&u.af.pMem[u.af.i]) ); |
| 64738 | + Deephemeralize(&u.af.pMem[u.af.i]); |
| 64739 | + assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0 |
| 64740 | + || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 ); |
| 64741 | + sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]); |
| 64742 | + sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]); |
| 64743 | + REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]); |
| 64702 | 64744 | } |
| 64703 | 64745 | if( db->mallocFailed ) goto no_mem; |
| 64704 | 64746 | |
| 64705 | 64747 | /* Return SQLITE_ROW |
| 64706 | 64748 | */ |
| | @@ -64720,13 +64762,13 @@ |
| 64720 | 64762 | ** It is illegal for P1 and P3 to be the same register. Sometimes, |
| 64721 | 64763 | ** if P3 is the same register as P2, the implementation is able |
| 64722 | 64764 | ** to avoid a memcpy(). |
| 64723 | 64765 | */ |
| 64724 | 64766 | case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ |
| 64725 | | -#if 0 /* local variables moved into u.af */ |
| 64767 | +#if 0 /* local variables moved into u.ag */ |
| 64726 | 64768 | i64 nByte; |
| 64727 | | -#endif /* local variables moved into u.af */ |
| 64769 | +#endif /* local variables moved into u.ag */ |
| 64728 | 64770 | |
| 64729 | 64771 | pIn1 = &aMem[pOp->p1]; |
| 64730 | 64772 | pIn2 = &aMem[pOp->p2]; |
| 64731 | 64773 | pOut = &aMem[pOp->p3]; |
| 64732 | 64774 | assert( pIn1!=pOut ); |
| | @@ -64735,26 +64777,26 @@ |
| 64735 | 64777 | break; |
| 64736 | 64778 | } |
| 64737 | 64779 | if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; |
| 64738 | 64780 | Stringify(pIn1, encoding); |
| 64739 | 64781 | Stringify(pIn2, encoding); |
| 64740 | | - u.af.nByte = pIn1->n + pIn2->n; |
| 64741 | | - if( u.af.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 64782 | + u.ag.nByte = pIn1->n + pIn2->n; |
| 64783 | + if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 64742 | 64784 | goto too_big; |
| 64743 | 64785 | } |
| 64744 | 64786 | MemSetTypeFlag(pOut, MEM_Str); |
| 64745 | | - if( sqlite3VdbeMemGrow(pOut, (int)u.af.nByte+2, pOut==pIn2) ){ |
| 64787 | + if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){ |
| 64746 | 64788 | goto no_mem; |
| 64747 | 64789 | } |
| 64748 | 64790 | if( pOut!=pIn2 ){ |
| 64749 | 64791 | memcpy(pOut->z, pIn2->z, pIn2->n); |
| 64750 | 64792 | } |
| 64751 | 64793 | memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); |
| 64752 | | - pOut->z[u.af.nByte] = 0; |
| 64753 | | - pOut->z[u.af.nByte+1] = 0; |
| 64794 | + pOut->z[u.ag.nByte] = 0; |
| 64795 | + pOut->z[u.ag.nByte+1] = 0; |
| 64754 | 64796 | pOut->flags |= MEM_Term; |
| 64755 | | - pOut->n = (int)u.af.nByte; |
| 64797 | + pOut->n = (int)u.ag.nByte; |
| 64756 | 64798 | pOut->enc = encoding; |
| 64757 | 64799 | UPDATE_MAX_BLOBSIZE(pOut); |
| 64758 | 64800 | break; |
| 64759 | 64801 | } |
| 64760 | 64802 | |
| | @@ -64794,80 +64836,80 @@ |
| 64794 | 64836 | case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ |
| 64795 | 64837 | case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ |
| 64796 | 64838 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ |
| 64797 | 64839 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ |
| 64798 | 64840 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
| 64799 | | -#if 0 /* local variables moved into u.ag */ |
| 64841 | +#if 0 /* local variables moved into u.ah */ |
| 64800 | 64842 | int flags; /* Combined MEM_* flags from both inputs */ |
| 64801 | 64843 | i64 iA; /* Integer value of left operand */ |
| 64802 | 64844 | i64 iB; /* Integer value of right operand */ |
| 64803 | 64845 | double rA; /* Real value of left operand */ |
| 64804 | 64846 | double rB; /* Real value of right operand */ |
| 64805 | | -#endif /* local variables moved into u.ag */ |
| 64847 | +#endif /* local variables moved into u.ah */ |
| 64806 | 64848 | |
| 64807 | 64849 | pIn1 = &aMem[pOp->p1]; |
| 64808 | 64850 | applyNumericAffinity(pIn1); |
| 64809 | 64851 | pIn2 = &aMem[pOp->p2]; |
| 64810 | 64852 | applyNumericAffinity(pIn2); |
| 64811 | 64853 | pOut = &aMem[pOp->p3]; |
| 64812 | | - u.ag.flags = pIn1->flags | pIn2->flags; |
| 64813 | | - if( (u.ag.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 64854 | + u.ah.flags = pIn1->flags | pIn2->flags; |
| 64855 | + if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 64814 | 64856 | if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ |
| 64815 | | - u.ag.iA = pIn1->u.i; |
| 64816 | | - u.ag.iB = pIn2->u.i; |
| 64857 | + u.ah.iA = pIn1->u.i; |
| 64858 | + u.ah.iB = pIn2->u.i; |
| 64817 | 64859 | switch( pOp->opcode ){ |
| 64818 | | - case OP_Add: if( sqlite3AddInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break; |
| 64819 | | - case OP_Subtract: if( sqlite3SubInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break; |
| 64820 | | - case OP_Multiply: if( sqlite3MulInt64(&u.ag.iB,u.ag.iA) ) goto fp_math; break; |
| 64860 | + case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break; |
| 64861 | + case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break; |
| 64862 | + case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break; |
| 64821 | 64863 | case OP_Divide: { |
| 64822 | | - if( u.ag.iA==0 ) goto arithmetic_result_is_null; |
| 64823 | | - if( u.ag.iA==-1 && u.ag.iB==SMALLEST_INT64 ) goto fp_math; |
| 64824 | | - u.ag.iB /= u.ag.iA; |
| 64864 | + if( u.ah.iA==0 ) goto arithmetic_result_is_null; |
| 64865 | + if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math; |
| 64866 | + u.ah.iB /= u.ah.iA; |
| 64825 | 64867 | break; |
| 64826 | 64868 | } |
| 64827 | 64869 | default: { |
| 64828 | | - if( u.ag.iA==0 ) goto arithmetic_result_is_null; |
| 64829 | | - if( u.ag.iA==-1 ) u.ag.iA = 1; |
| 64830 | | - u.ag.iB %= u.ag.iA; |
| 64870 | + if( u.ah.iA==0 ) goto arithmetic_result_is_null; |
| 64871 | + if( u.ah.iA==-1 ) u.ah.iA = 1; |
| 64872 | + u.ah.iB %= u.ah.iA; |
| 64831 | 64873 | break; |
| 64832 | 64874 | } |
| 64833 | 64875 | } |
| 64834 | | - pOut->u.i = u.ag.iB; |
| 64876 | + pOut->u.i = u.ah.iB; |
| 64835 | 64877 | MemSetTypeFlag(pOut, MEM_Int); |
| 64836 | 64878 | }else{ |
| 64837 | 64879 | fp_math: |
| 64838 | | - u.ag.rA = sqlite3VdbeRealValue(pIn1); |
| 64839 | | - u.ag.rB = sqlite3VdbeRealValue(pIn2); |
| 64880 | + u.ah.rA = sqlite3VdbeRealValue(pIn1); |
| 64881 | + u.ah.rB = sqlite3VdbeRealValue(pIn2); |
| 64840 | 64882 | switch( pOp->opcode ){ |
| 64841 | | - case OP_Add: u.ag.rB += u.ag.rA; break; |
| 64842 | | - case OP_Subtract: u.ag.rB -= u.ag.rA; break; |
| 64843 | | - case OP_Multiply: u.ag.rB *= u.ag.rA; break; |
| 64883 | + case OP_Add: u.ah.rB += u.ah.rA; break; |
| 64884 | + case OP_Subtract: u.ah.rB -= u.ah.rA; break; |
| 64885 | + case OP_Multiply: u.ah.rB *= u.ah.rA; break; |
| 64844 | 64886 | case OP_Divide: { |
| 64845 | 64887 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
| 64846 | | - if( u.ag.rA==(double)0 ) goto arithmetic_result_is_null; |
| 64847 | | - u.ag.rB /= u.ag.rA; |
| 64888 | + if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null; |
| 64889 | + u.ah.rB /= u.ah.rA; |
| 64848 | 64890 | break; |
| 64849 | 64891 | } |
| 64850 | 64892 | default: { |
| 64851 | | - u.ag.iA = (i64)u.ag.rA; |
| 64852 | | - u.ag.iB = (i64)u.ag.rB; |
| 64853 | | - if( u.ag.iA==0 ) goto arithmetic_result_is_null; |
| 64854 | | - if( u.ag.iA==-1 ) u.ag.iA = 1; |
| 64855 | | - u.ag.rB = (double)(u.ag.iB % u.ag.iA); |
| 64893 | + u.ah.iA = (i64)u.ah.rA; |
| 64894 | + u.ah.iB = (i64)u.ah.rB; |
| 64895 | + if( u.ah.iA==0 ) goto arithmetic_result_is_null; |
| 64896 | + if( u.ah.iA==-1 ) u.ah.iA = 1; |
| 64897 | + u.ah.rB = (double)(u.ah.iB % u.ah.iA); |
| 64856 | 64898 | break; |
| 64857 | 64899 | } |
| 64858 | 64900 | } |
| 64859 | 64901 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 64860 | | - pOut->u.i = u.ag.rB; |
| 64902 | + pOut->u.i = u.ah.rB; |
| 64861 | 64903 | MemSetTypeFlag(pOut, MEM_Int); |
| 64862 | 64904 | #else |
| 64863 | | - if( sqlite3IsNaN(u.ag.rB) ){ |
| 64905 | + if( sqlite3IsNaN(u.ah.rB) ){ |
| 64864 | 64906 | goto arithmetic_result_is_null; |
| 64865 | 64907 | } |
| 64866 | | - pOut->r = u.ag.rB; |
| 64908 | + pOut->r = u.ah.rB; |
| 64867 | 64909 | MemSetTypeFlag(pOut, MEM_Real); |
| 64868 | | - if( (u.ag.flags & MEM_Real)==0 ){ |
| 64910 | + if( (u.ah.flags & MEM_Real)==0 ){ |
| 64869 | 64911 | sqlite3VdbeIntegerAffinity(pOut); |
| 64870 | 64912 | } |
| 64871 | 64913 | #endif |
| 64872 | 64914 | } |
| 64873 | 64915 | break; |
| | @@ -64915,96 +64957,96 @@ |
| 64915 | 64957 | ** invocation of this opcode. |
| 64916 | 64958 | ** |
| 64917 | 64959 | ** See also: AggStep and AggFinal |
| 64918 | 64960 | */ |
| 64919 | 64961 | case OP_Function: { |
| 64920 | | -#if 0 /* local variables moved into u.ah */ |
| 64962 | +#if 0 /* local variables moved into u.ai */ |
| 64921 | 64963 | int i; |
| 64922 | 64964 | Mem *pArg; |
| 64923 | 64965 | sqlite3_context ctx; |
| 64924 | 64966 | sqlite3_value **apVal; |
| 64925 | 64967 | int n; |
| 64926 | | -#endif /* local variables moved into u.ah */ |
| 64968 | +#endif /* local variables moved into u.ai */ |
| 64927 | 64969 | |
| 64928 | | - u.ah.n = pOp->p5; |
| 64929 | | - u.ah.apVal = p->apArg; |
| 64930 | | - assert( u.ah.apVal || u.ah.n==0 ); |
| 64970 | + u.ai.n = pOp->p5; |
| 64971 | + u.ai.apVal = p->apArg; |
| 64972 | + assert( u.ai.apVal || u.ai.n==0 ); |
| 64931 | 64973 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 64932 | 64974 | pOut = &aMem[pOp->p3]; |
| 64933 | 64975 | memAboutToChange(p, pOut); |
| 64934 | 64976 | |
| 64935 | | - assert( u.ah.n==0 || (pOp->p2>0 && pOp->p2+u.ah.n<=p->nMem+1) ); |
| 64936 | | - assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ah.n ); |
| 64937 | | - u.ah.pArg = &aMem[pOp->p2]; |
| 64938 | | - for(u.ah.i=0; u.ah.i<u.ah.n; u.ah.i++, u.ah.pArg++){ |
| 64939 | | - assert( memIsValid(u.ah.pArg) ); |
| 64940 | | - u.ah.apVal[u.ah.i] = u.ah.pArg; |
| 64941 | | - Deephemeralize(u.ah.pArg); |
| 64942 | | - sqlite3VdbeMemStoreType(u.ah.pArg); |
| 64943 | | - REGISTER_TRACE(pOp->p2+u.ah.i, u.ah.pArg); |
| 64977 | + assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) ); |
| 64978 | + assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 64979 | + u.ai.pArg = &aMem[pOp->p2]; |
| 64980 | + for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 64981 | + assert( memIsValid(u.ai.pArg) ); |
| 64982 | + u.ai.apVal[u.ai.i] = u.ai.pArg; |
| 64983 | + Deephemeralize(u.ai.pArg); |
| 64984 | + sqlite3VdbeMemStoreType(u.ai.pArg); |
| 64985 | + REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg); |
| 64944 | 64986 | } |
| 64945 | 64987 | |
| 64946 | 64988 | assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC ); |
| 64947 | 64989 | if( pOp->p4type==P4_FUNCDEF ){ |
| 64948 | | - u.ah.ctx.pFunc = pOp->p4.pFunc; |
| 64949 | | - u.ah.ctx.pVdbeFunc = 0; |
| 64990 | + u.ai.ctx.pFunc = pOp->p4.pFunc; |
| 64991 | + u.ai.ctx.pVdbeFunc = 0; |
| 64950 | 64992 | }else{ |
| 64951 | | - u.ah.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; |
| 64952 | | - u.ah.ctx.pFunc = u.ah.ctx.pVdbeFunc->pFunc; |
| 64993 | + u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc; |
| 64994 | + u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc; |
| 64953 | 64995 | } |
| 64954 | 64996 | |
| 64955 | | - u.ah.ctx.s.flags = MEM_Null; |
| 64956 | | - u.ah.ctx.s.db = db; |
| 64957 | | - u.ah.ctx.s.xDel = 0; |
| 64958 | | - u.ah.ctx.s.zMalloc = 0; |
| 64997 | + u.ai.ctx.s.flags = MEM_Null; |
| 64998 | + u.ai.ctx.s.db = db; |
| 64999 | + u.ai.ctx.s.xDel = 0; |
| 65000 | + u.ai.ctx.s.zMalloc = 0; |
| 64959 | 65001 | |
| 64960 | 65002 | /* The output cell may already have a buffer allocated. Move |
| 64961 | | - ** the pointer to u.ah.ctx.s so in case the user-function can use |
| 65003 | + ** the pointer to u.ai.ctx.s so in case the user-function can use |
| 64962 | 65004 | ** the already allocated buffer instead of allocating a new one. |
| 64963 | 65005 | */ |
| 64964 | | - sqlite3VdbeMemMove(&u.ah.ctx.s, pOut); |
| 64965 | | - MemSetTypeFlag(&u.ah.ctx.s, MEM_Null); |
| 65006 | + sqlite3VdbeMemMove(&u.ai.ctx.s, pOut); |
| 65007 | + MemSetTypeFlag(&u.ai.ctx.s, MEM_Null); |
| 64966 | 65008 | |
| 64967 | | - u.ah.ctx.isError = 0; |
| 64968 | | - if( u.ah.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 65009 | + u.ai.ctx.isError = 0; |
| 65010 | + if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 64969 | 65011 | assert( pOp>aOp ); |
| 64970 | 65012 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 64971 | 65013 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 64972 | | - u.ah.ctx.pColl = pOp[-1].p4.pColl; |
| 65014 | + u.ai.ctx.pColl = pOp[-1].p4.pColl; |
| 64973 | 65015 | } |
| 64974 | 65016 | db->lastRowid = lastRowid; |
| 64975 | | - (*u.ah.ctx.pFunc->xFunc)(&u.ah.ctx, u.ah.n, u.ah.apVal); /* IMP: R-24505-23230 */ |
| 65017 | + (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */ |
| 64976 | 65018 | lastRowid = db->lastRowid; |
| 64977 | 65019 | |
| 64978 | 65020 | /* If any auxiliary data functions have been called by this user function, |
| 64979 | 65021 | ** immediately call the destructor for any non-static values. |
| 64980 | 65022 | */ |
| 64981 | | - if( u.ah.ctx.pVdbeFunc ){ |
| 64982 | | - sqlite3VdbeDeleteAuxData(u.ah.ctx.pVdbeFunc, pOp->p1); |
| 64983 | | - pOp->p4.pVdbeFunc = u.ah.ctx.pVdbeFunc; |
| 65023 | + if( u.ai.ctx.pVdbeFunc ){ |
| 65024 | + sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1); |
| 65025 | + pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc; |
| 64984 | 65026 | pOp->p4type = P4_VDBEFUNC; |
| 64985 | 65027 | } |
| 64986 | 65028 | |
| 64987 | 65029 | if( db->mallocFailed ){ |
| 64988 | 65030 | /* Even though a malloc() has failed, the implementation of the |
| 64989 | 65031 | ** user function may have called an sqlite3_result_XXX() function |
| 64990 | 65032 | ** to return a value. The following call releases any resources |
| 64991 | 65033 | ** associated with such a value. |
| 64992 | 65034 | */ |
| 64993 | | - sqlite3VdbeMemRelease(&u.ah.ctx.s); |
| 65035 | + sqlite3VdbeMemRelease(&u.ai.ctx.s); |
| 64994 | 65036 | goto no_mem; |
| 64995 | 65037 | } |
| 64996 | 65038 | |
| 64997 | 65039 | /* If the function returned an error, throw an exception */ |
| 64998 | | - if( u.ah.ctx.isError ){ |
| 64999 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ah.ctx.s)); |
| 65000 | | - rc = u.ah.ctx.isError; |
| 65040 | + if( u.ai.ctx.isError ){ |
| 65041 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s)); |
| 65042 | + rc = u.ai.ctx.isError; |
| 65001 | 65043 | } |
| 65002 | 65044 | |
| 65003 | 65045 | /* Copy the result of the function into register P3 */ |
| 65004 | | - sqlite3VdbeChangeEncoding(&u.ah.ctx.s, encoding); |
| 65005 | | - sqlite3VdbeMemMove(pOut, &u.ah.ctx.s); |
| 65046 | + sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding); |
| 65047 | + sqlite3VdbeMemMove(pOut, &u.ai.ctx.s); |
| 65006 | 65048 | if( sqlite3VdbeMemTooBig(pOut) ){ |
| 65007 | 65049 | goto too_big; |
| 65008 | 65050 | } |
| 65009 | 65051 | |
| 65010 | 65052 | #if 0 |
| | @@ -65048,56 +65090,56 @@ |
| 65048 | 65090 | */ |
| 65049 | 65091 | case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ |
| 65050 | 65092 | case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ |
| 65051 | 65093 | case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ |
| 65052 | 65094 | case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ |
| 65053 | | -#if 0 /* local variables moved into u.ai */ |
| 65095 | +#if 0 /* local variables moved into u.aj */ |
| 65054 | 65096 | i64 iA; |
| 65055 | 65097 | u64 uA; |
| 65056 | 65098 | i64 iB; |
| 65057 | 65099 | u8 op; |
| 65058 | | -#endif /* local variables moved into u.ai */ |
| 65100 | +#endif /* local variables moved into u.aj */ |
| 65059 | 65101 | |
| 65060 | 65102 | pIn1 = &aMem[pOp->p1]; |
| 65061 | 65103 | pIn2 = &aMem[pOp->p2]; |
| 65062 | 65104 | pOut = &aMem[pOp->p3]; |
| 65063 | 65105 | if( (pIn1->flags | pIn2->flags) & MEM_Null ){ |
| 65064 | 65106 | sqlite3VdbeMemSetNull(pOut); |
| 65065 | 65107 | break; |
| 65066 | 65108 | } |
| 65067 | | - u.ai.iA = sqlite3VdbeIntValue(pIn2); |
| 65068 | | - u.ai.iB = sqlite3VdbeIntValue(pIn1); |
| 65069 | | - u.ai.op = pOp->opcode; |
| 65070 | | - if( u.ai.op==OP_BitAnd ){ |
| 65071 | | - u.ai.iA &= u.ai.iB; |
| 65072 | | - }else if( u.ai.op==OP_BitOr ){ |
| 65073 | | - u.ai.iA |= u.ai.iB; |
| 65074 | | - }else if( u.ai.iB!=0 ){ |
| 65075 | | - assert( u.ai.op==OP_ShiftRight || u.ai.op==OP_ShiftLeft ); |
| 65109 | + u.aj.iA = sqlite3VdbeIntValue(pIn2); |
| 65110 | + u.aj.iB = sqlite3VdbeIntValue(pIn1); |
| 65111 | + u.aj.op = pOp->opcode; |
| 65112 | + if( u.aj.op==OP_BitAnd ){ |
| 65113 | + u.aj.iA &= u.aj.iB; |
| 65114 | + }else if( u.aj.op==OP_BitOr ){ |
| 65115 | + u.aj.iA |= u.aj.iB; |
| 65116 | + }else if( u.aj.iB!=0 ){ |
| 65117 | + assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft ); |
| 65076 | 65118 | |
| 65077 | 65119 | /* If shifting by a negative amount, shift in the other direction */ |
| 65078 | | - if( u.ai.iB<0 ){ |
| 65120 | + if( u.aj.iB<0 ){ |
| 65079 | 65121 | assert( OP_ShiftRight==OP_ShiftLeft+1 ); |
| 65080 | | - u.ai.op = 2*OP_ShiftLeft + 1 - u.ai.op; |
| 65081 | | - u.ai.iB = u.ai.iB>(-64) ? -u.ai.iB : 64; |
| 65122 | + u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op; |
| 65123 | + u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64; |
| 65082 | 65124 | } |
| 65083 | 65125 | |
| 65084 | | - if( u.ai.iB>=64 ){ |
| 65085 | | - u.ai.iA = (u.ai.iA>=0 || u.ai.op==OP_ShiftLeft) ? 0 : -1; |
| 65086 | | - }else{ |
| 65087 | | - memcpy(&u.ai.uA, &u.ai.iA, sizeof(u.ai.uA)); |
| 65088 | | - if( u.ai.op==OP_ShiftLeft ){ |
| 65089 | | - u.ai.uA <<= u.ai.iB; |
| 65090 | | - }else{ |
| 65091 | | - u.ai.uA >>= u.ai.iB; |
| 65126 | + if( u.aj.iB>=64 ){ |
| 65127 | + u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1; |
| 65128 | + }else{ |
| 65129 | + memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA)); |
| 65130 | + if( u.aj.op==OP_ShiftLeft ){ |
| 65131 | + u.aj.uA <<= u.aj.iB; |
| 65132 | + }else{ |
| 65133 | + u.aj.uA >>= u.aj.iB; |
| 65092 | 65134 | /* Sign-extend on a right shift of a negative number */ |
| 65093 | | - if( u.ai.iA<0 ) u.ai.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ai.iB); |
| 65135 | + if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB); |
| 65094 | 65136 | } |
| 65095 | | - memcpy(&u.ai.iA, &u.ai.uA, sizeof(u.ai.iA)); |
| 65137 | + memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA)); |
| 65096 | 65138 | } |
| 65097 | 65139 | } |
| 65098 | | - pOut->u.i = u.ai.iA; |
| 65140 | + pOut->u.i = u.aj.iA; |
| 65099 | 65141 | MemSetTypeFlag(pOut, MEM_Int); |
| 65100 | 65142 | break; |
| 65101 | 65143 | } |
| 65102 | 65144 | |
| 65103 | 65145 | /* Opcode: AddImm P1 P2 * * * |
| | @@ -65285,10 +65327,14 @@ |
| 65285 | 65327 | ** are of different types, then numbers are considered less than |
| 65286 | 65328 | ** strings and strings are considered less than blobs. |
| 65287 | 65329 | ** |
| 65288 | 65330 | ** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead, |
| 65289 | 65331 | ** store a boolean result (either 0, or 1, or NULL) in register P2. |
| 65332 | +** |
| 65333 | +** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered |
| 65334 | +** equal to one another, provided that they do not have their MEM_Cleared |
| 65335 | +** bit set. |
| 65290 | 65336 | */ |
| 65291 | 65337 | /* Opcode: Ne P1 P2 P3 P4 P5 |
| 65292 | 65338 | ** |
| 65293 | 65339 | ** This works just like the Lt opcode except that the jump is taken if |
| 65294 | 65340 | ** the operands in registers P1 and P3 are not equal. See the Lt opcode for |
| | @@ -65334,30 +65380,38 @@ |
| 65334 | 65380 | case OP_Ne: /* same as TK_NE, jump, in1, in3 */ |
| 65335 | 65381 | case OP_Lt: /* same as TK_LT, jump, in1, in3 */ |
| 65336 | 65382 | case OP_Le: /* same as TK_LE, jump, in1, in3 */ |
| 65337 | 65383 | case OP_Gt: /* same as TK_GT, jump, in1, in3 */ |
| 65338 | 65384 | case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ |
| 65339 | | -#if 0 /* local variables moved into u.aj */ |
| 65385 | +#if 0 /* local variables moved into u.ak */ |
| 65340 | 65386 | int res; /* Result of the comparison of pIn1 against pIn3 */ |
| 65341 | 65387 | char affinity; /* Affinity to use for comparison */ |
| 65342 | 65388 | u16 flags1; /* Copy of initial value of pIn1->flags */ |
| 65343 | 65389 | u16 flags3; /* Copy of initial value of pIn3->flags */ |
| 65344 | | -#endif /* local variables moved into u.aj */ |
| 65390 | +#endif /* local variables moved into u.ak */ |
| 65345 | 65391 | |
| 65346 | 65392 | pIn1 = &aMem[pOp->p1]; |
| 65347 | 65393 | pIn3 = &aMem[pOp->p3]; |
| 65348 | | - u.aj.flags1 = pIn1->flags; |
| 65349 | | - u.aj.flags3 = pIn3->flags; |
| 65350 | | - if( (u.aj.flags1 | u.aj.flags3)&MEM_Null ){ |
| 65394 | + u.ak.flags1 = pIn1->flags; |
| 65395 | + u.ak.flags3 = pIn3->flags; |
| 65396 | + if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){ |
| 65351 | 65397 | /* One or both operands are NULL */ |
| 65352 | 65398 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 65353 | 65399 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 65354 | 65400 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 65355 | 65401 | ** or not both operands are null. |
| 65356 | 65402 | */ |
| 65357 | 65403 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 65358 | | - u.aj.res = (u.aj.flags1 & u.aj.flags3 & MEM_Null)==0; |
| 65404 | + assert( (u.ak.flags1 & MEM_Cleared)==0 ); |
| 65405 | + if( (u.ak.flags1&MEM_Null)!=0 |
| 65406 | + && (u.ak.flags3&MEM_Null)!=0 |
| 65407 | + && (u.ak.flags3&MEM_Cleared)==0 |
| 65408 | + ){ |
| 65409 | + u.ak.res = 0; /* Results are equal */ |
| 65410 | + }else{ |
| 65411 | + u.ak.res = 1; /* Results are not equal */ |
| 65412 | + } |
| 65359 | 65413 | }else{ |
| 65360 | 65414 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 65361 | 65415 | ** then the result is always NULL. |
| 65362 | 65416 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 65363 | 65417 | */ |
| | @@ -65370,44 +65424,44 @@ |
| 65370 | 65424 | } |
| 65371 | 65425 | break; |
| 65372 | 65426 | } |
| 65373 | 65427 | }else{ |
| 65374 | 65428 | /* Neither operand is NULL. Do a comparison. */ |
| 65375 | | - u.aj.affinity = pOp->p5 & SQLITE_AFF_MASK; |
| 65376 | | - if( u.aj.affinity ){ |
| 65377 | | - applyAffinity(pIn1, u.aj.affinity, encoding); |
| 65378 | | - applyAffinity(pIn3, u.aj.affinity, encoding); |
| 65429 | + u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK; |
| 65430 | + if( u.ak.affinity ){ |
| 65431 | + applyAffinity(pIn1, u.ak.affinity, encoding); |
| 65432 | + applyAffinity(pIn3, u.ak.affinity, encoding); |
| 65379 | 65433 | if( db->mallocFailed ) goto no_mem; |
| 65380 | 65434 | } |
| 65381 | 65435 | |
| 65382 | 65436 | assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); |
| 65383 | 65437 | ExpandBlob(pIn1); |
| 65384 | 65438 | ExpandBlob(pIn3); |
| 65385 | | - u.aj.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); |
| 65439 | + u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); |
| 65386 | 65440 | } |
| 65387 | 65441 | switch( pOp->opcode ){ |
| 65388 | | - case OP_Eq: u.aj.res = u.aj.res==0; break; |
| 65389 | | - case OP_Ne: u.aj.res = u.aj.res!=0; break; |
| 65390 | | - case OP_Lt: u.aj.res = u.aj.res<0; break; |
| 65391 | | - case OP_Le: u.aj.res = u.aj.res<=0; break; |
| 65392 | | - case OP_Gt: u.aj.res = u.aj.res>0; break; |
| 65393 | | - default: u.aj.res = u.aj.res>=0; break; |
| 65442 | + case OP_Eq: u.ak.res = u.ak.res==0; break; |
| 65443 | + case OP_Ne: u.ak.res = u.ak.res!=0; break; |
| 65444 | + case OP_Lt: u.ak.res = u.ak.res<0; break; |
| 65445 | + case OP_Le: u.ak.res = u.ak.res<=0; break; |
| 65446 | + case OP_Gt: u.ak.res = u.ak.res>0; break; |
| 65447 | + default: u.ak.res = u.ak.res>=0; break; |
| 65394 | 65448 | } |
| 65395 | 65449 | |
| 65396 | 65450 | if( pOp->p5 & SQLITE_STOREP2 ){ |
| 65397 | 65451 | pOut = &aMem[pOp->p2]; |
| 65398 | 65452 | memAboutToChange(p, pOut); |
| 65399 | 65453 | MemSetTypeFlag(pOut, MEM_Int); |
| 65400 | | - pOut->u.i = u.aj.res; |
| 65454 | + pOut->u.i = u.ak.res; |
| 65401 | 65455 | REGISTER_TRACE(pOp->p2, pOut); |
| 65402 | | - }else if( u.aj.res ){ |
| 65456 | + }else if( u.ak.res ){ |
| 65403 | 65457 | pc = pOp->p2-1; |
| 65404 | 65458 | } |
| 65405 | 65459 | |
| 65406 | 65460 | /* Undo any changes made by applyAffinity() to the input registers. */ |
| 65407 | | - pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.aj.flags1&MEM_TypeMask); |
| 65408 | | - pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.aj.flags3&MEM_TypeMask); |
| 65461 | + pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask); |
| 65462 | + pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask); |
| 65409 | 65463 | break; |
| 65410 | 65464 | } |
| 65411 | 65465 | |
| 65412 | 65466 | /* Opcode: Permutation * * * P4 * |
| 65413 | 65467 | ** |
| | @@ -65438,50 +65492,50 @@ |
| 65438 | 65492 | ** The comparison is a sort comparison, so NULLs compare equal, |
| 65439 | 65493 | ** NULLs are less than numbers, numbers are less than strings, |
| 65440 | 65494 | ** and strings are less than blobs. |
| 65441 | 65495 | */ |
| 65442 | 65496 | case OP_Compare: { |
| 65443 | | -#if 0 /* local variables moved into u.ak */ |
| 65497 | +#if 0 /* local variables moved into u.al */ |
| 65444 | 65498 | int n; |
| 65445 | 65499 | int i; |
| 65446 | 65500 | int p1; |
| 65447 | 65501 | int p2; |
| 65448 | 65502 | const KeyInfo *pKeyInfo; |
| 65449 | 65503 | int idx; |
| 65450 | 65504 | CollSeq *pColl; /* Collating sequence to use on this term */ |
| 65451 | 65505 | int bRev; /* True for DESCENDING sort order */ |
| 65452 | | -#endif /* local variables moved into u.ak */ |
| 65453 | | - |
| 65454 | | - u.ak.n = pOp->p3; |
| 65455 | | - u.ak.pKeyInfo = pOp->p4.pKeyInfo; |
| 65456 | | - assert( u.ak.n>0 ); |
| 65457 | | - assert( u.ak.pKeyInfo!=0 ); |
| 65458 | | - u.ak.p1 = pOp->p1; |
| 65459 | | - u.ak.p2 = pOp->p2; |
| 65506 | +#endif /* local variables moved into u.al */ |
| 65507 | + |
| 65508 | + u.al.n = pOp->p3; |
| 65509 | + u.al.pKeyInfo = pOp->p4.pKeyInfo; |
| 65510 | + assert( u.al.n>0 ); |
| 65511 | + assert( u.al.pKeyInfo!=0 ); |
| 65512 | + u.al.p1 = pOp->p1; |
| 65513 | + u.al.p2 = pOp->p2; |
| 65460 | 65514 | #if SQLITE_DEBUG |
| 65461 | 65515 | if( aPermute ){ |
| 65462 | 65516 | int k, mx = 0; |
| 65463 | | - for(k=0; k<u.ak.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 65464 | | - assert( u.ak.p1>0 && u.ak.p1+mx<=p->nMem+1 ); |
| 65465 | | - assert( u.ak.p2>0 && u.ak.p2+mx<=p->nMem+1 ); |
| 65517 | + for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 65518 | + assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 ); |
| 65519 | + assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 ); |
| 65466 | 65520 | }else{ |
| 65467 | | - assert( u.ak.p1>0 && u.ak.p1+u.ak.n<=p->nMem+1 ); |
| 65468 | | - assert( u.ak.p2>0 && u.ak.p2+u.ak.n<=p->nMem+1 ); |
| 65521 | + assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 ); |
| 65522 | + assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 ); |
| 65469 | 65523 | } |
| 65470 | 65524 | #endif /* SQLITE_DEBUG */ |
| 65471 | | - for(u.ak.i=0; u.ak.i<u.ak.n; u.ak.i++){ |
| 65472 | | - u.ak.idx = aPermute ? aPermute[u.ak.i] : u.ak.i; |
| 65473 | | - assert( memIsValid(&aMem[u.ak.p1+u.ak.idx]) ); |
| 65474 | | - assert( memIsValid(&aMem[u.ak.p2+u.ak.idx]) ); |
| 65475 | | - REGISTER_TRACE(u.ak.p1+u.ak.idx, &aMem[u.ak.p1+u.ak.idx]); |
| 65476 | | - REGISTER_TRACE(u.ak.p2+u.ak.idx, &aMem[u.ak.p2+u.ak.idx]); |
| 65477 | | - assert( u.ak.i<u.ak.pKeyInfo->nField ); |
| 65478 | | - u.ak.pColl = u.ak.pKeyInfo->aColl[u.ak.i]; |
| 65479 | | - u.ak.bRev = u.ak.pKeyInfo->aSortOrder[u.ak.i]; |
| 65480 | | - iCompare = sqlite3MemCompare(&aMem[u.ak.p1+u.ak.idx], &aMem[u.ak.p2+u.ak.idx], u.ak.pColl); |
| 65525 | + for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 65526 | + u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 65527 | + assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| 65528 | + assert( memIsValid(&aMem[u.al.p2+u.al.idx]) ); |
| 65529 | + REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]); |
| 65530 | + REGISTER_TRACE(u.al.p2+u.al.idx, &aMem[u.al.p2+u.al.idx]); |
| 65531 | + assert( u.al.i<u.al.pKeyInfo->nField ); |
| 65532 | + u.al.pColl = u.al.pKeyInfo->aColl[u.al.i]; |
| 65533 | + u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i]; |
| 65534 | + iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl); |
| 65481 | 65535 | if( iCompare ){ |
| 65482 | | - if( u.ak.bRev ) iCompare = -iCompare; |
| 65536 | + if( u.al.bRev ) iCompare = -iCompare; |
| 65483 | 65537 | break; |
| 65484 | 65538 | } |
| 65485 | 65539 | } |
| 65486 | 65540 | aPermute = 0; |
| 65487 | 65541 | break; |
| | @@ -65522,39 +65576,39 @@ |
| 65522 | 65576 | ** even if the other input is NULL. A NULL and false or two NULLs |
| 65523 | 65577 | ** give a NULL output. |
| 65524 | 65578 | */ |
| 65525 | 65579 | case OP_And: /* same as TK_AND, in1, in2, out3 */ |
| 65526 | 65580 | case OP_Or: { /* same as TK_OR, in1, in2, out3 */ |
| 65527 | | -#if 0 /* local variables moved into u.al */ |
| 65581 | +#if 0 /* local variables moved into u.am */ |
| 65528 | 65582 | int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 65529 | 65583 | int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 65530 | | -#endif /* local variables moved into u.al */ |
| 65584 | +#endif /* local variables moved into u.am */ |
| 65531 | 65585 | |
| 65532 | 65586 | pIn1 = &aMem[pOp->p1]; |
| 65533 | 65587 | if( pIn1->flags & MEM_Null ){ |
| 65534 | | - u.al.v1 = 2; |
| 65588 | + u.am.v1 = 2; |
| 65535 | 65589 | }else{ |
| 65536 | | - u.al.v1 = sqlite3VdbeIntValue(pIn1)!=0; |
| 65590 | + u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0; |
| 65537 | 65591 | } |
| 65538 | 65592 | pIn2 = &aMem[pOp->p2]; |
| 65539 | 65593 | if( pIn2->flags & MEM_Null ){ |
| 65540 | | - u.al.v2 = 2; |
| 65594 | + u.am.v2 = 2; |
| 65541 | 65595 | }else{ |
| 65542 | | - u.al.v2 = sqlite3VdbeIntValue(pIn2)!=0; |
| 65596 | + u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0; |
| 65543 | 65597 | } |
| 65544 | 65598 | if( pOp->opcode==OP_And ){ |
| 65545 | 65599 | static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; |
| 65546 | | - u.al.v1 = and_logic[u.al.v1*3+u.al.v2]; |
| 65600 | + u.am.v1 = and_logic[u.am.v1*3+u.am.v2]; |
| 65547 | 65601 | }else{ |
| 65548 | 65602 | static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; |
| 65549 | | - u.al.v1 = or_logic[u.al.v1*3+u.al.v2]; |
| 65603 | + u.am.v1 = or_logic[u.am.v1*3+u.am.v2]; |
| 65550 | 65604 | } |
| 65551 | 65605 | pOut = &aMem[pOp->p3]; |
| 65552 | | - if( u.al.v1==2 ){ |
| 65606 | + if( u.am.v1==2 ){ |
| 65553 | 65607 | MemSetTypeFlag(pOut, MEM_Null); |
| 65554 | 65608 | }else{ |
| 65555 | | - pOut->u.i = u.al.v1; |
| 65609 | + pOut->u.i = u.am.v1; |
| 65556 | 65610 | MemSetTypeFlag(pOut, MEM_Int); |
| 65557 | 65611 | } |
| 65558 | 65612 | break; |
| 65559 | 65613 | } |
| 65560 | 65614 | |
| | @@ -65621,25 +65675,25 @@ |
| 65621 | 65675 | ** is considered false if it has a numeric value of zero. If the value |
| 65622 | 65676 | ** in P1 is NULL then take the jump if P3 is zero. |
| 65623 | 65677 | */ |
| 65624 | 65678 | case OP_If: /* jump, in1 */ |
| 65625 | 65679 | case OP_IfNot: { /* jump, in1 */ |
| 65626 | | -#if 0 /* local variables moved into u.am */ |
| 65680 | +#if 0 /* local variables moved into u.an */ |
| 65627 | 65681 | int c; |
| 65628 | | -#endif /* local variables moved into u.am */ |
| 65682 | +#endif /* local variables moved into u.an */ |
| 65629 | 65683 | pIn1 = &aMem[pOp->p1]; |
| 65630 | 65684 | if( pIn1->flags & MEM_Null ){ |
| 65631 | | - u.am.c = pOp->p3; |
| 65685 | + u.an.c = pOp->p3; |
| 65632 | 65686 | }else{ |
| 65633 | 65687 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 65634 | | - u.am.c = sqlite3VdbeIntValue(pIn1)!=0; |
| 65688 | + u.an.c = sqlite3VdbeIntValue(pIn1)!=0; |
| 65635 | 65689 | #else |
| 65636 | | - u.am.c = sqlite3VdbeRealValue(pIn1)!=0.0; |
| 65690 | + u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0; |
| 65637 | 65691 | #endif |
| 65638 | | - if( pOp->opcode==OP_IfNot ) u.am.c = !u.am.c; |
| 65692 | + if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c; |
| 65639 | 65693 | } |
| 65640 | | - if( u.am.c ){ |
| 65694 | + if( u.an.c ){ |
| 65641 | 65695 | pc = pOp->p2-1; |
| 65642 | 65696 | } |
| 65643 | 65697 | break; |
| 65644 | 65698 | } |
| 65645 | 65699 | |
| | @@ -65690,11 +65744,11 @@ |
| 65690 | 65744 | ** the result is guaranteed to only be used as the argument of a length() |
| 65691 | 65745 | ** or typeof() function, respectively. The loading of large blobs can be |
| 65692 | 65746 | ** skipped for length() and all content loading can be skipped for typeof(). |
| 65693 | 65747 | */ |
| 65694 | 65748 | case OP_Column: { |
| 65695 | | -#if 0 /* local variables moved into u.an */ |
| 65749 | +#if 0 /* local variables moved into u.ao */ |
| 65696 | 65750 | u32 payloadSize; /* Number of bytes in the record */ |
| 65697 | 65751 | i64 payloadSize64; /* Number of bytes in the record */ |
| 65698 | 65752 | int p1; /* P1 value of the opcode */ |
| 65699 | 65753 | int p2; /* column number to retrieve */ |
| 65700 | 65754 | VdbeCursor *pC; /* The VDBE cursor */ |
| | @@ -65714,130 +65768,130 @@ |
| 65714 | 65768 | u32 szField; /* Number of bytes in the content of a field */ |
| 65715 | 65769 | int szHdr; /* Size of the header size field at start of record */ |
| 65716 | 65770 | int avail; /* Number of bytes of available data */ |
| 65717 | 65771 | u32 t; /* A type code from the record header */ |
| 65718 | 65772 | Mem *pReg; /* PseudoTable input register */ |
| 65719 | | -#endif /* local variables moved into u.an */ |
| 65773 | +#endif /* local variables moved into u.ao */ |
| 65720 | 65774 | |
| 65721 | 65775 | |
| 65722 | | - u.an.p1 = pOp->p1; |
| 65723 | | - u.an.p2 = pOp->p2; |
| 65724 | | - u.an.pC = 0; |
| 65725 | | - memset(&u.an.sMem, 0, sizeof(u.an.sMem)); |
| 65726 | | - assert( u.an.p1<p->nCursor ); |
| 65776 | + u.ao.p1 = pOp->p1; |
| 65777 | + u.ao.p2 = pOp->p2; |
| 65778 | + u.ao.pC = 0; |
| 65779 | + memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 65780 | + assert( u.ao.p1<p->nCursor ); |
| 65727 | 65781 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 65728 | | - u.an.pDest = &aMem[pOp->p3]; |
| 65729 | | - memAboutToChange(p, u.an.pDest); |
| 65730 | | - u.an.zRec = 0; |
| 65782 | + u.ao.pDest = &aMem[pOp->p3]; |
| 65783 | + memAboutToChange(p, u.ao.pDest); |
| 65784 | + u.ao.zRec = 0; |
| 65731 | 65785 | |
| 65732 | | - /* This block sets the variable u.an.payloadSize to be the total number of |
| 65786 | + /* This block sets the variable u.ao.payloadSize to be the total number of |
| 65733 | 65787 | ** bytes in the record. |
| 65734 | 65788 | ** |
| 65735 | | - ** u.an.zRec is set to be the complete text of the record if it is available. |
| 65789 | + ** u.ao.zRec is set to be the complete text of the record if it is available. |
| 65736 | 65790 | ** The complete record text is always available for pseudo-tables |
| 65737 | 65791 | ** If the record is stored in a cursor, the complete record text |
| 65738 | | - ** might be available in the u.an.pC->aRow cache. Or it might not be. |
| 65739 | | - ** If the data is unavailable, u.an.zRec is set to NULL. |
| 65792 | + ** might be available in the u.ao.pC->aRow cache. Or it might not be. |
| 65793 | + ** If the data is unavailable, u.ao.zRec is set to NULL. |
| 65740 | 65794 | ** |
| 65741 | 65795 | ** We also compute the number of columns in the record. For cursors, |
| 65742 | 65796 | ** the number of columns is stored in the VdbeCursor.nField element. |
| 65743 | 65797 | */ |
| 65744 | | - u.an.pC = p->apCsr[u.an.p1]; |
| 65745 | | - assert( u.an.pC!=0 ); |
| 65798 | + u.ao.pC = p->apCsr[u.ao.p1]; |
| 65799 | + assert( u.ao.pC!=0 ); |
| 65746 | 65800 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 65747 | | - assert( u.an.pC->pVtabCursor==0 ); |
| 65801 | + assert( u.ao.pC->pVtabCursor==0 ); |
| 65748 | 65802 | #endif |
| 65749 | | - u.an.pCrsr = u.an.pC->pCursor; |
| 65750 | | - if( u.an.pCrsr!=0 ){ |
| 65803 | + u.ao.pCrsr = u.ao.pC->pCursor; |
| 65804 | + if( u.ao.pCrsr!=0 ){ |
| 65751 | 65805 | /* The record is stored in a B-Tree */ |
| 65752 | | - rc = sqlite3VdbeCursorMoveto(u.an.pC); |
| 65806 | + rc = sqlite3VdbeCursorMoveto(u.ao.pC); |
| 65753 | 65807 | if( rc ) goto abort_due_to_error; |
| 65754 | | - if( u.an.pC->nullRow ){ |
| 65755 | | - u.an.payloadSize = 0; |
| 65756 | | - }else if( u.an.pC->cacheStatus==p->cacheCtr ){ |
| 65757 | | - u.an.payloadSize = u.an.pC->payloadSize; |
| 65758 | | - u.an.zRec = (char*)u.an.pC->aRow; |
| 65759 | | - }else if( u.an.pC->isIndex ){ |
| 65760 | | - assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) ); |
| 65761 | | - VVA_ONLY(rc =) sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64); |
| 65808 | + if( u.ao.pC->nullRow ){ |
| 65809 | + u.ao.payloadSize = 0; |
| 65810 | + }else if( u.ao.pC->cacheStatus==p->cacheCtr ){ |
| 65811 | + u.ao.payloadSize = u.ao.pC->payloadSize; |
| 65812 | + u.ao.zRec = (char*)u.ao.pC->aRow; |
| 65813 | + }else if( u.ao.pC->isIndex ){ |
| 65814 | + assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) ); |
| 65815 | + VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64); |
| 65762 | 65816 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 65763 | 65817 | /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the |
| 65764 | | - ** payload size, so it is impossible for u.an.payloadSize64 to be |
| 65818 | + ** payload size, so it is impossible for u.ao.payloadSize64 to be |
| 65765 | 65819 | ** larger than 32 bits. */ |
| 65766 | | - assert( (u.an.payloadSize64 & SQLITE_MAX_U32)==(u64)u.an.payloadSize64 ); |
| 65767 | | - u.an.payloadSize = (u32)u.an.payloadSize64; |
| 65820 | + assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 ); |
| 65821 | + u.ao.payloadSize = (u32)u.ao.payloadSize64; |
| 65768 | 65822 | }else{ |
| 65769 | | - assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) ); |
| 65770 | | - VVA_ONLY(rc =) sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize); |
| 65823 | + assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) ); |
| 65824 | + VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize); |
| 65771 | 65825 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 65772 | 65826 | } |
| 65773 | | - }else if( ALWAYS(u.an.pC->pseudoTableReg>0) ){ |
| 65774 | | - u.an.pReg = &aMem[u.an.pC->pseudoTableReg]; |
| 65775 | | - assert( u.an.pReg->flags & MEM_Blob ); |
| 65776 | | - assert( memIsValid(u.an.pReg) ); |
| 65777 | | - u.an.payloadSize = u.an.pReg->n; |
| 65778 | | - u.an.zRec = u.an.pReg->z; |
| 65779 | | - u.an.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; |
| 65780 | | - assert( u.an.payloadSize==0 || u.an.zRec!=0 ); |
| 65827 | + }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){ |
| 65828 | + u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg]; |
| 65829 | + assert( u.ao.pReg->flags & MEM_Blob ); |
| 65830 | + assert( memIsValid(u.ao.pReg) ); |
| 65831 | + u.ao.payloadSize = u.ao.pReg->n; |
| 65832 | + u.ao.zRec = u.ao.pReg->z; |
| 65833 | + u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; |
| 65834 | + assert( u.ao.payloadSize==0 || u.ao.zRec!=0 ); |
| 65781 | 65835 | }else{ |
| 65782 | 65836 | /* Consider the row to be NULL */ |
| 65783 | | - u.an.payloadSize = 0; |
| 65837 | + u.ao.payloadSize = 0; |
| 65784 | 65838 | } |
| 65785 | 65839 | |
| 65786 | | - /* If u.an.payloadSize is 0, then just store a NULL. This can happen because of |
| 65840 | + /* If u.ao.payloadSize is 0, then just store a NULL. This can happen because of |
| 65787 | 65841 | ** nullRow or because of a corrupt database. */ |
| 65788 | | - if( u.an.payloadSize==0 ){ |
| 65789 | | - MemSetTypeFlag(u.an.pDest, MEM_Null); |
| 65842 | + if( u.ao.payloadSize==0 ){ |
| 65843 | + MemSetTypeFlag(u.ao.pDest, MEM_Null); |
| 65790 | 65844 | goto op_column_out; |
| 65791 | 65845 | } |
| 65792 | 65846 | assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); |
| 65793 | | - if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 65847 | + if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 65794 | 65848 | goto too_big; |
| 65795 | 65849 | } |
| 65796 | 65850 | |
| 65797 | | - u.an.nField = u.an.pC->nField; |
| 65798 | | - assert( u.an.p2<u.an.nField ); |
| 65851 | + u.ao.nField = u.ao.pC->nField; |
| 65852 | + assert( u.ao.p2<u.ao.nField ); |
| 65799 | 65853 | |
| 65800 | 65854 | /* Read and parse the table header. Store the results of the parse |
| 65801 | 65855 | ** into the record header cache fields of the cursor. |
| 65802 | 65856 | */ |
| 65803 | | - u.an.aType = u.an.pC->aType; |
| 65804 | | - if( u.an.pC->cacheStatus==p->cacheCtr ){ |
| 65805 | | - u.an.aOffset = u.an.pC->aOffset; |
| 65857 | + u.ao.aType = u.ao.pC->aType; |
| 65858 | + if( u.ao.pC->cacheStatus==p->cacheCtr ){ |
| 65859 | + u.ao.aOffset = u.ao.pC->aOffset; |
| 65806 | 65860 | }else{ |
| 65807 | | - assert(u.an.aType); |
| 65808 | | - u.an.avail = 0; |
| 65809 | | - u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField]; |
| 65810 | | - u.an.pC->payloadSize = u.an.payloadSize; |
| 65811 | | - u.an.pC->cacheStatus = p->cacheCtr; |
| 65861 | + assert(u.ao.aType); |
| 65862 | + u.ao.avail = 0; |
| 65863 | + u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField]; |
| 65864 | + u.ao.pC->payloadSize = u.ao.payloadSize; |
| 65865 | + u.ao.pC->cacheStatus = p->cacheCtr; |
| 65812 | 65866 | |
| 65813 | 65867 | /* Figure out how many bytes are in the header */ |
| 65814 | | - if( u.an.zRec ){ |
| 65815 | | - u.an.zData = u.an.zRec; |
| 65868 | + if( u.ao.zRec ){ |
| 65869 | + u.ao.zData = u.ao.zRec; |
| 65816 | 65870 | }else{ |
| 65817 | | - if( u.an.pC->isIndex ){ |
| 65818 | | - u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail); |
| 65871 | + if( u.ao.pC->isIndex ){ |
| 65872 | + u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail); |
| 65819 | 65873 | }else{ |
| 65820 | | - u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail); |
| 65874 | + u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail); |
| 65821 | 65875 | } |
| 65822 | 65876 | /* If KeyFetch()/DataFetch() managed to get the entire payload, |
| 65823 | | - ** save the payload in the u.an.pC->aRow cache. That will save us from |
| 65877 | + ** save the payload in the u.ao.pC->aRow cache. That will save us from |
| 65824 | 65878 | ** having to make additional calls to fetch the content portion of |
| 65825 | 65879 | ** the record. |
| 65826 | 65880 | */ |
| 65827 | | - assert( u.an.avail>=0 ); |
| 65828 | | - if( u.an.payloadSize <= (u32)u.an.avail ){ |
| 65829 | | - u.an.zRec = u.an.zData; |
| 65830 | | - u.an.pC->aRow = (u8*)u.an.zData; |
| 65881 | + assert( u.ao.avail>=0 ); |
| 65882 | + if( u.ao.payloadSize <= (u32)u.ao.avail ){ |
| 65883 | + u.ao.zRec = u.ao.zData; |
| 65884 | + u.ao.pC->aRow = (u8*)u.ao.zData; |
| 65831 | 65885 | }else{ |
| 65832 | | - u.an.pC->aRow = 0; |
| 65886 | + u.ao.pC->aRow = 0; |
| 65833 | 65887 | } |
| 65834 | 65888 | } |
| 65835 | 65889 | /* The following assert is true in all cases except when |
| 65836 | 65890 | ** the database file has been corrupted externally. |
| 65837 | | - ** assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */ |
| 65838 | | - u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset); |
| 65891 | + ** assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */ |
| 65892 | + u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset); |
| 65839 | 65893 | |
| 65840 | 65894 | /* Make sure a corrupt database has not given us an oversize header. |
| 65841 | 65895 | ** Do this now to avoid an oversize memory allocation. |
| 65842 | 65896 | ** |
| 65843 | 65897 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
| | @@ -65844,161 +65898,161 @@ |
| 65844 | 65898 | ** types use so much data space that there can only be 4096 and 32 of |
| 65845 | 65899 | ** them, respectively. So the maximum header length results from a |
| 65846 | 65900 | ** 3-byte type for each of the maximum of 32768 columns plus three |
| 65847 | 65901 | ** extra bytes for the header length itself. 32768*3 + 3 = 98307. |
| 65848 | 65902 | */ |
| 65849 | | - if( u.an.offset > 98307 ){ |
| 65903 | + if( u.ao.offset > 98307 ){ |
| 65850 | 65904 | rc = SQLITE_CORRUPT_BKPT; |
| 65851 | 65905 | goto op_column_out; |
| 65852 | 65906 | } |
| 65853 | 65907 | |
| 65854 | | - /* Compute in u.an.len the number of bytes of data we need to read in order |
| 65855 | | - ** to get u.an.nField type values. u.an.offset is an upper bound on this. But |
| 65856 | | - ** u.an.nField might be significantly less than the true number of columns |
| 65857 | | - ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset. |
| 65858 | | - ** We want to minimize u.an.len in order to limit the size of the memory |
| 65859 | | - ** allocation, especially if a corrupt database file has caused u.an.offset |
| 65908 | + /* Compute in u.ao.len the number of bytes of data we need to read in order |
| 65909 | + ** to get u.ao.nField type values. u.ao.offset is an upper bound on this. But |
| 65910 | + ** u.ao.nField might be significantly less than the true number of columns |
| 65911 | + ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset. |
| 65912 | + ** We want to minimize u.ao.len in order to limit the size of the memory |
| 65913 | + ** allocation, especially if a corrupt database file has caused u.ao.offset |
| 65860 | 65914 | ** to be oversized. Offset is limited to 98307 above. But 98307 might |
| 65861 | 65915 | ** still exceed Robson memory allocation limits on some configurations. |
| 65862 | | - ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3 |
| 65863 | | - ** will likely be much smaller since u.an.nField will likely be less than |
| 65916 | + ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3 |
| 65917 | + ** will likely be much smaller since u.ao.nField will likely be less than |
| 65864 | 65918 | ** 20 or so. This insures that Robson memory allocation limits are |
| 65865 | 65919 | ** not exceeded even for corrupt database files. |
| 65866 | 65920 | */ |
| 65867 | | - u.an.len = u.an.nField*5 + 3; |
| 65868 | | - if( u.an.len > (int)u.an.offset ) u.an.len = (int)u.an.offset; |
| 65921 | + u.ao.len = u.ao.nField*5 + 3; |
| 65922 | + if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset; |
| 65869 | 65923 | |
| 65870 | 65924 | /* The KeyFetch() or DataFetch() above are fast and will get the entire |
| 65871 | 65925 | ** record header in most cases. But they will fail to get the complete |
| 65872 | 65926 | ** record header if the record header does not fit on a single page |
| 65873 | 65927 | ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to |
| 65874 | 65928 | ** acquire the complete header text. |
| 65875 | 65929 | */ |
| 65876 | | - if( !u.an.zRec && u.an.avail<u.an.len ){ |
| 65877 | | - u.an.sMem.flags = 0; |
| 65878 | | - u.an.sMem.db = 0; |
| 65879 | | - rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, 0, u.an.len, u.an.pC->isIndex, &u.an.sMem); |
| 65930 | + if( !u.ao.zRec && u.ao.avail<u.ao.len ){ |
| 65931 | + u.ao.sMem.flags = 0; |
| 65932 | + u.ao.sMem.db = 0; |
| 65933 | + rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, 0, u.ao.len, u.ao.pC->isIndex, &u.ao.sMem); |
| 65880 | 65934 | if( rc!=SQLITE_OK ){ |
| 65881 | 65935 | goto op_column_out; |
| 65882 | 65936 | } |
| 65883 | | - u.an.zData = u.an.sMem.z; |
| 65884 | | - } |
| 65885 | | - u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len]; |
| 65886 | | - u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr]; |
| 65887 | | - |
| 65888 | | - /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[] |
| 65889 | | - ** arrays. u.an.aType[u.an.i] will contain the type integer for the u.an.i-th |
| 65890 | | - ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning |
| 65891 | | - ** of the record to the start of the data for the u.an.i-th column |
| 65892 | | - */ |
| 65893 | | - for(u.an.i=0; u.an.i<u.an.nField; u.an.i++){ |
| 65894 | | - if( u.an.zIdx<u.an.zEndHdr ){ |
| 65895 | | - u.an.aOffset[u.an.i] = u.an.offset; |
| 65896 | | - if( u.an.zIdx[0]<0x80 ){ |
| 65897 | | - u.an.t = u.an.zIdx[0]; |
| 65898 | | - u.an.zIdx++; |
| 65937 | + u.ao.zData = u.ao.sMem.z; |
| 65938 | + } |
| 65939 | + u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len]; |
| 65940 | + u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr]; |
| 65941 | + |
| 65942 | + /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[] |
| 65943 | + ** arrays. u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th |
| 65944 | + ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning |
| 65945 | + ** of the record to the start of the data for the u.ao.i-th column |
| 65946 | + */ |
| 65947 | + for(u.ao.i=0; u.ao.i<u.ao.nField; u.ao.i++){ |
| 65948 | + if( u.ao.zIdx<u.ao.zEndHdr ){ |
| 65949 | + u.ao.aOffset[u.ao.i] = u.ao.offset; |
| 65950 | + if( u.ao.zIdx[0]<0x80 ){ |
| 65951 | + u.ao.t = u.ao.zIdx[0]; |
| 65952 | + u.ao.zIdx++; |
| 65899 | 65953 | }else{ |
| 65900 | | - u.an.zIdx += sqlite3GetVarint32(u.an.zIdx, &u.an.t); |
| 65954 | + u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t); |
| 65901 | 65955 | } |
| 65902 | | - u.an.aType[u.an.i] = u.an.t; |
| 65903 | | - u.an.szField = sqlite3VdbeSerialTypeLen(u.an.t); |
| 65904 | | - u.an.offset += u.an.szField; |
| 65905 | | - if( u.an.offset<u.an.szField ){ /* True if u.an.offset overflows */ |
| 65906 | | - u.an.zIdx = &u.an.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ |
| 65956 | + u.ao.aType[u.ao.i] = u.ao.t; |
| 65957 | + u.ao.szField = sqlite3VdbeSerialTypeLen(u.ao.t); |
| 65958 | + u.ao.offset += u.ao.szField; |
| 65959 | + if( u.ao.offset<u.ao.szField ){ /* True if u.ao.offset overflows */ |
| 65960 | + u.ao.zIdx = &u.ao.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ |
| 65907 | 65961 | break; |
| 65908 | 65962 | } |
| 65909 | 65963 | }else{ |
| 65910 | | - /* If u.an.i is less that u.an.nField, then there are fewer fields in this |
| 65964 | + /* If u.ao.i is less that u.ao.nField, then there are fewer fields in this |
| 65911 | 65965 | ** record than SetNumColumns indicated there are columns in the |
| 65912 | | - ** table. Set the u.an.offset for any extra columns not present in |
| 65966 | + ** table. Set the u.ao.offset for any extra columns not present in |
| 65913 | 65967 | ** the record to 0. This tells code below to store the default value |
| 65914 | 65968 | ** for the column instead of deserializing a value from the record. |
| 65915 | 65969 | */ |
| 65916 | | - u.an.aOffset[u.an.i] = 0; |
| 65970 | + u.ao.aOffset[u.ao.i] = 0; |
| 65917 | 65971 | } |
| 65918 | 65972 | } |
| 65919 | | - sqlite3VdbeMemRelease(&u.an.sMem); |
| 65920 | | - u.an.sMem.flags = MEM_Null; |
| 65973 | + sqlite3VdbeMemRelease(&u.ao.sMem); |
| 65974 | + u.ao.sMem.flags = MEM_Null; |
| 65921 | 65975 | |
| 65922 | 65976 | /* If we have read more header data than was contained in the header, |
| 65923 | 65977 | ** or if the end of the last field appears to be past the end of the |
| 65924 | 65978 | ** record, or if the end of the last field appears to be before the end |
| 65925 | 65979 | ** of the record (when all fields present), then we must be dealing |
| 65926 | 65980 | ** with a corrupt database. |
| 65927 | 65981 | */ |
| 65928 | | - if( (u.an.zIdx > u.an.zEndHdr) || (u.an.offset > u.an.payloadSize) |
| 65929 | | - || (u.an.zIdx==u.an.zEndHdr && u.an.offset!=u.an.payloadSize) ){ |
| 65982 | + if( (u.ao.zIdx > u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize) |
| 65983 | + || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){ |
| 65930 | 65984 | rc = SQLITE_CORRUPT_BKPT; |
| 65931 | 65985 | goto op_column_out; |
| 65932 | 65986 | } |
| 65933 | 65987 | } |
| 65934 | 65988 | |
| 65935 | | - /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then |
| 65936 | | - ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero, |
| 65989 | + /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then |
| 65990 | + ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero, |
| 65937 | 65991 | ** then there are not enough fields in the record to satisfy the |
| 65938 | 65992 | ** request. In this case, set the value NULL or to P4 if P4 is |
| 65939 | 65993 | ** a pointer to a Mem object. |
| 65940 | 65994 | */ |
| 65941 | | - if( u.an.aOffset[u.an.p2] ){ |
| 65995 | + if( u.ao.aOffset[u.ao.p2] ){ |
| 65942 | 65996 | assert( rc==SQLITE_OK ); |
| 65943 | | - if( u.an.zRec ){ |
| 65997 | + if( u.ao.zRec ){ |
| 65944 | 65998 | /* This is the common case where the whole row fits on a single page */ |
| 65945 | | - VdbeMemRelease(u.an.pDest); |
| 65946 | | - sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest); |
| 65999 | + VdbeMemRelease(u.ao.pDest); |
| 66000 | + sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest); |
| 65947 | 66001 | }else{ |
| 65948 | 66002 | /* This branch happens only when the row overflows onto multiple pages */ |
| 65949 | | - u.an.t = u.an.aType[u.an.p2]; |
| 66003 | + u.ao.t = u.ao.aType[u.ao.p2]; |
| 65950 | 66004 | if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 |
| 65951 | | - && ((u.an.t>=12 && (u.an.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) |
| 66005 | + && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) |
| 65952 | 66006 | ){ |
| 65953 | 66007 | /* Content is irrelevant for the typeof() function and for |
| 65954 | 66008 | ** the length(X) function if X is a blob. So we might as well use |
| 65955 | 66009 | ** bogus content rather than reading content from disk. NULL works |
| 65956 | | - ** for text and blob and whatever is in the u.an.payloadSize64 variable |
| 66010 | + ** for text and blob and whatever is in the u.ao.payloadSize64 variable |
| 65957 | 66011 | ** will work for everything else. */ |
| 65958 | | - u.an.zData = u.an.t<12 ? (char*)&u.an.payloadSize64 : 0; |
| 66012 | + u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0; |
| 65959 | 66013 | }else{ |
| 65960 | | - u.an.len = sqlite3VdbeSerialTypeLen(u.an.t); |
| 65961 | | - sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest); |
| 65962 | | - rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len, u.an.pC->isIndex, |
| 65963 | | - &u.an.sMem); |
| 66014 | + u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t); |
| 66015 | + sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest); |
| 66016 | + rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len, u.ao.pC->isIndex, |
| 66017 | + &u.ao.sMem); |
| 65964 | 66018 | if( rc!=SQLITE_OK ){ |
| 65965 | 66019 | goto op_column_out; |
| 65966 | 66020 | } |
| 65967 | | - u.an.zData = u.an.sMem.z; |
| 66021 | + u.ao.zData = u.ao.sMem.z; |
| 65968 | 66022 | } |
| 65969 | | - sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.t, u.an.pDest); |
| 66023 | + sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest); |
| 65970 | 66024 | } |
| 65971 | | - u.an.pDest->enc = encoding; |
| 66025 | + u.ao.pDest->enc = encoding; |
| 65972 | 66026 | }else{ |
| 65973 | 66027 | if( pOp->p4type==P4_MEM ){ |
| 65974 | | - sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static); |
| 66028 | + sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static); |
| 65975 | 66029 | }else{ |
| 65976 | | - MemSetTypeFlag(u.an.pDest, MEM_Null); |
| 66030 | + MemSetTypeFlag(u.ao.pDest, MEM_Null); |
| 65977 | 66031 | } |
| 65978 | 66032 | } |
| 65979 | 66033 | |
| 65980 | 66034 | /* If we dynamically allocated space to hold the data (in the |
| 65981 | 66035 | ** sqlite3VdbeMemFromBtree() call above) then transfer control of that |
| 65982 | | - ** dynamically allocated space over to the u.an.pDest structure. |
| 66036 | + ** dynamically allocated space over to the u.ao.pDest structure. |
| 65983 | 66037 | ** This prevents a memory copy. |
| 65984 | 66038 | */ |
| 65985 | | - if( u.an.sMem.zMalloc ){ |
| 65986 | | - assert( u.an.sMem.z==u.an.sMem.zMalloc ); |
| 65987 | | - assert( !(u.an.pDest->flags & MEM_Dyn) ); |
| 65988 | | - assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z ); |
| 65989 | | - u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static); |
| 65990 | | - u.an.pDest->flags |= MEM_Term; |
| 65991 | | - u.an.pDest->z = u.an.sMem.z; |
| 65992 | | - u.an.pDest->zMalloc = u.an.sMem.zMalloc; |
| 66039 | + if( u.ao.sMem.zMalloc ){ |
| 66040 | + assert( u.ao.sMem.z==u.ao.sMem.zMalloc ); |
| 66041 | + assert( !(u.ao.pDest->flags & MEM_Dyn) ); |
| 66042 | + assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z ); |
| 66043 | + u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static); |
| 66044 | + u.ao.pDest->flags |= MEM_Term; |
| 66045 | + u.ao.pDest->z = u.ao.sMem.z; |
| 66046 | + u.ao.pDest->zMalloc = u.ao.sMem.zMalloc; |
| 65993 | 66047 | } |
| 65994 | 66048 | |
| 65995 | | - rc = sqlite3VdbeMemMakeWriteable(u.an.pDest); |
| 66049 | + rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest); |
| 65996 | 66050 | |
| 65997 | 66051 | op_column_out: |
| 65998 | | - UPDATE_MAX_BLOBSIZE(u.an.pDest); |
| 65999 | | - REGISTER_TRACE(pOp->p3, u.an.pDest); |
| 66052 | + UPDATE_MAX_BLOBSIZE(u.ao.pDest); |
| 66053 | + REGISTER_TRACE(pOp->p3, u.ao.pDest); |
| 66000 | 66054 | break; |
| 66001 | 66055 | } |
| 66002 | 66056 | |
| 66003 | 66057 | /* Opcode: Affinity P1 P2 * P4 * |
| 66004 | 66058 | ** |
| | @@ -66007,24 +66061,24 @@ |
| 66007 | 66061 | ** P4 is a string that is P2 characters long. The nth character of the |
| 66008 | 66062 | ** string indicates the column affinity that should be used for the nth |
| 66009 | 66063 | ** memory cell in the range. |
| 66010 | 66064 | */ |
| 66011 | 66065 | case OP_Affinity: { |
| 66012 | | -#if 0 /* local variables moved into u.ao */ |
| 66066 | +#if 0 /* local variables moved into u.ap */ |
| 66013 | 66067 | const char *zAffinity; /* The affinity to be applied */ |
| 66014 | 66068 | char cAff; /* A single character of affinity */ |
| 66015 | | -#endif /* local variables moved into u.ao */ |
| 66069 | +#endif /* local variables moved into u.ap */ |
| 66016 | 66070 | |
| 66017 | | - u.ao.zAffinity = pOp->p4.z; |
| 66018 | | - assert( u.ao.zAffinity!=0 ); |
| 66019 | | - assert( u.ao.zAffinity[pOp->p2]==0 ); |
| 66071 | + u.ap.zAffinity = pOp->p4.z; |
| 66072 | + assert( u.ap.zAffinity!=0 ); |
| 66073 | + assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 66020 | 66074 | pIn1 = &aMem[pOp->p1]; |
| 66021 | | - while( (u.ao.cAff = *(u.ao.zAffinity++))!=0 ){ |
| 66075 | + while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 66022 | 66076 | assert( pIn1 <= &p->aMem[p->nMem] ); |
| 66023 | 66077 | assert( memIsValid(pIn1) ); |
| 66024 | 66078 | ExpandBlob(pIn1); |
| 66025 | | - applyAffinity(pIn1, u.ao.cAff, encoding); |
| 66079 | + applyAffinity(pIn1, u.ap.cAff, encoding); |
| 66026 | 66080 | pIn1++; |
| 66027 | 66081 | } |
| 66028 | 66082 | break; |
| 66029 | 66083 | } |
| 66030 | 66084 | |
| | @@ -66042,11 +66096,11 @@ |
| 66042 | 66096 | ** macros defined in sqliteInt.h. |
| 66043 | 66097 | ** |
| 66044 | 66098 | ** If P4 is NULL then all index fields have the affinity NONE. |
| 66045 | 66099 | */ |
| 66046 | 66100 | case OP_MakeRecord: { |
| 66047 | | -#if 0 /* local variables moved into u.ap */ |
| 66101 | +#if 0 /* local variables moved into u.aq */ |
| 66048 | 66102 | u8 *zNewRecord; /* A buffer to hold the data for the new record */ |
| 66049 | 66103 | Mem *pRec; /* The new record */ |
| 66050 | 66104 | u64 nData; /* Number of bytes of data space */ |
| 66051 | 66105 | int nHdr; /* Number of bytes of header space */ |
| 66052 | 66106 | i64 nByte; /* Data space required for this record */ |
| | @@ -66058,11 +66112,11 @@ |
| 66058 | 66112 | int nField; /* Number of fields in the record */ |
| 66059 | 66113 | char *zAffinity; /* The affinity string for the record */ |
| 66060 | 66114 | int file_format; /* File format to use for encoding */ |
| 66061 | 66115 | int i; /* Space used in zNewRecord[] */ |
| 66062 | 66116 | int len; /* Length of a field */ |
| 66063 | | -#endif /* local variables moved into u.ap */ |
| 66117 | +#endif /* local variables moved into u.aq */ |
| 66064 | 66118 | |
| 66065 | 66119 | /* Assuming the record contains N fields, the record format looks |
| 66066 | 66120 | ** like this: |
| 66067 | 66121 | ** |
| 66068 | 66122 | ** ------------------------------------------------------------------------ |
| | @@ -66075,87 +66129,87 @@ |
| 66075 | 66129 | ** Each type field is a varint representing the serial type of the |
| 66076 | 66130 | ** corresponding data element (see sqlite3VdbeSerialType()). The |
| 66077 | 66131 | ** hdr-size field is also a varint which is the offset from the beginning |
| 66078 | 66132 | ** of the record to data0. |
| 66079 | 66133 | */ |
| 66080 | | - u.ap.nData = 0; /* Number of bytes of data space */ |
| 66081 | | - u.ap.nHdr = 0; /* Number of bytes of header space */ |
| 66082 | | - u.ap.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 66083 | | - u.ap.nField = pOp->p1; |
| 66084 | | - u.ap.zAffinity = pOp->p4.z; |
| 66085 | | - assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 ); |
| 66086 | | - u.ap.pData0 = &aMem[u.ap.nField]; |
| 66087 | | - u.ap.nField = pOp->p2; |
| 66088 | | - u.ap.pLast = &u.ap.pData0[u.ap.nField-1]; |
| 66089 | | - u.ap.file_format = p->minWriteFileFormat; |
| 66134 | + u.aq.nData = 0; /* Number of bytes of data space */ |
| 66135 | + u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 66136 | + u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 66137 | + u.aq.nField = pOp->p1; |
| 66138 | + u.aq.zAffinity = pOp->p4.z; |
| 66139 | + assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 ); |
| 66140 | + u.aq.pData0 = &aMem[u.aq.nField]; |
| 66141 | + u.aq.nField = pOp->p2; |
| 66142 | + u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 66143 | + u.aq.file_format = p->minWriteFileFormat; |
| 66090 | 66144 | |
| 66091 | 66145 | /* Identify the output register */ |
| 66092 | 66146 | assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); |
| 66093 | 66147 | pOut = &aMem[pOp->p3]; |
| 66094 | 66148 | memAboutToChange(p, pOut); |
| 66095 | 66149 | |
| 66096 | 66150 | /* Loop through the elements that will make up the record to figure |
| 66097 | 66151 | ** out how much space is required for the new record. |
| 66098 | 66152 | */ |
| 66099 | | - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ |
| 66100 | | - assert( memIsValid(u.ap.pRec) ); |
| 66101 | | - if( u.ap.zAffinity ){ |
| 66102 | | - applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding); |
| 66103 | | - } |
| 66104 | | - if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){ |
| 66105 | | - sqlite3VdbeMemExpandBlob(u.ap.pRec); |
| 66106 | | - } |
| 66107 | | - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); |
| 66108 | | - u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type); |
| 66109 | | - u.ap.nData += u.ap.len; |
| 66110 | | - u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type); |
| 66111 | | - if( u.ap.pRec->flags & MEM_Zero ){ |
| 66153 | + for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ |
| 66154 | + assert( memIsValid(u.aq.pRec) ); |
| 66155 | + if( u.aq.zAffinity ){ |
| 66156 | + applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding); |
| 66157 | + } |
| 66158 | + if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){ |
| 66159 | + sqlite3VdbeMemExpandBlob(u.aq.pRec); |
| 66160 | + } |
| 66161 | + u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format); |
| 66162 | + u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type); |
| 66163 | + u.aq.nData += u.aq.len; |
| 66164 | + u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type); |
| 66165 | + if( u.aq.pRec->flags & MEM_Zero ){ |
| 66112 | 66166 | /* Only pure zero-filled BLOBs can be input to this Opcode. |
| 66113 | 66167 | ** We do not allow blobs with a prefix and a zero-filled tail. */ |
| 66114 | | - u.ap.nZero += u.ap.pRec->u.nZero; |
| 66115 | | - }else if( u.ap.len ){ |
| 66116 | | - u.ap.nZero = 0; |
| 66168 | + u.aq.nZero += u.aq.pRec->u.nZero; |
| 66169 | + }else if( u.aq.len ){ |
| 66170 | + u.aq.nZero = 0; |
| 66117 | 66171 | } |
| 66118 | 66172 | } |
| 66119 | 66173 | |
| 66120 | 66174 | /* Add the initial header varint and total the size */ |
| 66121 | | - u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr); |
| 66122 | | - if( u.ap.nVarint<sqlite3VarintLen(u.ap.nHdr) ){ |
| 66123 | | - u.ap.nHdr++; |
| 66175 | + u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr); |
| 66176 | + if( u.aq.nVarint<sqlite3VarintLen(u.aq.nHdr) ){ |
| 66177 | + u.aq.nHdr++; |
| 66124 | 66178 | } |
| 66125 | | - u.ap.nByte = u.ap.nHdr+u.ap.nData-u.ap.nZero; |
| 66126 | | - if( u.ap.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 66179 | + u.aq.nByte = u.aq.nHdr+u.aq.nData-u.aq.nZero; |
| 66180 | + if( u.aq.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 66127 | 66181 | goto too_big; |
| 66128 | 66182 | } |
| 66129 | 66183 | |
| 66130 | 66184 | /* Make sure the output register has a buffer large enough to store |
| 66131 | 66185 | ** the new record. The output register (pOp->p3) is not allowed to |
| 66132 | 66186 | ** be one of the input registers (because the following call to |
| 66133 | 66187 | ** sqlite3VdbeMemGrow() could clobber the value before it is used). |
| 66134 | 66188 | */ |
| 66135 | | - if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){ |
| 66189 | + if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){ |
| 66136 | 66190 | goto no_mem; |
| 66137 | 66191 | } |
| 66138 | | - u.ap.zNewRecord = (u8 *)pOut->z; |
| 66192 | + u.aq.zNewRecord = (u8 *)pOut->z; |
| 66139 | 66193 | |
| 66140 | 66194 | /* Write the record */ |
| 66141 | | - u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr); |
| 66142 | | - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ |
| 66143 | | - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); |
| 66144 | | - u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type); /* serial type */ |
| 66145 | | - } |
| 66146 | | - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ /* serial data */ |
| 66147 | | - u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format); |
| 66148 | | - } |
| 66149 | | - assert( u.ap.i==u.ap.nByte ); |
| 66195 | + u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr); |
| 66196 | + for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ |
| 66197 | + u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format); |
| 66198 | + u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type); /* serial type */ |
| 66199 | + } |
| 66200 | + for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 66201 | + u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format); |
| 66202 | + } |
| 66203 | + assert( u.aq.i==u.aq.nByte ); |
| 66150 | 66204 | |
| 66151 | 66205 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 66152 | | - pOut->n = (int)u.ap.nByte; |
| 66206 | + pOut->n = (int)u.aq.nByte; |
| 66153 | 66207 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 66154 | 66208 | pOut->xDel = 0; |
| 66155 | | - if( u.ap.nZero ){ |
| 66156 | | - pOut->u.nZero = u.ap.nZero; |
| 66209 | + if( u.aq.nZero ){ |
| 66210 | + pOut->u.nZero = u.aq.nZero; |
| 66157 | 66211 | pOut->flags |= MEM_Zero; |
| 66158 | 66212 | } |
| 66159 | 66213 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ |
| 66160 | 66214 | REGISTER_TRACE(pOp->p3, pOut); |
| 66161 | 66215 | UPDATE_MAX_BLOBSIZE(pOut); |
| | @@ -66167,22 +66221,22 @@ |
| 66167 | 66221 | ** Store the number of entries (an integer value) in the table or index |
| 66168 | 66222 | ** opened by cursor P1 in register P2 |
| 66169 | 66223 | */ |
| 66170 | 66224 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 66171 | 66225 | case OP_Count: { /* out2-prerelease */ |
| 66172 | | -#if 0 /* local variables moved into u.aq */ |
| 66226 | +#if 0 /* local variables moved into u.ar */ |
| 66173 | 66227 | i64 nEntry; |
| 66174 | 66228 | BtCursor *pCrsr; |
| 66175 | | -#endif /* local variables moved into u.aq */ |
| 66176 | | - |
| 66177 | | - u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor; |
| 66178 | | - if( ALWAYS(u.aq.pCrsr) ){ |
| 66179 | | - rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry); |
| 66180 | | - }else{ |
| 66181 | | - u.aq.nEntry = 0; |
| 66182 | | - } |
| 66183 | | - pOut->u.i = u.aq.nEntry; |
| 66229 | +#endif /* local variables moved into u.ar */ |
| 66230 | + |
| 66231 | + u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor; |
| 66232 | + if( ALWAYS(u.ar.pCrsr) ){ |
| 66233 | + rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry); |
| 66234 | + }else{ |
| 66235 | + u.ar.nEntry = 0; |
| 66236 | + } |
| 66237 | + pOut->u.i = u.ar.nEntry; |
| 66184 | 66238 | break; |
| 66185 | 66239 | } |
| 66186 | 66240 | #endif |
| 66187 | 66241 | |
| 66188 | 66242 | /* Opcode: Savepoint P1 * * P4 * |
| | @@ -66190,42 +66244,42 @@ |
| 66190 | 66244 | ** Open, release or rollback the savepoint named by parameter P4, depending |
| 66191 | 66245 | ** on the value of P1. To open a new savepoint, P1==0. To release (commit) an |
| 66192 | 66246 | ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. |
| 66193 | 66247 | */ |
| 66194 | 66248 | case OP_Savepoint: { |
| 66195 | | -#if 0 /* local variables moved into u.ar */ |
| 66249 | +#if 0 /* local variables moved into u.as */ |
| 66196 | 66250 | int p1; /* Value of P1 operand */ |
| 66197 | 66251 | char *zName; /* Name of savepoint */ |
| 66198 | 66252 | int nName; |
| 66199 | 66253 | Savepoint *pNew; |
| 66200 | 66254 | Savepoint *pSavepoint; |
| 66201 | 66255 | Savepoint *pTmp; |
| 66202 | 66256 | int iSavepoint; |
| 66203 | 66257 | int ii; |
| 66204 | | -#endif /* local variables moved into u.ar */ |
| 66258 | +#endif /* local variables moved into u.as */ |
| 66205 | 66259 | |
| 66206 | | - u.ar.p1 = pOp->p1; |
| 66207 | | - u.ar.zName = pOp->p4.z; |
| 66260 | + u.as.p1 = pOp->p1; |
| 66261 | + u.as.zName = pOp->p4.z; |
| 66208 | 66262 | |
| 66209 | | - /* Assert that the u.ar.p1 parameter is valid. Also that if there is no open |
| 66263 | + /* Assert that the u.as.p1 parameter is valid. Also that if there is no open |
| 66210 | 66264 | ** transaction, then there cannot be any savepoints. |
| 66211 | 66265 | */ |
| 66212 | 66266 | assert( db->pSavepoint==0 || db->autoCommit==0 ); |
| 66213 | | - assert( u.ar.p1==SAVEPOINT_BEGIN||u.ar.p1==SAVEPOINT_RELEASE||u.ar.p1==SAVEPOINT_ROLLBACK ); |
| 66267 | + assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK ); |
| 66214 | 66268 | assert( db->pSavepoint || db->isTransactionSavepoint==0 ); |
| 66215 | 66269 | assert( checkSavepointCount(db) ); |
| 66216 | 66270 | |
| 66217 | | - if( u.ar.p1==SAVEPOINT_BEGIN ){ |
| 66271 | + if( u.as.p1==SAVEPOINT_BEGIN ){ |
| 66218 | 66272 | if( db->writeVdbeCnt>0 ){ |
| 66219 | 66273 | /* A new savepoint cannot be created if there are active write |
| 66220 | 66274 | ** statements (i.e. open read/write incremental blob handles). |
| 66221 | 66275 | */ |
| 66222 | 66276 | sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " |
| 66223 | 66277 | "SQL statements in progress"); |
| 66224 | 66278 | rc = SQLITE_BUSY; |
| 66225 | 66279 | }else{ |
| 66226 | | - u.ar.nName = sqlite3Strlen30(u.ar.zName); |
| 66280 | + u.as.nName = sqlite3Strlen30(u.as.zName); |
| 66227 | 66281 | |
| 66228 | 66282 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 66229 | 66283 | /* This call is Ok even if this savepoint is actually a transaction |
| 66230 | 66284 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 66231 | 66285 | ** If this is a transaction savepoint being opened, it is guaranteed |
| | @@ -66235,14 +66289,14 @@ |
| 66235 | 66289 | db->nStatement+db->nSavepoint); |
| 66236 | 66290 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66237 | 66291 | #endif |
| 66238 | 66292 | |
| 66239 | 66293 | /* Create a new savepoint structure. */ |
| 66240 | | - u.ar.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.ar.nName+1); |
| 66241 | | - if( u.ar.pNew ){ |
| 66242 | | - u.ar.pNew->zName = (char *)&u.ar.pNew[1]; |
| 66243 | | - memcpy(u.ar.pNew->zName, u.ar.zName, u.ar.nName+1); |
| 66294 | + u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1); |
| 66295 | + if( u.as.pNew ){ |
| 66296 | + u.as.pNew->zName = (char *)&u.as.pNew[1]; |
| 66297 | + memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1); |
| 66244 | 66298 | |
| 66245 | 66299 | /* If there is no open transaction, then mark this as a special |
| 66246 | 66300 | ** "transaction savepoint". */ |
| 66247 | 66301 | if( db->autoCommit ){ |
| 66248 | 66302 | db->autoCommit = 0; |
| | @@ -66250,31 +66304,31 @@ |
| 66250 | 66304 | }else{ |
| 66251 | 66305 | db->nSavepoint++; |
| 66252 | 66306 | } |
| 66253 | 66307 | |
| 66254 | 66308 | /* Link the new savepoint into the database handle's list. */ |
| 66255 | | - u.ar.pNew->pNext = db->pSavepoint; |
| 66256 | | - db->pSavepoint = u.ar.pNew; |
| 66257 | | - u.ar.pNew->nDeferredCons = db->nDeferredCons; |
| 66309 | + u.as.pNew->pNext = db->pSavepoint; |
| 66310 | + db->pSavepoint = u.as.pNew; |
| 66311 | + u.as.pNew->nDeferredCons = db->nDeferredCons; |
| 66258 | 66312 | } |
| 66259 | 66313 | } |
| 66260 | 66314 | }else{ |
| 66261 | | - u.ar.iSavepoint = 0; |
| 66315 | + u.as.iSavepoint = 0; |
| 66262 | 66316 | |
| 66263 | 66317 | /* Find the named savepoint. If there is no such savepoint, then an |
| 66264 | 66318 | ** an error is returned to the user. */ |
| 66265 | 66319 | for( |
| 66266 | | - u.ar.pSavepoint = db->pSavepoint; |
| 66267 | | - u.ar.pSavepoint && sqlite3StrICmp(u.ar.pSavepoint->zName, u.ar.zName); |
| 66268 | | - u.ar.pSavepoint = u.ar.pSavepoint->pNext |
| 66320 | + u.as.pSavepoint = db->pSavepoint; |
| 66321 | + u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName); |
| 66322 | + u.as.pSavepoint = u.as.pSavepoint->pNext |
| 66269 | 66323 | ){ |
| 66270 | | - u.ar.iSavepoint++; |
| 66324 | + u.as.iSavepoint++; |
| 66271 | 66325 | } |
| 66272 | | - if( !u.ar.pSavepoint ){ |
| 66273 | | - sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName); |
| 66326 | + if( !u.as.pSavepoint ){ |
| 66327 | + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName); |
| 66274 | 66328 | rc = SQLITE_ERROR; |
| 66275 | | - }else if( db->writeVdbeCnt>0 && u.ar.p1==SAVEPOINT_RELEASE ){ |
| 66329 | + }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){ |
| 66276 | 66330 | /* It is not possible to release (commit) a savepoint if there are |
| 66277 | 66331 | ** active write statements. |
| 66278 | 66332 | */ |
| 66279 | 66333 | sqlite3SetString(&p->zErrMsg, db, |
| 66280 | 66334 | "cannot release savepoint - SQL statements in progress" |
| | @@ -66284,12 +66338,12 @@ |
| 66284 | 66338 | |
| 66285 | 66339 | /* Determine whether or not this is a transaction savepoint. If so, |
| 66286 | 66340 | ** and this is a RELEASE command, then the current transaction |
| 66287 | 66341 | ** is committed. |
| 66288 | 66342 | */ |
| 66289 | | - int isTransaction = u.ar.pSavepoint->pNext==0 && db->isTransactionSavepoint; |
| 66290 | | - if( isTransaction && u.ar.p1==SAVEPOINT_RELEASE ){ |
| 66343 | + int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint; |
| 66344 | + if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){ |
| 66291 | 66345 | if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 66292 | 66346 | goto vdbe_return; |
| 66293 | 66347 | } |
| 66294 | 66348 | db->autoCommit = 1; |
| 66295 | 66349 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| | @@ -66299,55 +66353,55 @@ |
| 66299 | 66353 | goto vdbe_return; |
| 66300 | 66354 | } |
| 66301 | 66355 | db->isTransactionSavepoint = 0; |
| 66302 | 66356 | rc = p->rc; |
| 66303 | 66357 | }else{ |
| 66304 | | - u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1; |
| 66305 | | - if( u.ar.p1==SAVEPOINT_ROLLBACK ){ |
| 66306 | | - for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){ |
| 66307 | | - sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT); |
| 66358 | + u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1; |
| 66359 | + if( u.as.p1==SAVEPOINT_ROLLBACK ){ |
| 66360 | + for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){ |
| 66361 | + sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT); |
| 66308 | 66362 | } |
| 66309 | 66363 | } |
| 66310 | | - for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){ |
| 66311 | | - rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint); |
| 66364 | + for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){ |
| 66365 | + rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint); |
| 66312 | 66366 | if( rc!=SQLITE_OK ){ |
| 66313 | 66367 | goto abort_due_to_error; |
| 66314 | 66368 | } |
| 66315 | 66369 | } |
| 66316 | | - if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ |
| 66370 | + if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ |
| 66317 | 66371 | sqlite3ExpirePreparedStatements(db); |
| 66318 | 66372 | sqlite3ResetAllSchemasOfConnection(db); |
| 66319 | 66373 | db->flags = (db->flags | SQLITE_InternChanges); |
| 66320 | 66374 | } |
| 66321 | 66375 | } |
| 66322 | 66376 | |
| 66323 | 66377 | /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all |
| 66324 | 66378 | ** savepoints nested inside of the savepoint being operated on. */ |
| 66325 | | - while( db->pSavepoint!=u.ar.pSavepoint ){ |
| 66326 | | - u.ar.pTmp = db->pSavepoint; |
| 66327 | | - db->pSavepoint = u.ar.pTmp->pNext; |
| 66328 | | - sqlite3DbFree(db, u.ar.pTmp); |
| 66379 | + while( db->pSavepoint!=u.as.pSavepoint ){ |
| 66380 | + u.as.pTmp = db->pSavepoint; |
| 66381 | + db->pSavepoint = u.as.pTmp->pNext; |
| 66382 | + sqlite3DbFree(db, u.as.pTmp); |
| 66329 | 66383 | db->nSavepoint--; |
| 66330 | 66384 | } |
| 66331 | 66385 | |
| 66332 | 66386 | /* If it is a RELEASE, then destroy the savepoint being operated on |
| 66333 | 66387 | ** too. If it is a ROLLBACK TO, then set the number of deferred |
| 66334 | 66388 | ** constraint violations present in the database to the value stored |
| 66335 | 66389 | ** when the savepoint was created. */ |
| 66336 | | - if( u.ar.p1==SAVEPOINT_RELEASE ){ |
| 66337 | | - assert( u.ar.pSavepoint==db->pSavepoint ); |
| 66338 | | - db->pSavepoint = u.ar.pSavepoint->pNext; |
| 66339 | | - sqlite3DbFree(db, u.ar.pSavepoint); |
| 66390 | + if( u.as.p1==SAVEPOINT_RELEASE ){ |
| 66391 | + assert( u.as.pSavepoint==db->pSavepoint ); |
| 66392 | + db->pSavepoint = u.as.pSavepoint->pNext; |
| 66393 | + sqlite3DbFree(db, u.as.pSavepoint); |
| 66340 | 66394 | if( !isTransaction ){ |
| 66341 | 66395 | db->nSavepoint--; |
| 66342 | 66396 | } |
| 66343 | 66397 | }else{ |
| 66344 | | - db->nDeferredCons = u.ar.pSavepoint->nDeferredCons; |
| 66398 | + db->nDeferredCons = u.as.pSavepoint->nDeferredCons; |
| 66345 | 66399 | } |
| 66346 | 66400 | |
| 66347 | 66401 | if( !isTransaction ){ |
| 66348 | | - rc = sqlite3VtabSavepoint(db, u.ar.p1, u.ar.iSavepoint); |
| 66402 | + rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint); |
| 66349 | 66403 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66350 | 66404 | } |
| 66351 | 66405 | } |
| 66352 | 66406 | } |
| 66353 | 66407 | |
| | @@ -66362,53 +66416,53 @@ |
| 66362 | 66416 | ** there are active writing VMs or active VMs that use shared cache. |
| 66363 | 66417 | ** |
| 66364 | 66418 | ** This instruction causes the VM to halt. |
| 66365 | 66419 | */ |
| 66366 | 66420 | case OP_AutoCommit: { |
| 66367 | | -#if 0 /* local variables moved into u.as */ |
| 66421 | +#if 0 /* local variables moved into u.at */ |
| 66368 | 66422 | int desiredAutoCommit; |
| 66369 | 66423 | int iRollback; |
| 66370 | 66424 | int turnOnAC; |
| 66371 | | -#endif /* local variables moved into u.as */ |
| 66425 | +#endif /* local variables moved into u.at */ |
| 66372 | 66426 | |
| 66373 | | - u.as.desiredAutoCommit = pOp->p1; |
| 66374 | | - u.as.iRollback = pOp->p2; |
| 66375 | | - u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit; |
| 66376 | | - assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 ); |
| 66377 | | - assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 ); |
| 66427 | + u.at.desiredAutoCommit = pOp->p1; |
| 66428 | + u.at.iRollback = pOp->p2; |
| 66429 | + u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit; |
| 66430 | + assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 ); |
| 66431 | + assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 ); |
| 66378 | 66432 | assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ |
| 66379 | 66433 | |
| 66380 | 66434 | #if 0 |
| 66381 | | - if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){ |
| 66435 | + if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){ |
| 66382 | 66436 | /* If this instruction implements a ROLLBACK and other VMs are |
| 66383 | 66437 | ** still running, and a transaction is active, return an error indicating |
| 66384 | 66438 | ** that the other VMs must complete first. |
| 66385 | 66439 | */ |
| 66386 | 66440 | sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " |
| 66387 | 66441 | "SQL statements in progress"); |
| 66388 | 66442 | rc = SQLITE_BUSY; |
| 66389 | 66443 | }else |
| 66390 | 66444 | #endif |
| 66391 | | - if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){ |
| 66445 | + if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){ |
| 66392 | 66446 | /* If this instruction implements a COMMIT and other VMs are writing |
| 66393 | 66447 | ** return an error indicating that the other VMs must complete first. |
| 66394 | 66448 | */ |
| 66395 | 66449 | sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " |
| 66396 | 66450 | "SQL statements in progress"); |
| 66397 | 66451 | rc = SQLITE_BUSY; |
| 66398 | | - }else if( u.as.desiredAutoCommit!=db->autoCommit ){ |
| 66399 | | - if( u.as.iRollback ){ |
| 66400 | | - assert( u.as.desiredAutoCommit==1 ); |
| 66452 | + }else if( u.at.desiredAutoCommit!=db->autoCommit ){ |
| 66453 | + if( u.at.iRollback ){ |
| 66454 | + assert( u.at.desiredAutoCommit==1 ); |
| 66401 | 66455 | sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); |
| 66402 | 66456 | db->autoCommit = 1; |
| 66403 | 66457 | }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 66404 | 66458 | goto vdbe_return; |
| 66405 | 66459 | }else{ |
| 66406 | | - db->autoCommit = (u8)u.as.desiredAutoCommit; |
| 66460 | + db->autoCommit = (u8)u.at.desiredAutoCommit; |
| 66407 | 66461 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| 66408 | 66462 | p->pc = pc; |
| 66409 | | - db->autoCommit = (u8)(1-u.as.desiredAutoCommit); |
| 66463 | + db->autoCommit = (u8)(1-u.at.desiredAutoCommit); |
| 66410 | 66464 | p->rc = rc = SQLITE_BUSY; |
| 66411 | 66465 | goto vdbe_return; |
| 66412 | 66466 | } |
| 66413 | 66467 | } |
| 66414 | 66468 | assert( db->nStatement==0 ); |
| | @@ -66419,12 +66473,12 @@ |
| 66419 | 66473 | rc = SQLITE_ERROR; |
| 66420 | 66474 | } |
| 66421 | 66475 | goto vdbe_return; |
| 66422 | 66476 | }else{ |
| 66423 | 66477 | sqlite3SetString(&p->zErrMsg, db, |
| 66424 | | - (!u.as.desiredAutoCommit)?"cannot start a transaction within a transaction":( |
| 66425 | | - (u.as.iRollback)?"cannot rollback - no transaction is active": |
| 66478 | + (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":( |
| 66479 | + (u.at.iRollback)?"cannot rollback - no transaction is active": |
| 66426 | 66480 | "cannot commit - no transaction is active")); |
| 66427 | 66481 | |
| 66428 | 66482 | rc = SQLITE_ERROR; |
| 66429 | 66483 | } |
| 66430 | 66484 | break; |
| | @@ -66460,20 +66514,20 @@ |
| 66460 | 66514 | ** will automatically commit when the VDBE halts. |
| 66461 | 66515 | ** |
| 66462 | 66516 | ** If P2 is zero, then a read-lock is obtained on the database file. |
| 66463 | 66517 | */ |
| 66464 | 66518 | case OP_Transaction: { |
| 66465 | | -#if 0 /* local variables moved into u.at */ |
| 66519 | +#if 0 /* local variables moved into u.au */ |
| 66466 | 66520 | Btree *pBt; |
| 66467 | | -#endif /* local variables moved into u.at */ |
| 66521 | +#endif /* local variables moved into u.au */ |
| 66468 | 66522 | |
| 66469 | 66523 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 66470 | 66524 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 66471 | | - u.at.pBt = db->aDb[pOp->p1].pBt; |
| 66525 | + u.au.pBt = db->aDb[pOp->p1].pBt; |
| 66472 | 66526 | |
| 66473 | | - if( u.at.pBt ){ |
| 66474 | | - rc = sqlite3BtreeBeginTrans(u.at.pBt, pOp->p2); |
| 66527 | + if( u.au.pBt ){ |
| 66528 | + rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2); |
| 66475 | 66529 | if( rc==SQLITE_BUSY ){ |
| 66476 | 66530 | p->pc = pc; |
| 66477 | 66531 | p->rc = rc = SQLITE_BUSY; |
| 66478 | 66532 | goto vdbe_return; |
| 66479 | 66533 | } |
| | @@ -66482,20 +66536,20 @@ |
| 66482 | 66536 | } |
| 66483 | 66537 | |
| 66484 | 66538 | if( pOp->p2 && p->usesStmtJournal |
| 66485 | 66539 | && (db->autoCommit==0 || db->activeVdbeCnt>1) |
| 66486 | 66540 | ){ |
| 66487 | | - assert( sqlite3BtreeIsInTrans(u.at.pBt) ); |
| 66541 | + assert( sqlite3BtreeIsInTrans(u.au.pBt) ); |
| 66488 | 66542 | if( p->iStatement==0 ){ |
| 66489 | 66543 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 66490 | 66544 | db->nStatement++; |
| 66491 | 66545 | p->iStatement = db->nSavepoint + db->nStatement; |
| 66492 | 66546 | } |
| 66493 | 66547 | |
| 66494 | 66548 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); |
| 66495 | 66549 | if( rc==SQLITE_OK ){ |
| 66496 | | - rc = sqlite3BtreeBeginStmt(u.at.pBt, p->iStatement); |
| 66550 | + rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement); |
| 66497 | 66551 | } |
| 66498 | 66552 | |
| 66499 | 66553 | /* Store the current value of the database handles deferred constraint |
| 66500 | 66554 | ** counter. If the statement transaction needs to be rolled back, |
| 66501 | 66555 | ** the value of this counter needs to be restored too. */ |
| | @@ -66516,25 +66570,25 @@ |
| 66516 | 66570 | ** There must be a read-lock on the database (either a transaction |
| 66517 | 66571 | ** must be started or there must be an open cursor) before |
| 66518 | 66572 | ** executing this instruction. |
| 66519 | 66573 | */ |
| 66520 | 66574 | case OP_ReadCookie: { /* out2-prerelease */ |
| 66521 | | -#if 0 /* local variables moved into u.au */ |
| 66575 | +#if 0 /* local variables moved into u.av */ |
| 66522 | 66576 | int iMeta; |
| 66523 | 66577 | int iDb; |
| 66524 | 66578 | int iCookie; |
| 66525 | | -#endif /* local variables moved into u.au */ |
| 66579 | +#endif /* local variables moved into u.av */ |
| 66526 | 66580 | |
| 66527 | | - u.au.iDb = pOp->p1; |
| 66528 | | - u.au.iCookie = pOp->p3; |
| 66581 | + u.av.iDb = pOp->p1; |
| 66582 | + u.av.iCookie = pOp->p3; |
| 66529 | 66583 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 66530 | | - assert( u.au.iDb>=0 && u.au.iDb<db->nDb ); |
| 66531 | | - assert( db->aDb[u.au.iDb].pBt!=0 ); |
| 66532 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.au.iDb))!=0 ); |
| 66584 | + assert( u.av.iDb>=0 && u.av.iDb<db->nDb ); |
| 66585 | + assert( db->aDb[u.av.iDb].pBt!=0 ); |
| 66586 | + assert( (p->btreeMask & (((yDbMask)1)<<u.av.iDb))!=0 ); |
| 66533 | 66587 | |
| 66534 | | - sqlite3BtreeGetMeta(db->aDb[u.au.iDb].pBt, u.au.iCookie, (u32 *)&u.au.iMeta); |
| 66535 | | - pOut->u.i = u.au.iMeta; |
| 66588 | + sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta); |
| 66589 | + pOut->u.i = u.av.iMeta; |
| 66536 | 66590 | break; |
| 66537 | 66591 | } |
| 66538 | 66592 | |
| 66539 | 66593 | /* Opcode: SetCookie P1 P2 P3 * * |
| 66540 | 66594 | ** |
| | @@ -66545,30 +66599,30 @@ |
| 66545 | 66599 | ** database file used to store temporary tables. |
| 66546 | 66600 | ** |
| 66547 | 66601 | ** A transaction must be started before executing this opcode. |
| 66548 | 66602 | */ |
| 66549 | 66603 | case OP_SetCookie: { /* in3 */ |
| 66550 | | -#if 0 /* local variables moved into u.av */ |
| 66604 | +#if 0 /* local variables moved into u.aw */ |
| 66551 | 66605 | Db *pDb; |
| 66552 | | -#endif /* local variables moved into u.av */ |
| 66606 | +#endif /* local variables moved into u.aw */ |
| 66553 | 66607 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 66554 | 66608 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 66555 | 66609 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 66556 | | - u.av.pDb = &db->aDb[pOp->p1]; |
| 66557 | | - assert( u.av.pDb->pBt!=0 ); |
| 66610 | + u.aw.pDb = &db->aDb[pOp->p1]; |
| 66611 | + assert( u.aw.pDb->pBt!=0 ); |
| 66558 | 66612 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 66559 | 66613 | pIn3 = &aMem[pOp->p3]; |
| 66560 | 66614 | sqlite3VdbeMemIntegerify(pIn3); |
| 66561 | 66615 | /* See note about index shifting on OP_ReadCookie */ |
| 66562 | | - rc = sqlite3BtreeUpdateMeta(u.av.pDb->pBt, pOp->p2, (int)pIn3->u.i); |
| 66616 | + rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i); |
| 66563 | 66617 | if( pOp->p2==BTREE_SCHEMA_VERSION ){ |
| 66564 | 66618 | /* When the schema cookie changes, record the new cookie internally */ |
| 66565 | | - u.av.pDb->pSchema->schema_cookie = (int)pIn3->u.i; |
| 66619 | + u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i; |
| 66566 | 66620 | db->flags |= SQLITE_InternChanges; |
| 66567 | 66621 | }else if( pOp->p2==BTREE_FILE_FORMAT ){ |
| 66568 | 66622 | /* Record changes in the file format */ |
| 66569 | | - u.av.pDb->pSchema->file_format = (u8)pIn3->u.i; |
| 66623 | + u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i; |
| 66570 | 66624 | } |
| 66571 | 66625 | if( pOp->p1==1 ){ |
| 66572 | 66626 | /* Invalidate all prepared statements whenever the TEMP database |
| 66573 | 66627 | ** schema is changed. Ticket #1644 */ |
| 66574 | 66628 | sqlite3ExpirePreparedStatements(db); |
| | @@ -66594,27 +66648,27 @@ |
| 66594 | 66648 | ** Either a transaction needs to have been started or an OP_Open needs |
| 66595 | 66649 | ** to be executed (to establish a read lock) before this opcode is |
| 66596 | 66650 | ** invoked. |
| 66597 | 66651 | */ |
| 66598 | 66652 | case OP_VerifyCookie: { |
| 66599 | | -#if 0 /* local variables moved into u.aw */ |
| 66653 | +#if 0 /* local variables moved into u.ax */ |
| 66600 | 66654 | int iMeta; |
| 66601 | 66655 | int iGen; |
| 66602 | 66656 | Btree *pBt; |
| 66603 | | -#endif /* local variables moved into u.aw */ |
| 66657 | +#endif /* local variables moved into u.ax */ |
| 66604 | 66658 | |
| 66605 | 66659 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 66606 | 66660 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 66607 | 66661 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 66608 | | - u.aw.pBt = db->aDb[pOp->p1].pBt; |
| 66609 | | - if( u.aw.pBt ){ |
| 66610 | | - sqlite3BtreeGetMeta(u.aw.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.aw.iMeta); |
| 66611 | | - u.aw.iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 66662 | + u.ax.pBt = db->aDb[pOp->p1].pBt; |
| 66663 | + if( u.ax.pBt ){ |
| 66664 | + sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta); |
| 66665 | + u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 66612 | 66666 | }else{ |
| 66613 | | - u.aw.iGen = u.aw.iMeta = 0; |
| 66667 | + u.ax.iGen = u.ax.iMeta = 0; |
| 66614 | 66668 | } |
| 66615 | | - if( u.aw.iMeta!=pOp->p2 || u.aw.iGen!=pOp->p3 ){ |
| 66669 | + if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){ |
| 66616 | 66670 | sqlite3DbFree(db, p->zErrMsg); |
| 66617 | 66671 | p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); |
| 66618 | 66672 | /* If the schema-cookie from the database file matches the cookie |
| 66619 | 66673 | ** stored with the in-memory representation of the schema, do |
| 66620 | 66674 | ** not reload the schema from the database file. |
| | @@ -66626,11 +66680,11 @@ |
| 66626 | 66680 | ** discard the database schema, as the user code implementing the |
| 66627 | 66681 | ** v-table would have to be ready for the sqlite3_vtab structure itself |
| 66628 | 66682 | ** to be invalidated whenever sqlite3_step() is called from within |
| 66629 | 66683 | ** a v-table method. |
| 66630 | 66684 | */ |
| 66631 | | - if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){ |
| 66685 | + if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){ |
| 66632 | 66686 | sqlite3ResetOneSchema(db, pOp->p1); |
| 66633 | 66687 | } |
| 66634 | 66688 | |
| 66635 | 66689 | p->expired = 1; |
| 66636 | 66690 | rc = SQLITE_SCHEMA; |
| | @@ -66687,91 +66741,91 @@ |
| 66687 | 66741 | ** |
| 66688 | 66742 | ** See also OpenRead. |
| 66689 | 66743 | */ |
| 66690 | 66744 | case OP_OpenRead: |
| 66691 | 66745 | case OP_OpenWrite: { |
| 66692 | | -#if 0 /* local variables moved into u.ax */ |
| 66746 | +#if 0 /* local variables moved into u.ay */ |
| 66693 | 66747 | int nField; |
| 66694 | 66748 | KeyInfo *pKeyInfo; |
| 66695 | 66749 | int p2; |
| 66696 | 66750 | int iDb; |
| 66697 | 66751 | int wrFlag; |
| 66698 | 66752 | Btree *pX; |
| 66699 | 66753 | VdbeCursor *pCur; |
| 66700 | 66754 | Db *pDb; |
| 66701 | | -#endif /* local variables moved into u.ax */ |
| 66755 | +#endif /* local variables moved into u.ay */ |
| 66702 | 66756 | |
| 66703 | 66757 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 66704 | 66758 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 66705 | 66759 | |
| 66706 | 66760 | if( p->expired ){ |
| 66707 | 66761 | rc = SQLITE_ABORT; |
| 66708 | 66762 | break; |
| 66709 | 66763 | } |
| 66710 | 66764 | |
| 66711 | | - u.ax.nField = 0; |
| 66712 | | - u.ax.pKeyInfo = 0; |
| 66713 | | - u.ax.p2 = pOp->p2; |
| 66714 | | - u.ax.iDb = pOp->p3; |
| 66715 | | - assert( u.ax.iDb>=0 && u.ax.iDb<db->nDb ); |
| 66716 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.ax.iDb))!=0 ); |
| 66717 | | - u.ax.pDb = &db->aDb[u.ax.iDb]; |
| 66718 | | - u.ax.pX = u.ax.pDb->pBt; |
| 66719 | | - assert( u.ax.pX!=0 ); |
| 66765 | + u.ay.nField = 0; |
| 66766 | + u.ay.pKeyInfo = 0; |
| 66767 | + u.ay.p2 = pOp->p2; |
| 66768 | + u.ay.iDb = pOp->p3; |
| 66769 | + assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb ); |
| 66770 | + assert( (p->btreeMask & (((yDbMask)1)<<u.ay.iDb))!=0 ); |
| 66771 | + u.ay.pDb = &db->aDb[u.ay.iDb]; |
| 66772 | + u.ay.pX = u.ay.pDb->pBt; |
| 66773 | + assert( u.ay.pX!=0 ); |
| 66720 | 66774 | if( pOp->opcode==OP_OpenWrite ){ |
| 66721 | | - u.ax.wrFlag = 1; |
| 66722 | | - assert( sqlite3SchemaMutexHeld(db, u.ax.iDb, 0) ); |
| 66723 | | - if( u.ax.pDb->pSchema->file_format < p->minWriteFileFormat ){ |
| 66724 | | - p->minWriteFileFormat = u.ax.pDb->pSchema->file_format; |
| 66775 | + u.ay.wrFlag = 1; |
| 66776 | + assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) ); |
| 66777 | + if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){ |
| 66778 | + p->minWriteFileFormat = u.ay.pDb->pSchema->file_format; |
| 66725 | 66779 | } |
| 66726 | 66780 | }else{ |
| 66727 | | - u.ax.wrFlag = 0; |
| 66781 | + u.ay.wrFlag = 0; |
| 66728 | 66782 | } |
| 66729 | 66783 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 66730 | | - assert( u.ax.p2>0 ); |
| 66731 | | - assert( u.ax.p2<=p->nMem ); |
| 66732 | | - pIn2 = &aMem[u.ax.p2]; |
| 66784 | + assert( u.ay.p2>0 ); |
| 66785 | + assert( u.ay.p2<=p->nMem ); |
| 66786 | + pIn2 = &aMem[u.ay.p2]; |
| 66733 | 66787 | assert( memIsValid(pIn2) ); |
| 66734 | 66788 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 66735 | 66789 | sqlite3VdbeMemIntegerify(pIn2); |
| 66736 | | - u.ax.p2 = (int)pIn2->u.i; |
| 66737 | | - /* The u.ax.p2 value always comes from a prior OP_CreateTable opcode and |
| 66738 | | - ** that opcode will always set the u.ax.p2 value to 2 or more or else fail. |
| 66790 | + u.ay.p2 = (int)pIn2->u.i; |
| 66791 | + /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and |
| 66792 | + ** that opcode will always set the u.ay.p2 value to 2 or more or else fail. |
| 66739 | 66793 | ** If there were a failure, the prepared statement would have halted |
| 66740 | 66794 | ** before reaching this instruction. */ |
| 66741 | | - if( NEVER(u.ax.p2<2) ) { |
| 66795 | + if( NEVER(u.ay.p2<2) ) { |
| 66742 | 66796 | rc = SQLITE_CORRUPT_BKPT; |
| 66743 | 66797 | goto abort_due_to_error; |
| 66744 | 66798 | } |
| 66745 | 66799 | } |
| 66746 | 66800 | if( pOp->p4type==P4_KEYINFO ){ |
| 66747 | | - u.ax.pKeyInfo = pOp->p4.pKeyInfo; |
| 66748 | | - u.ax.pKeyInfo->enc = ENC(p->db); |
| 66749 | | - u.ax.nField = u.ax.pKeyInfo->nField+1; |
| 66801 | + u.ay.pKeyInfo = pOp->p4.pKeyInfo; |
| 66802 | + u.ay.pKeyInfo->enc = ENC(p->db); |
| 66803 | + u.ay.nField = u.ay.pKeyInfo->nField+1; |
| 66750 | 66804 | }else if( pOp->p4type==P4_INT32 ){ |
| 66751 | | - u.ax.nField = pOp->p4.i; |
| 66805 | + u.ay.nField = pOp->p4.i; |
| 66752 | 66806 | } |
| 66753 | 66807 | assert( pOp->p1>=0 ); |
| 66754 | | - u.ax.pCur = allocateCursor(p, pOp->p1, u.ax.nField, u.ax.iDb, 1); |
| 66755 | | - if( u.ax.pCur==0 ) goto no_mem; |
| 66756 | | - u.ax.pCur->nullRow = 1; |
| 66757 | | - u.ax.pCur->isOrdered = 1; |
| 66758 | | - rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); |
| 66759 | | - u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; |
| 66808 | + u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1); |
| 66809 | + if( u.ay.pCur==0 ) goto no_mem; |
| 66810 | + u.ay.pCur->nullRow = 1; |
| 66811 | + u.ay.pCur->isOrdered = 1; |
| 66812 | + rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor); |
| 66813 | + u.ay.pCur->pKeyInfo = u.ay.pKeyInfo; |
| 66760 | 66814 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 66761 | | - sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 66815 | + sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 66762 | 66816 | |
| 66763 | 66817 | /* Since it performs no memory allocation or IO, the only value that |
| 66764 | 66818 | ** sqlite3BtreeCursor() may return is SQLITE_OK. */ |
| 66765 | 66819 | assert( rc==SQLITE_OK ); |
| 66766 | 66820 | |
| 66767 | 66821 | /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of |
| 66768 | 66822 | ** SQLite used to check if the root-page flags were sane at this point |
| 66769 | 66823 | ** and report database corruption if they were not, but this check has |
| 66770 | 66824 | ** since moved into the btree layer. */ |
| 66771 | | - u.ax.pCur->isTable = pOp->p4type!=P4_KEYINFO; |
| 66772 | | - u.ax.pCur->isIndex = !u.ax.pCur->isTable; |
| 66825 | + u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO; |
| 66826 | + u.ay.pCur->isIndex = !u.ay.pCur->isTable; |
| 66773 | 66827 | break; |
| 66774 | 66828 | } |
| 66775 | 66829 | |
| 66776 | 66830 | /* Opcode: OpenEphemeral P1 P2 * P4 P5 |
| 66777 | 66831 | ** |
| | @@ -66803,28 +66857,28 @@ |
| 66803 | 66857 | ** by this opcode will be used for automatically created transient |
| 66804 | 66858 | ** indices in joins. |
| 66805 | 66859 | */ |
| 66806 | 66860 | case OP_OpenAutoindex: |
| 66807 | 66861 | case OP_OpenEphemeral: { |
| 66808 | | -#if 0 /* local variables moved into u.ay */ |
| 66862 | +#if 0 /* local variables moved into u.az */ |
| 66809 | 66863 | VdbeCursor *pCx; |
| 66810 | | -#endif /* local variables moved into u.ay */ |
| 66864 | +#endif /* local variables moved into u.az */ |
| 66811 | 66865 | static const int vfsFlags = |
| 66812 | 66866 | SQLITE_OPEN_READWRITE | |
| 66813 | 66867 | SQLITE_OPEN_CREATE | |
| 66814 | 66868 | SQLITE_OPEN_EXCLUSIVE | |
| 66815 | 66869 | SQLITE_OPEN_DELETEONCLOSE | |
| 66816 | 66870 | SQLITE_OPEN_TRANSIENT_DB; |
| 66817 | 66871 | |
| 66818 | 66872 | assert( pOp->p1>=0 ); |
| 66819 | | - u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66820 | | - if( u.ay.pCx==0 ) goto no_mem; |
| 66821 | | - u.ay.pCx->nullRow = 1; |
| 66822 | | - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ay.pCx->pBt, |
| 66873 | + u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66874 | + if( u.az.pCx==0 ) goto no_mem; |
| 66875 | + u.az.pCx->nullRow = 1; |
| 66876 | + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt, |
| 66823 | 66877 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| 66824 | 66878 | if( rc==SQLITE_OK ){ |
| 66825 | | - rc = sqlite3BtreeBeginTrans(u.ay.pCx->pBt, 1); |
| 66879 | + rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1); |
| 66826 | 66880 | } |
| 66827 | 66881 | if( rc==SQLITE_OK ){ |
| 66828 | 66882 | /* If a transient index is required, create it by calling |
| 66829 | 66883 | ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
| 66830 | 66884 | ** opening it. If a transient table is required, just use the |
| | @@ -66831,26 +66885,26 @@ |
| 66831 | 66885 | ** automatically created table with root-page 1 (an BLOB_INTKEY table). |
| 66832 | 66886 | */ |
| 66833 | 66887 | if( pOp->p4.pKeyInfo ){ |
| 66834 | 66888 | int pgno; |
| 66835 | 66889 | assert( pOp->p4type==P4_KEYINFO ); |
| 66836 | | - rc = sqlite3BtreeCreateTable(u.ay.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 66890 | + rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 66837 | 66891 | if( rc==SQLITE_OK ){ |
| 66838 | 66892 | assert( pgno==MASTER_ROOT+1 ); |
| 66839 | | - rc = sqlite3BtreeCursor(u.ay.pCx->pBt, pgno, 1, |
| 66840 | | - (KeyInfo*)pOp->p4.z, u.ay.pCx->pCursor); |
| 66841 | | - u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66842 | | - u.ay.pCx->pKeyInfo->enc = ENC(p->db); |
| 66843 | | - } |
| 66844 | | - u.ay.pCx->isTable = 0; |
| 66845 | | - }else{ |
| 66846 | | - rc = sqlite3BtreeCursor(u.ay.pCx->pBt, MASTER_ROOT, 1, 0, u.ay.pCx->pCursor); |
| 66847 | | - u.ay.pCx->isTable = 1; |
| 66893 | + rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1, |
| 66894 | + (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor); |
| 66895 | + u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66896 | + u.az.pCx->pKeyInfo->enc = ENC(p->db); |
| 66897 | + } |
| 66898 | + u.az.pCx->isTable = 0; |
| 66899 | + }else{ |
| 66900 | + rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor); |
| 66901 | + u.az.pCx->isTable = 1; |
| 66848 | 66902 | } |
| 66849 | 66903 | } |
| 66850 | | - u.ay.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66851 | | - u.ay.pCx->isIndex = !u.ay.pCx->isTable; |
| 66904 | + u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66905 | + u.az.pCx->isIndex = !u.az.pCx->isTable; |
| 66852 | 66906 | break; |
| 66853 | 66907 | } |
| 66854 | 66908 | |
| 66855 | 66909 | /* Opcode: OpenSorter P1 P2 * P4 * |
| 66856 | 66910 | ** |
| | @@ -66857,20 +66911,21 @@ |
| 66857 | 66911 | ** This opcode works like OP_OpenEphemeral except that it opens |
| 66858 | 66912 | ** a transient index that is specifically designed to sort large |
| 66859 | 66913 | ** tables using an external merge-sort algorithm. |
| 66860 | 66914 | */ |
| 66861 | 66915 | case OP_SorterOpen: { |
| 66862 | | -#if 0 /* local variables moved into u.az */ |
| 66916 | +#if 0 /* local variables moved into u.ba */ |
| 66863 | 66917 | VdbeCursor *pCx; |
| 66864 | | -#endif /* local variables moved into u.az */ |
| 66918 | +#endif /* local variables moved into u.ba */ |
| 66919 | + |
| 66865 | 66920 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 66866 | | - u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66867 | | - if( u.az.pCx==0 ) goto no_mem; |
| 66868 | | - u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66869 | | - u.az.pCx->pKeyInfo->enc = ENC(p->db); |
| 66870 | | - u.az.pCx->isSorter = 1; |
| 66871 | | - rc = sqlite3VdbeSorterInit(db, u.az.pCx); |
| 66921 | + u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66922 | + if( u.ba.pCx==0 ) goto no_mem; |
| 66923 | + u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66924 | + u.ba.pCx->pKeyInfo->enc = ENC(p->db); |
| 66925 | + u.ba.pCx->isSorter = 1; |
| 66926 | + rc = sqlite3VdbeSorterInit(db, u.ba.pCx); |
| 66872 | 66927 | #else |
| 66873 | 66928 | pOp->opcode = OP_OpenEphemeral; |
| 66874 | 66929 | pc--; |
| 66875 | 66930 | #endif |
| 66876 | 66931 | break; |
| | @@ -66890,21 +66945,21 @@ |
| 66890 | 66945 | ** |
| 66891 | 66946 | ** P3 is the number of fields in the records that will be stored by |
| 66892 | 66947 | ** the pseudo-table. |
| 66893 | 66948 | */ |
| 66894 | 66949 | case OP_OpenPseudo: { |
| 66895 | | -#if 0 /* local variables moved into u.ba */ |
| 66950 | +#if 0 /* local variables moved into u.bb */ |
| 66896 | 66951 | VdbeCursor *pCx; |
| 66897 | | -#endif /* local variables moved into u.ba */ |
| 66952 | +#endif /* local variables moved into u.bb */ |
| 66898 | 66953 | |
| 66899 | 66954 | assert( pOp->p1>=0 ); |
| 66900 | | - u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 66901 | | - if( u.ba.pCx==0 ) goto no_mem; |
| 66902 | | - u.ba.pCx->nullRow = 1; |
| 66903 | | - u.ba.pCx->pseudoTableReg = pOp->p2; |
| 66904 | | - u.ba.pCx->isTable = 1; |
| 66905 | | - u.ba.pCx->isIndex = 0; |
| 66955 | + u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 66956 | + if( u.bb.pCx==0 ) goto no_mem; |
| 66957 | + u.bb.pCx->nullRow = 1; |
| 66958 | + u.bb.pCx->pseudoTableReg = pOp->p2; |
| 66959 | + u.bb.pCx->isTable = 1; |
| 66960 | + u.bb.pCx->isIndex = 0; |
| 66906 | 66961 | break; |
| 66907 | 66962 | } |
| 66908 | 66963 | |
| 66909 | 66964 | /* Opcode: Close P1 * * * * |
| 66910 | 66965 | ** |
| | @@ -66972,39 +67027,39 @@ |
| 66972 | 67027 | */ |
| 66973 | 67028 | case OP_SeekLt: /* jump, in3 */ |
| 66974 | 67029 | case OP_SeekLe: /* jump, in3 */ |
| 66975 | 67030 | case OP_SeekGe: /* jump, in3 */ |
| 66976 | 67031 | case OP_SeekGt: { /* jump, in3 */ |
| 66977 | | -#if 0 /* local variables moved into u.bb */ |
| 67032 | +#if 0 /* local variables moved into u.bc */ |
| 66978 | 67033 | int res; |
| 66979 | 67034 | int oc; |
| 66980 | 67035 | VdbeCursor *pC; |
| 66981 | 67036 | UnpackedRecord r; |
| 66982 | 67037 | int nField; |
| 66983 | 67038 | i64 iKey; /* The rowid we are to seek to */ |
| 66984 | | -#endif /* local variables moved into u.bb */ |
| 67039 | +#endif /* local variables moved into u.bc */ |
| 66985 | 67040 | |
| 66986 | 67041 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 66987 | 67042 | assert( pOp->p2!=0 ); |
| 66988 | | - u.bb.pC = p->apCsr[pOp->p1]; |
| 66989 | | - assert( u.bb.pC!=0 ); |
| 66990 | | - assert( u.bb.pC->pseudoTableReg==0 ); |
| 67043 | + u.bc.pC = p->apCsr[pOp->p1]; |
| 67044 | + assert( u.bc.pC!=0 ); |
| 67045 | + assert( u.bc.pC->pseudoTableReg==0 ); |
| 66991 | 67046 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 66992 | 67047 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 66993 | 67048 | assert( OP_SeekGt == OP_SeekLt+3 ); |
| 66994 | | - assert( u.bb.pC->isOrdered ); |
| 66995 | | - if( ALWAYS(u.bb.pC->pCursor!=0) ){ |
| 66996 | | - u.bb.oc = pOp->opcode; |
| 66997 | | - u.bb.pC->nullRow = 0; |
| 66998 | | - if( u.bb.pC->isTable ){ |
| 67049 | + assert( u.bc.pC->isOrdered ); |
| 67050 | + if( ALWAYS(u.bc.pC->pCursor!=0) ){ |
| 67051 | + u.bc.oc = pOp->opcode; |
| 67052 | + u.bc.pC->nullRow = 0; |
| 67053 | + if( u.bc.pC->isTable ){ |
| 66999 | 67054 | /* The input value in P3 might be of any type: integer, real, string, |
| 67000 | 67055 | ** blob, or NULL. But it needs to be an integer before we can do |
| 67001 | 67056 | ** the seek, so covert it. */ |
| 67002 | 67057 | pIn3 = &aMem[pOp->p3]; |
| 67003 | 67058 | applyNumericAffinity(pIn3); |
| 67004 | | - u.bb.iKey = sqlite3VdbeIntValue(pIn3); |
| 67005 | | - u.bb.pC->rowidIsValid = 0; |
| 67059 | + u.bc.iKey = sqlite3VdbeIntValue(pIn3); |
| 67060 | + u.bc.pC->rowidIsValid = 0; |
| 67006 | 67061 | |
| 67007 | 67062 | /* If the P3 value could not be converted into an integer without |
| 67008 | 67063 | ** loss of information, then special processing is required... */ |
| 67009 | 67064 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 67010 | 67065 | if( (pIn3->flags & MEM_Real)==0 ){ |
| | @@ -67015,105 +67070,105 @@ |
| 67015 | 67070 | } |
| 67016 | 67071 | /* If we reach this point, then the P3 value must be a floating |
| 67017 | 67072 | ** point number. */ |
| 67018 | 67073 | assert( (pIn3->flags & MEM_Real)!=0 ); |
| 67019 | 67074 | |
| 67020 | | - if( u.bb.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bb.iKey || pIn3->r>0) ){ |
| 67021 | | - /* The P3 value is too large in magnitude to be expressed as an |
| 67022 | | - ** integer. */ |
| 67023 | | - u.bb.res = 1; |
| 67024 | | - if( pIn3->r<0 ){ |
| 67025 | | - if( u.bb.oc>=OP_SeekGe ){ assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt ); |
| 67026 | | - rc = sqlite3BtreeFirst(u.bb.pC->pCursor, &u.bb.res); |
| 67027 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67028 | | - } |
| 67029 | | - }else{ |
| 67030 | | - if( u.bb.oc<=OP_SeekLe ){ assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe ); |
| 67031 | | - rc = sqlite3BtreeLast(u.bb.pC->pCursor, &u.bb.res); |
| 67032 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67033 | | - } |
| 67034 | | - } |
| 67035 | | - if( u.bb.res ){ |
| 67036 | | - pc = pOp->p2 - 1; |
| 67037 | | - } |
| 67038 | | - break; |
| 67039 | | - }else if( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekGe ){ |
| 67040 | | - /* Use the ceiling() function to convert real->int */ |
| 67041 | | - if( pIn3->r > (double)u.bb.iKey ) u.bb.iKey++; |
| 67042 | | - }else{ |
| 67043 | | - /* Use the floor() function to convert real->int */ |
| 67044 | | - assert( u.bb.oc==OP_SeekLe || u.bb.oc==OP_SeekGt ); |
| 67045 | | - if( pIn3->r < (double)u.bb.iKey ) u.bb.iKey--; |
| 67046 | | - } |
| 67047 | | - } |
| 67048 | | - rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, 0, (u64)u.bb.iKey, 0, &u.bb.res); |
| 67049 | | - if( rc!=SQLITE_OK ){ |
| 67050 | | - goto abort_due_to_error; |
| 67051 | | - } |
| 67052 | | - if( u.bb.res==0 ){ |
| 67053 | | - u.bb.pC->rowidIsValid = 1; |
| 67054 | | - u.bb.pC->lastRowid = u.bb.iKey; |
| 67055 | | - } |
| 67056 | | - }else{ |
| 67057 | | - u.bb.nField = pOp->p4.i; |
| 67058 | | - assert( pOp->p4type==P4_INT32 ); |
| 67059 | | - assert( u.bb.nField>0 ); |
| 67060 | | - u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo; |
| 67061 | | - u.bb.r.nField = (u16)u.bb.nField; |
| 67062 | | - |
| 67063 | | - /* The next line of code computes as follows, only faster: |
| 67064 | | - ** if( u.bb.oc==OP_SeekGt || u.bb.oc==OP_SeekLe ){ |
| 67065 | | - ** u.bb.r.flags = UNPACKED_INCRKEY; |
| 67066 | | - ** }else{ |
| 67067 | | - ** u.bb.r.flags = 0; |
| 67068 | | - ** } |
| 67069 | | - */ |
| 67070 | | - u.bb.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bb.oc - OP_SeekLt))); |
| 67071 | | - assert( u.bb.oc!=OP_SeekGt || u.bb.r.flags==UNPACKED_INCRKEY ); |
| 67072 | | - assert( u.bb.oc!=OP_SeekLe || u.bb.r.flags==UNPACKED_INCRKEY ); |
| 67073 | | - assert( u.bb.oc!=OP_SeekGe || u.bb.r.flags==0 ); |
| 67074 | | - assert( u.bb.oc!=OP_SeekLt || u.bb.r.flags==0 ); |
| 67075 | | - |
| 67076 | | - u.bb.r.aMem = &aMem[pOp->p3]; |
| 67077 | | -#ifdef SQLITE_DEBUG |
| 67078 | | - { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); } |
| 67079 | | -#endif |
| 67080 | | - ExpandBlob(u.bb.r.aMem); |
| 67081 | | - rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, &u.bb.r, 0, 0, &u.bb.res); |
| 67082 | | - if( rc!=SQLITE_OK ){ |
| 67083 | | - goto abort_due_to_error; |
| 67084 | | - } |
| 67085 | | - u.bb.pC->rowidIsValid = 0; |
| 67086 | | - } |
| 67087 | | - u.bb.pC->deferredMoveto = 0; |
| 67088 | | - u.bb.pC->cacheStatus = CACHE_STALE; |
| 67089 | | -#ifdef SQLITE_TEST |
| 67090 | | - sqlite3_search_count++; |
| 67091 | | -#endif |
| 67092 | | - if( u.bb.oc>=OP_SeekGe ){ assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt ); |
| 67093 | | - if( u.bb.res<0 || (u.bb.res==0 && u.bb.oc==OP_SeekGt) ){ |
| 67094 | | - rc = sqlite3BtreeNext(u.bb.pC->pCursor, &u.bb.res); |
| 67095 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67096 | | - u.bb.pC->rowidIsValid = 0; |
| 67097 | | - }else{ |
| 67098 | | - u.bb.res = 0; |
| 67099 | | - } |
| 67100 | | - }else{ |
| 67101 | | - assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe ); |
| 67102 | | - if( u.bb.res>0 || (u.bb.res==0 && u.bb.oc==OP_SeekLt) ){ |
| 67103 | | - rc = sqlite3BtreePrevious(u.bb.pC->pCursor, &u.bb.res); |
| 67104 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67105 | | - u.bb.pC->rowidIsValid = 0; |
| 67106 | | - }else{ |
| 67107 | | - /* u.bb.res might be negative because the table is empty. Check to |
| 67108 | | - ** see if this is the case. |
| 67109 | | - */ |
| 67110 | | - u.bb.res = sqlite3BtreeEof(u.bb.pC->pCursor); |
| 67111 | | - } |
| 67112 | | - } |
| 67113 | | - assert( pOp->p2>0 ); |
| 67114 | | - if( u.bb.res ){ |
| 67075 | + if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){ |
| 67076 | + /* The P3 value is too large in magnitude to be expressed as an |
| 67077 | + ** integer. */ |
| 67078 | + u.bc.res = 1; |
| 67079 | + if( pIn3->r<0 ){ |
| 67080 | + if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt ); |
| 67081 | + rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res); |
| 67082 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67083 | + } |
| 67084 | + }else{ |
| 67085 | + if( u.bc.oc<=OP_SeekLe ){ assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ); |
| 67086 | + rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res); |
| 67087 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67088 | + } |
| 67089 | + } |
| 67090 | + if( u.bc.res ){ |
| 67091 | + pc = pOp->p2 - 1; |
| 67092 | + } |
| 67093 | + break; |
| 67094 | + }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){ |
| 67095 | + /* Use the ceiling() function to convert real->int */ |
| 67096 | + if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++; |
| 67097 | + }else{ |
| 67098 | + /* Use the floor() function to convert real->int */ |
| 67099 | + assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt ); |
| 67100 | + if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--; |
| 67101 | + } |
| 67102 | + } |
| 67103 | + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res); |
| 67104 | + if( rc!=SQLITE_OK ){ |
| 67105 | + goto abort_due_to_error; |
| 67106 | + } |
| 67107 | + if( u.bc.res==0 ){ |
| 67108 | + u.bc.pC->rowidIsValid = 1; |
| 67109 | + u.bc.pC->lastRowid = u.bc.iKey; |
| 67110 | + } |
| 67111 | + }else{ |
| 67112 | + u.bc.nField = pOp->p4.i; |
| 67113 | + assert( pOp->p4type==P4_INT32 ); |
| 67114 | + assert( u.bc.nField>0 ); |
| 67115 | + u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; |
| 67116 | + u.bc.r.nField = (u16)u.bc.nField; |
| 67117 | + |
| 67118 | + /* The next line of code computes as follows, only faster: |
| 67119 | + ** if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){ |
| 67120 | + ** u.bc.r.flags = UNPACKED_INCRKEY; |
| 67121 | + ** }else{ |
| 67122 | + ** u.bc.r.flags = 0; |
| 67123 | + ** } |
| 67124 | + */ |
| 67125 | + u.bc.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt))); |
| 67126 | + assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY ); |
| 67127 | + assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY ); |
| 67128 | + assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 ); |
| 67129 | + assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 ); |
| 67130 | + |
| 67131 | + u.bc.r.aMem = &aMem[pOp->p3]; |
| 67132 | +#ifdef SQLITE_DEBUG |
| 67133 | + { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } |
| 67134 | +#endif |
| 67135 | + ExpandBlob(u.bc.r.aMem); |
| 67136 | + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res); |
| 67137 | + if( rc!=SQLITE_OK ){ |
| 67138 | + goto abort_due_to_error; |
| 67139 | + } |
| 67140 | + u.bc.pC->rowidIsValid = 0; |
| 67141 | + } |
| 67142 | + u.bc.pC->deferredMoveto = 0; |
| 67143 | + u.bc.pC->cacheStatus = CACHE_STALE; |
| 67144 | +#ifdef SQLITE_TEST |
| 67145 | + sqlite3_search_count++; |
| 67146 | +#endif |
| 67147 | + if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt ); |
| 67148 | + if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){ |
| 67149 | + rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res); |
| 67150 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67151 | + u.bc.pC->rowidIsValid = 0; |
| 67152 | + }else{ |
| 67153 | + u.bc.res = 0; |
| 67154 | + } |
| 67155 | + }else{ |
| 67156 | + assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ); |
| 67157 | + if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){ |
| 67158 | + rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res); |
| 67159 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67160 | + u.bc.pC->rowidIsValid = 0; |
| 67161 | + }else{ |
| 67162 | + /* u.bc.res might be negative because the table is empty. Check to |
| 67163 | + ** see if this is the case. |
| 67164 | + */ |
| 67165 | + u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor); |
| 67166 | + } |
| 67167 | + } |
| 67168 | + assert( pOp->p2>0 ); |
| 67169 | + if( u.bc.res ){ |
| 67115 | 67170 | pc = pOp->p2 - 1; |
| 67116 | 67171 | } |
| 67117 | 67172 | }else{ |
| 67118 | 67173 | /* This happens when attempting to open the sqlite3_master table |
| 67119 | 67174 | ** for read access returns SQLITE_EMPTY. In this case always |
| | @@ -67132,24 +67187,24 @@ |
| 67132 | 67187 | ** This is actually a deferred seek. Nothing actually happens until |
| 67133 | 67188 | ** the cursor is used to read a record. That way, if no reads |
| 67134 | 67189 | ** occur, no unnecessary I/O happens. |
| 67135 | 67190 | */ |
| 67136 | 67191 | case OP_Seek: { /* in2 */ |
| 67137 | | -#if 0 /* local variables moved into u.bc */ |
| 67192 | +#if 0 /* local variables moved into u.bd */ |
| 67138 | 67193 | VdbeCursor *pC; |
| 67139 | | -#endif /* local variables moved into u.bc */ |
| 67194 | +#endif /* local variables moved into u.bd */ |
| 67140 | 67195 | |
| 67141 | 67196 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67142 | | - u.bc.pC = p->apCsr[pOp->p1]; |
| 67143 | | - assert( u.bc.pC!=0 ); |
| 67144 | | - if( ALWAYS(u.bc.pC->pCursor!=0) ){ |
| 67145 | | - assert( u.bc.pC->isTable ); |
| 67146 | | - u.bc.pC->nullRow = 0; |
| 67197 | + u.bd.pC = p->apCsr[pOp->p1]; |
| 67198 | + assert( u.bd.pC!=0 ); |
| 67199 | + if( ALWAYS(u.bd.pC->pCursor!=0) ){ |
| 67200 | + assert( u.bd.pC->isTable ); |
| 67201 | + u.bd.pC->nullRow = 0; |
| 67147 | 67202 | pIn2 = &aMem[pOp->p2]; |
| 67148 | | - u.bc.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67149 | | - u.bc.pC->rowidIsValid = 0; |
| 67150 | | - u.bc.pC->deferredMoveto = 1; |
| 67203 | + u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67204 | + u.bd.pC->rowidIsValid = 0; |
| 67205 | + u.bd.pC->deferredMoveto = 1; |
| 67151 | 67206 | } |
| 67152 | 67207 | break; |
| 67153 | 67208 | } |
| 67154 | 67209 | |
| 67155 | 67210 | |
| | @@ -67177,67 +67232,67 @@ |
| 67177 | 67232 | ** |
| 67178 | 67233 | ** See also: Found, NotExists, IsUnique |
| 67179 | 67234 | */ |
| 67180 | 67235 | case OP_NotFound: /* jump, in3 */ |
| 67181 | 67236 | case OP_Found: { /* jump, in3 */ |
| 67182 | | -#if 0 /* local variables moved into u.bd */ |
| 67237 | +#if 0 /* local variables moved into u.be */ |
| 67183 | 67238 | int alreadyExists; |
| 67184 | 67239 | VdbeCursor *pC; |
| 67185 | 67240 | int res; |
| 67186 | 67241 | char *pFree; |
| 67187 | 67242 | UnpackedRecord *pIdxKey; |
| 67188 | 67243 | UnpackedRecord r; |
| 67189 | 67244 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 67190 | | -#endif /* local variables moved into u.bd */ |
| 67245 | +#endif /* local variables moved into u.be */ |
| 67191 | 67246 | |
| 67192 | 67247 | #ifdef SQLITE_TEST |
| 67193 | 67248 | sqlite3_found_count++; |
| 67194 | 67249 | #endif |
| 67195 | 67250 | |
| 67196 | | - u.bd.alreadyExists = 0; |
| 67251 | + u.be.alreadyExists = 0; |
| 67197 | 67252 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67198 | 67253 | assert( pOp->p4type==P4_INT32 ); |
| 67199 | | - u.bd.pC = p->apCsr[pOp->p1]; |
| 67200 | | - assert( u.bd.pC!=0 ); |
| 67254 | + u.be.pC = p->apCsr[pOp->p1]; |
| 67255 | + assert( u.be.pC!=0 ); |
| 67201 | 67256 | pIn3 = &aMem[pOp->p3]; |
| 67202 | | - if( ALWAYS(u.bd.pC->pCursor!=0) ){ |
| 67257 | + if( ALWAYS(u.be.pC->pCursor!=0) ){ |
| 67203 | 67258 | |
| 67204 | | - assert( u.bd.pC->isTable==0 ); |
| 67259 | + assert( u.be.pC->isTable==0 ); |
| 67205 | 67260 | if( pOp->p4.i>0 ){ |
| 67206 | | - u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo; |
| 67207 | | - u.bd.r.nField = (u16)pOp->p4.i; |
| 67208 | | - u.bd.r.aMem = pIn3; |
| 67261 | + u.be.r.pKeyInfo = u.be.pC->pKeyInfo; |
| 67262 | + u.be.r.nField = (u16)pOp->p4.i; |
| 67263 | + u.be.r.aMem = pIn3; |
| 67209 | 67264 | #ifdef SQLITE_DEBUG |
| 67210 | | - { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } |
| 67265 | + { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); } |
| 67211 | 67266 | #endif |
| 67212 | | - u.bd.r.flags = UNPACKED_PREFIX_MATCH; |
| 67213 | | - u.bd.pIdxKey = &u.bd.r; |
| 67267 | + u.be.r.flags = UNPACKED_PREFIX_MATCH; |
| 67268 | + u.be.pIdxKey = &u.be.r; |
| 67214 | 67269 | }else{ |
| 67215 | | - u.bd.pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 67216 | | - u.bd.pC->pKeyInfo, u.bd.aTempRec, sizeof(u.bd.aTempRec), &u.bd.pFree |
| 67270 | + u.be.pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 67271 | + u.be.pC->pKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree |
| 67217 | 67272 | ); |
| 67218 | | - if( u.bd.pIdxKey==0 ) goto no_mem; |
| 67273 | + if( u.be.pIdxKey==0 ) goto no_mem; |
| 67219 | 67274 | assert( pIn3->flags & MEM_Blob ); |
| 67220 | 67275 | assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ |
| 67221 | | - sqlite3VdbeRecordUnpack(u.bd.pC->pKeyInfo, pIn3->n, pIn3->z, u.bd.pIdxKey); |
| 67222 | | - u.bd.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 67276 | + sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey); |
| 67277 | + u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 67223 | 67278 | } |
| 67224 | | - rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, u.bd.pIdxKey, 0, 0, &u.bd.res); |
| 67279 | + rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res); |
| 67225 | 67280 | if( pOp->p4.i==0 ){ |
| 67226 | | - sqlite3DbFree(db, u.bd.pFree); |
| 67281 | + sqlite3DbFree(db, u.be.pFree); |
| 67227 | 67282 | } |
| 67228 | 67283 | if( rc!=SQLITE_OK ){ |
| 67229 | 67284 | break; |
| 67230 | 67285 | } |
| 67231 | | - u.bd.alreadyExists = (u.bd.res==0); |
| 67232 | | - u.bd.pC->deferredMoveto = 0; |
| 67233 | | - u.bd.pC->cacheStatus = CACHE_STALE; |
| 67286 | + u.be.alreadyExists = (u.be.res==0); |
| 67287 | + u.be.pC->deferredMoveto = 0; |
| 67288 | + u.be.pC->cacheStatus = CACHE_STALE; |
| 67234 | 67289 | } |
| 67235 | 67290 | if( pOp->opcode==OP_Found ){ |
| 67236 | | - if( u.bd.alreadyExists ) pc = pOp->p2 - 1; |
| 67291 | + if( u.be.alreadyExists ) pc = pOp->p2 - 1; |
| 67237 | 67292 | }else{ |
| 67238 | | - if( !u.bd.alreadyExists ) pc = pOp->p2 - 1; |
| 67293 | + if( !u.be.alreadyExists ) pc = pOp->p2 - 1; |
| 67239 | 67294 | } |
| 67240 | 67295 | break; |
| 67241 | 67296 | } |
| 67242 | 67297 | |
| 67243 | 67298 | /* Opcode: IsUnique P1 P2 P3 P4 * |
| | @@ -67265,67 +67320,67 @@ |
| 67265 | 67320 | ** instruction. |
| 67266 | 67321 | ** |
| 67267 | 67322 | ** See also: NotFound, NotExists, Found |
| 67268 | 67323 | */ |
| 67269 | 67324 | case OP_IsUnique: { /* jump, in3 */ |
| 67270 | | -#if 0 /* local variables moved into u.be */ |
| 67325 | +#if 0 /* local variables moved into u.bf */ |
| 67271 | 67326 | u16 ii; |
| 67272 | 67327 | VdbeCursor *pCx; |
| 67273 | 67328 | BtCursor *pCrsr; |
| 67274 | 67329 | u16 nField; |
| 67275 | 67330 | Mem *aMx; |
| 67276 | 67331 | UnpackedRecord r; /* B-Tree index search key */ |
| 67277 | 67332 | i64 R; /* Rowid stored in register P3 */ |
| 67278 | | -#endif /* local variables moved into u.be */ |
| 67333 | +#endif /* local variables moved into u.bf */ |
| 67279 | 67334 | |
| 67280 | 67335 | pIn3 = &aMem[pOp->p3]; |
| 67281 | | - u.be.aMx = &aMem[pOp->p4.i]; |
| 67336 | + u.bf.aMx = &aMem[pOp->p4.i]; |
| 67282 | 67337 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 67283 | 67338 | assert( pOp->p4type==P4_INT32 ); |
| 67284 | 67339 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 67285 | 67340 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67286 | 67341 | |
| 67287 | 67342 | /* Find the index cursor. */ |
| 67288 | | - u.be.pCx = p->apCsr[pOp->p1]; |
| 67289 | | - assert( u.be.pCx->deferredMoveto==0 ); |
| 67290 | | - u.be.pCx->seekResult = 0; |
| 67291 | | - u.be.pCx->cacheStatus = CACHE_STALE; |
| 67292 | | - u.be.pCrsr = u.be.pCx->pCursor; |
| 67343 | + u.bf.pCx = p->apCsr[pOp->p1]; |
| 67344 | + assert( u.bf.pCx->deferredMoveto==0 ); |
| 67345 | + u.bf.pCx->seekResult = 0; |
| 67346 | + u.bf.pCx->cacheStatus = CACHE_STALE; |
| 67347 | + u.bf.pCrsr = u.bf.pCx->pCursor; |
| 67293 | 67348 | |
| 67294 | 67349 | /* If any of the values are NULL, take the jump. */ |
| 67295 | | - u.be.nField = u.be.pCx->pKeyInfo->nField; |
| 67296 | | - for(u.be.ii=0; u.be.ii<u.be.nField; u.be.ii++){ |
| 67297 | | - if( u.be.aMx[u.be.ii].flags & MEM_Null ){ |
| 67350 | + u.bf.nField = u.bf.pCx->pKeyInfo->nField; |
| 67351 | + for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){ |
| 67352 | + if( u.bf.aMx[u.bf.ii].flags & MEM_Null ){ |
| 67298 | 67353 | pc = pOp->p2 - 1; |
| 67299 | | - u.be.pCrsr = 0; |
| 67354 | + u.bf.pCrsr = 0; |
| 67300 | 67355 | break; |
| 67301 | 67356 | } |
| 67302 | 67357 | } |
| 67303 | | - assert( (u.be.aMx[u.be.nField].flags & MEM_Null)==0 ); |
| 67358 | + assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 ); |
| 67304 | 67359 | |
| 67305 | | - if( u.be.pCrsr!=0 ){ |
| 67360 | + if( u.bf.pCrsr!=0 ){ |
| 67306 | 67361 | /* Populate the index search key. */ |
| 67307 | | - u.be.r.pKeyInfo = u.be.pCx->pKeyInfo; |
| 67308 | | - u.be.r.nField = u.be.nField + 1; |
| 67309 | | - u.be.r.flags = UNPACKED_PREFIX_SEARCH; |
| 67310 | | - u.be.r.aMem = u.be.aMx; |
| 67362 | + u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo; |
| 67363 | + u.bf.r.nField = u.bf.nField + 1; |
| 67364 | + u.bf.r.flags = UNPACKED_PREFIX_SEARCH; |
| 67365 | + u.bf.r.aMem = u.bf.aMx; |
| 67311 | 67366 | #ifdef SQLITE_DEBUG |
| 67312 | | - { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); } |
| 67367 | + { int i; for(i=0; i<u.bf.r.nField; i++) assert( memIsValid(&u.bf.r.aMem[i]) ); } |
| 67313 | 67368 | #endif |
| 67314 | 67369 | |
| 67315 | | - /* Extract the value of u.be.R from register P3. */ |
| 67370 | + /* Extract the value of u.bf.R from register P3. */ |
| 67316 | 67371 | sqlite3VdbeMemIntegerify(pIn3); |
| 67317 | | - u.be.R = pIn3->u.i; |
| 67372 | + u.bf.R = pIn3->u.i; |
| 67318 | 67373 | |
| 67319 | 67374 | /* Search the B-Tree index. If no conflicting record is found, jump |
| 67320 | 67375 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
| 67321 | 67376 | ** register P3 and fall through to the next instruction. */ |
| 67322 | | - rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, &u.be.r, 0, 0, &u.be.pCx->seekResult); |
| 67323 | | - if( (u.be.r.flags & UNPACKED_PREFIX_SEARCH) || u.be.r.rowid==u.be.R ){ |
| 67377 | + rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult); |
| 67378 | + if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){ |
| 67324 | 67379 | pc = pOp->p2 - 1; |
| 67325 | 67380 | }else{ |
| 67326 | | - pIn3->u.i = u.be.r.rowid; |
| 67381 | + pIn3->u.i = u.bf.r.rowid; |
| 67327 | 67382 | } |
| 67328 | 67383 | } |
| 67329 | 67384 | break; |
| 67330 | 67385 | } |
| 67331 | 67386 | |
| | @@ -67342,46 +67397,46 @@ |
| 67342 | 67397 | ** P1 is an index. |
| 67343 | 67398 | ** |
| 67344 | 67399 | ** See also: Found, NotFound, IsUnique |
| 67345 | 67400 | */ |
| 67346 | 67401 | case OP_NotExists: { /* jump, in3 */ |
| 67347 | | -#if 0 /* local variables moved into u.bf */ |
| 67402 | +#if 0 /* local variables moved into u.bg */ |
| 67348 | 67403 | VdbeCursor *pC; |
| 67349 | 67404 | BtCursor *pCrsr; |
| 67350 | 67405 | int res; |
| 67351 | 67406 | u64 iKey; |
| 67352 | | -#endif /* local variables moved into u.bf */ |
| 67407 | +#endif /* local variables moved into u.bg */ |
| 67353 | 67408 | |
| 67354 | 67409 | pIn3 = &aMem[pOp->p3]; |
| 67355 | 67410 | assert( pIn3->flags & MEM_Int ); |
| 67356 | 67411 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67357 | | - u.bf.pC = p->apCsr[pOp->p1]; |
| 67358 | | - assert( u.bf.pC!=0 ); |
| 67359 | | - assert( u.bf.pC->isTable ); |
| 67360 | | - assert( u.bf.pC->pseudoTableReg==0 ); |
| 67361 | | - u.bf.pCrsr = u.bf.pC->pCursor; |
| 67362 | | - if( ALWAYS(u.bf.pCrsr!=0) ){ |
| 67363 | | - u.bf.res = 0; |
| 67364 | | - u.bf.iKey = pIn3->u.i; |
| 67365 | | - rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, 0, u.bf.iKey, 0, &u.bf.res); |
| 67366 | | - u.bf.pC->lastRowid = pIn3->u.i; |
| 67367 | | - u.bf.pC->rowidIsValid = u.bf.res==0 ?1:0; |
| 67368 | | - u.bf.pC->nullRow = 0; |
| 67369 | | - u.bf.pC->cacheStatus = CACHE_STALE; |
| 67370 | | - u.bf.pC->deferredMoveto = 0; |
| 67371 | | - if( u.bf.res!=0 ){ |
| 67412 | + u.bg.pC = p->apCsr[pOp->p1]; |
| 67413 | + assert( u.bg.pC!=0 ); |
| 67414 | + assert( u.bg.pC->isTable ); |
| 67415 | + assert( u.bg.pC->pseudoTableReg==0 ); |
| 67416 | + u.bg.pCrsr = u.bg.pC->pCursor; |
| 67417 | + if( ALWAYS(u.bg.pCrsr!=0) ){ |
| 67418 | + u.bg.res = 0; |
| 67419 | + u.bg.iKey = pIn3->u.i; |
| 67420 | + rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res); |
| 67421 | + u.bg.pC->lastRowid = pIn3->u.i; |
| 67422 | + u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0; |
| 67423 | + u.bg.pC->nullRow = 0; |
| 67424 | + u.bg.pC->cacheStatus = CACHE_STALE; |
| 67425 | + u.bg.pC->deferredMoveto = 0; |
| 67426 | + if( u.bg.res!=0 ){ |
| 67372 | 67427 | pc = pOp->p2 - 1; |
| 67373 | | - assert( u.bf.pC->rowidIsValid==0 ); |
| 67428 | + assert( u.bg.pC->rowidIsValid==0 ); |
| 67374 | 67429 | } |
| 67375 | | - u.bf.pC->seekResult = u.bf.res; |
| 67430 | + u.bg.pC->seekResult = u.bg.res; |
| 67376 | 67431 | }else{ |
| 67377 | 67432 | /* This happens when an attempt to open a read cursor on the |
| 67378 | 67433 | ** sqlite_master table returns SQLITE_EMPTY. |
| 67379 | 67434 | */ |
| 67380 | 67435 | pc = pOp->p2 - 1; |
| 67381 | | - assert( u.bf.pC->rowidIsValid==0 ); |
| 67382 | | - u.bf.pC->seekResult = 0; |
| 67436 | + assert( u.bg.pC->rowidIsValid==0 ); |
| 67437 | + u.bg.pC->seekResult = 0; |
| 67383 | 67438 | } |
| 67384 | 67439 | break; |
| 67385 | 67440 | } |
| 67386 | 67441 | |
| 67387 | 67442 | /* Opcode: Sequence P1 P2 * * * |
| | @@ -67412,25 +67467,25 @@ |
| 67412 | 67467 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 67413 | 67468 | ** generated record number. This P3 mechanism is used to help implement the |
| 67414 | 67469 | ** AUTOINCREMENT feature. |
| 67415 | 67470 | */ |
| 67416 | 67471 | case OP_NewRowid: { /* out2-prerelease */ |
| 67417 | | -#if 0 /* local variables moved into u.bg */ |
| 67472 | +#if 0 /* local variables moved into u.bh */ |
| 67418 | 67473 | i64 v; /* The new rowid */ |
| 67419 | 67474 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 67420 | 67475 | int res; /* Result of an sqlite3BtreeLast() */ |
| 67421 | 67476 | int cnt; /* Counter to limit the number of searches */ |
| 67422 | 67477 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 67423 | 67478 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 67424 | | -#endif /* local variables moved into u.bg */ |
| 67479 | +#endif /* local variables moved into u.bh */ |
| 67425 | 67480 | |
| 67426 | | - u.bg.v = 0; |
| 67427 | | - u.bg.res = 0; |
| 67481 | + u.bh.v = 0; |
| 67482 | + u.bh.res = 0; |
| 67428 | 67483 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67429 | | - u.bg.pC = p->apCsr[pOp->p1]; |
| 67430 | | - assert( u.bg.pC!=0 ); |
| 67431 | | - if( NEVER(u.bg.pC->pCursor==0) ){ |
| 67484 | + u.bh.pC = p->apCsr[pOp->p1]; |
| 67485 | + assert( u.bh.pC!=0 ); |
| 67486 | + if( NEVER(u.bh.pC->pCursor==0) ){ |
| 67432 | 67487 | /* The zero initialization above is all that is needed */ |
| 67433 | 67488 | }else{ |
| 67434 | 67489 | /* The next rowid or record number (different terms for the same |
| 67435 | 67490 | ** thing) is obtained in a two-step algorithm. |
| 67436 | 67491 | ** |
| | @@ -67442,11 +67497,11 @@ |
| 67442 | 67497 | ** The second algorithm is to select a rowid at random and see if |
| 67443 | 67498 | ** it already exists in the table. If it does not exist, we have |
| 67444 | 67499 | ** succeeded. If the random rowid does exist, we select a new one |
| 67445 | 67500 | ** and try again, up to 100 times. |
| 67446 | 67501 | */ |
| 67447 | | - assert( u.bg.pC->isTable ); |
| 67502 | + assert( u.bh.pC->isTable ); |
| 67448 | 67503 | |
| 67449 | 67504 | #ifdef SQLITE_32BIT_ROWID |
| 67450 | 67505 | # define MAX_ROWID 0x7fffffff |
| 67451 | 67506 | #else |
| 67452 | 67507 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| | @@ -67454,101 +67509,101 @@ |
| 67454 | 67509 | ** to provide the constant while making all compilers happy. |
| 67455 | 67510 | */ |
| 67456 | 67511 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 67457 | 67512 | #endif |
| 67458 | 67513 | |
| 67459 | | - if( !u.bg.pC->useRandomRowid ){ |
| 67460 | | - u.bg.v = sqlite3BtreeGetCachedRowid(u.bg.pC->pCursor); |
| 67461 | | - if( u.bg.v==0 ){ |
| 67462 | | - rc = sqlite3BtreeLast(u.bg.pC->pCursor, &u.bg.res); |
| 67514 | + if( !u.bh.pC->useRandomRowid ){ |
| 67515 | + u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor); |
| 67516 | + if( u.bh.v==0 ){ |
| 67517 | + rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res); |
| 67463 | 67518 | if( rc!=SQLITE_OK ){ |
| 67464 | 67519 | goto abort_due_to_error; |
| 67465 | 67520 | } |
| 67466 | | - if( u.bg.res ){ |
| 67467 | | - u.bg.v = 1; /* IMP: R-61914-48074 */ |
| 67521 | + if( u.bh.res ){ |
| 67522 | + u.bh.v = 1; /* IMP: R-61914-48074 */ |
| 67468 | 67523 | }else{ |
| 67469 | | - assert( sqlite3BtreeCursorIsValid(u.bg.pC->pCursor) ); |
| 67470 | | - rc = sqlite3BtreeKeySize(u.bg.pC->pCursor, &u.bg.v); |
| 67524 | + assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) ); |
| 67525 | + rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v); |
| 67471 | 67526 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 67472 | | - if( u.bg.v>=MAX_ROWID ){ |
| 67473 | | - u.bg.pC->useRandomRowid = 1; |
| 67527 | + if( u.bh.v>=MAX_ROWID ){ |
| 67528 | + u.bh.pC->useRandomRowid = 1; |
| 67474 | 67529 | }else{ |
| 67475 | | - u.bg.v++; /* IMP: R-29538-34987 */ |
| 67530 | + u.bh.v++; /* IMP: R-29538-34987 */ |
| 67476 | 67531 | } |
| 67477 | 67532 | } |
| 67478 | 67533 | } |
| 67479 | 67534 | |
| 67480 | 67535 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 67481 | 67536 | if( pOp->p3 ){ |
| 67482 | 67537 | /* Assert that P3 is a valid memory cell. */ |
| 67483 | 67538 | assert( pOp->p3>0 ); |
| 67484 | 67539 | if( p->pFrame ){ |
| 67485 | | - for(u.bg.pFrame=p->pFrame; u.bg.pFrame->pParent; u.bg.pFrame=u.bg.pFrame->pParent); |
| 67540 | + for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent); |
| 67486 | 67541 | /* Assert that P3 is a valid memory cell. */ |
| 67487 | | - assert( pOp->p3<=u.bg.pFrame->nMem ); |
| 67488 | | - u.bg.pMem = &u.bg.pFrame->aMem[pOp->p3]; |
| 67542 | + assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 67543 | + u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 67489 | 67544 | }else{ |
| 67490 | 67545 | /* Assert that P3 is a valid memory cell. */ |
| 67491 | 67546 | assert( pOp->p3<=p->nMem ); |
| 67492 | | - u.bg.pMem = &aMem[pOp->p3]; |
| 67493 | | - memAboutToChange(p, u.bg.pMem); |
| 67494 | | - } |
| 67495 | | - assert( memIsValid(u.bg.pMem) ); |
| 67496 | | - |
| 67497 | | - REGISTER_TRACE(pOp->p3, u.bg.pMem); |
| 67498 | | - sqlite3VdbeMemIntegerify(u.bg.pMem); |
| 67499 | | - assert( (u.bg.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 67500 | | - if( u.bg.pMem->u.i==MAX_ROWID || u.bg.pC->useRandomRowid ){ |
| 67547 | + u.bh.pMem = &aMem[pOp->p3]; |
| 67548 | + memAboutToChange(p, u.bh.pMem); |
| 67549 | + } |
| 67550 | + assert( memIsValid(u.bh.pMem) ); |
| 67551 | + |
| 67552 | + REGISTER_TRACE(pOp->p3, u.bh.pMem); |
| 67553 | + sqlite3VdbeMemIntegerify(u.bh.pMem); |
| 67554 | + assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 67555 | + if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){ |
| 67501 | 67556 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 67502 | 67557 | goto abort_due_to_error; |
| 67503 | 67558 | } |
| 67504 | | - if( u.bg.v<u.bg.pMem->u.i+1 ){ |
| 67505 | | - u.bg.v = u.bg.pMem->u.i + 1; |
| 67559 | + if( u.bh.v<u.bh.pMem->u.i+1 ){ |
| 67560 | + u.bh.v = u.bh.pMem->u.i + 1; |
| 67506 | 67561 | } |
| 67507 | | - u.bg.pMem->u.i = u.bg.v; |
| 67562 | + u.bh.pMem->u.i = u.bh.v; |
| 67508 | 67563 | } |
| 67509 | 67564 | #endif |
| 67510 | 67565 | |
| 67511 | | - sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, u.bg.v<MAX_ROWID ? u.bg.v+1 : 0); |
| 67566 | + sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0); |
| 67512 | 67567 | } |
| 67513 | | - if( u.bg.pC->useRandomRowid ){ |
| 67568 | + if( u.bh.pC->useRandomRowid ){ |
| 67514 | 67569 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 67515 | 67570 | ** largest possible integer (9223372036854775807) then the database |
| 67516 | 67571 | ** engine starts picking positive candidate ROWIDs at random until |
| 67517 | 67572 | ** it finds one that is not previously used. */ |
| 67518 | 67573 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 67519 | 67574 | ** an AUTOINCREMENT table. */ |
| 67520 | 67575 | /* on the first attempt, simply do one more than previous */ |
| 67521 | | - u.bg.v = lastRowid; |
| 67522 | | - u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67523 | | - u.bg.v++; /* ensure non-zero */ |
| 67524 | | - u.bg.cnt = 0; |
| 67525 | | - while( ((rc = sqlite3BtreeMovetoUnpacked(u.bg.pC->pCursor, 0, (u64)u.bg.v, |
| 67526 | | - 0, &u.bg.res))==SQLITE_OK) |
| 67527 | | - && (u.bg.res==0) |
| 67528 | | - && (++u.bg.cnt<100)){ |
| 67576 | + u.bh.v = lastRowid; |
| 67577 | + u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67578 | + u.bh.v++; /* ensure non-zero */ |
| 67579 | + u.bh.cnt = 0; |
| 67580 | + while( ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v, |
| 67581 | + 0, &u.bh.res))==SQLITE_OK) |
| 67582 | + && (u.bh.res==0) |
| 67583 | + && (++u.bh.cnt<100)){ |
| 67529 | 67584 | /* collision - try another random rowid */ |
| 67530 | | - sqlite3_randomness(sizeof(u.bg.v), &u.bg.v); |
| 67531 | | - if( u.bg.cnt<5 ){ |
| 67585 | + sqlite3_randomness(sizeof(u.bh.v), &u.bh.v); |
| 67586 | + if( u.bh.cnt<5 ){ |
| 67532 | 67587 | /* try "small" random rowids for the initial attempts */ |
| 67533 | | - u.bg.v &= 0xffffff; |
| 67588 | + u.bh.v &= 0xffffff; |
| 67534 | 67589 | }else{ |
| 67535 | | - u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67590 | + u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67536 | 67591 | } |
| 67537 | | - u.bg.v++; /* ensure non-zero */ |
| 67592 | + u.bh.v++; /* ensure non-zero */ |
| 67538 | 67593 | } |
| 67539 | | - if( rc==SQLITE_OK && u.bg.res==0 ){ |
| 67594 | + if( rc==SQLITE_OK && u.bh.res==0 ){ |
| 67540 | 67595 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 67541 | 67596 | goto abort_due_to_error; |
| 67542 | 67597 | } |
| 67543 | | - assert( u.bg.v>0 ); /* EV: R-40812-03570 */ |
| 67598 | + assert( u.bh.v>0 ); /* EV: R-40812-03570 */ |
| 67544 | 67599 | } |
| 67545 | | - u.bg.pC->rowidIsValid = 0; |
| 67546 | | - u.bg.pC->deferredMoveto = 0; |
| 67547 | | - u.bg.pC->cacheStatus = CACHE_STALE; |
| 67600 | + u.bh.pC->rowidIsValid = 0; |
| 67601 | + u.bh.pC->deferredMoveto = 0; |
| 67602 | + u.bh.pC->cacheStatus = CACHE_STALE; |
| 67548 | 67603 | } |
| 67549 | | - pOut->u.i = u.bg.v; |
| 67604 | + pOut->u.i = u.bh.v; |
| 67550 | 67605 | break; |
| 67551 | 67606 | } |
| 67552 | 67607 | |
| 67553 | 67608 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 67554 | 67609 | ** |
| | @@ -67594,74 +67649,74 @@ |
| 67594 | 67649 | ** This works exactly like OP_Insert except that the key is the |
| 67595 | 67650 | ** integer value P3, not the value of the integer stored in register P3. |
| 67596 | 67651 | */ |
| 67597 | 67652 | case OP_Insert: |
| 67598 | 67653 | case OP_InsertInt: { |
| 67599 | | -#if 0 /* local variables moved into u.bh */ |
| 67654 | +#if 0 /* local variables moved into u.bi */ |
| 67600 | 67655 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 67601 | 67656 | Mem *pKey; /* MEM cell holding key for the record */ |
| 67602 | 67657 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 67603 | 67658 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 67604 | 67659 | int nZero; /* Number of zero-bytes to append */ |
| 67605 | 67660 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 67606 | 67661 | const char *zDb; /* database name - used by the update hook */ |
| 67607 | 67662 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 67608 | 67663 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 67609 | | -#endif /* local variables moved into u.bh */ |
| 67664 | +#endif /* local variables moved into u.bi */ |
| 67610 | 67665 | |
| 67611 | | - u.bh.pData = &aMem[pOp->p2]; |
| 67666 | + u.bi.pData = &aMem[pOp->p2]; |
| 67612 | 67667 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67613 | | - assert( memIsValid(u.bh.pData) ); |
| 67614 | | - u.bh.pC = p->apCsr[pOp->p1]; |
| 67615 | | - assert( u.bh.pC!=0 ); |
| 67616 | | - assert( u.bh.pC->pCursor!=0 ); |
| 67617 | | - assert( u.bh.pC->pseudoTableReg==0 ); |
| 67618 | | - assert( u.bh.pC->isTable ); |
| 67619 | | - REGISTER_TRACE(pOp->p2, u.bh.pData); |
| 67668 | + assert( memIsValid(u.bi.pData) ); |
| 67669 | + u.bi.pC = p->apCsr[pOp->p1]; |
| 67670 | + assert( u.bi.pC!=0 ); |
| 67671 | + assert( u.bi.pC->pCursor!=0 ); |
| 67672 | + assert( u.bi.pC->pseudoTableReg==0 ); |
| 67673 | + assert( u.bi.pC->isTable ); |
| 67674 | + REGISTER_TRACE(pOp->p2, u.bi.pData); |
| 67620 | 67675 | |
| 67621 | 67676 | if( pOp->opcode==OP_Insert ){ |
| 67622 | | - u.bh.pKey = &aMem[pOp->p3]; |
| 67623 | | - assert( u.bh.pKey->flags & MEM_Int ); |
| 67624 | | - assert( memIsValid(u.bh.pKey) ); |
| 67625 | | - REGISTER_TRACE(pOp->p3, u.bh.pKey); |
| 67626 | | - u.bh.iKey = u.bh.pKey->u.i; |
| 67677 | + u.bi.pKey = &aMem[pOp->p3]; |
| 67678 | + assert( u.bi.pKey->flags & MEM_Int ); |
| 67679 | + assert( memIsValid(u.bi.pKey) ); |
| 67680 | + REGISTER_TRACE(pOp->p3, u.bi.pKey); |
| 67681 | + u.bi.iKey = u.bi.pKey->u.i; |
| 67627 | 67682 | }else{ |
| 67628 | 67683 | assert( pOp->opcode==OP_InsertInt ); |
| 67629 | | - u.bh.iKey = pOp->p3; |
| 67684 | + u.bi.iKey = pOp->p3; |
| 67630 | 67685 | } |
| 67631 | 67686 | |
| 67632 | 67687 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 67633 | | - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bh.iKey; |
| 67634 | | - if( u.bh.pData->flags & MEM_Null ){ |
| 67635 | | - u.bh.pData->z = 0; |
| 67636 | | - u.bh.pData->n = 0; |
| 67637 | | - }else{ |
| 67638 | | - assert( u.bh.pData->flags & (MEM_Blob|MEM_Str) ); |
| 67639 | | - } |
| 67640 | | - u.bh.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bh.pC->seekResult : 0); |
| 67641 | | - if( u.bh.pData->flags & MEM_Zero ){ |
| 67642 | | - u.bh.nZero = u.bh.pData->u.nZero; |
| 67643 | | - }else{ |
| 67644 | | - u.bh.nZero = 0; |
| 67645 | | - } |
| 67646 | | - sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); |
| 67647 | | - rc = sqlite3BtreeInsert(u.bh.pC->pCursor, 0, u.bh.iKey, |
| 67648 | | - u.bh.pData->z, u.bh.pData->n, u.bh.nZero, |
| 67649 | | - pOp->p5 & OPFLAG_APPEND, u.bh.seekResult |
| 67688 | + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey; |
| 67689 | + if( u.bi.pData->flags & MEM_Null ){ |
| 67690 | + u.bi.pData->z = 0; |
| 67691 | + u.bi.pData->n = 0; |
| 67692 | + }else{ |
| 67693 | + assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) ); |
| 67694 | + } |
| 67695 | + u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0); |
| 67696 | + if( u.bi.pData->flags & MEM_Zero ){ |
| 67697 | + u.bi.nZero = u.bi.pData->u.nZero; |
| 67698 | + }else{ |
| 67699 | + u.bi.nZero = 0; |
| 67700 | + } |
| 67701 | + sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0); |
| 67702 | + rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey, |
| 67703 | + u.bi.pData->z, u.bi.pData->n, u.bi.nZero, |
| 67704 | + pOp->p5 & OPFLAG_APPEND, u.bi.seekResult |
| 67650 | 67705 | ); |
| 67651 | | - u.bh.pC->rowidIsValid = 0; |
| 67652 | | - u.bh.pC->deferredMoveto = 0; |
| 67653 | | - u.bh.pC->cacheStatus = CACHE_STALE; |
| 67706 | + u.bi.pC->rowidIsValid = 0; |
| 67707 | + u.bi.pC->deferredMoveto = 0; |
| 67708 | + u.bi.pC->cacheStatus = CACHE_STALE; |
| 67654 | 67709 | |
| 67655 | 67710 | /* Invoke the update-hook if required. */ |
| 67656 | 67711 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67657 | | - u.bh.zDb = db->aDb[u.bh.pC->iDb].zName; |
| 67658 | | - u.bh.zTbl = pOp->p4.z; |
| 67659 | | - u.bh.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 67660 | | - assert( u.bh.pC->isTable ); |
| 67661 | | - db->xUpdateCallback(db->pUpdateArg, u.bh.op, u.bh.zDb, u.bh.zTbl, u.bh.iKey); |
| 67662 | | - assert( u.bh.pC->iDb>=0 ); |
| 67712 | + u.bi.zDb = db->aDb[u.bi.pC->iDb].zName; |
| 67713 | + u.bi.zTbl = pOp->p4.z; |
| 67714 | + u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 67715 | + assert( u.bi.pC->isTable ); |
| 67716 | + db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey); |
| 67717 | + assert( u.bi.pC->iDb>=0 ); |
| 67663 | 67718 | } |
| 67664 | 67719 | break; |
| 67665 | 67720 | } |
| 67666 | 67721 | |
| 67667 | 67722 | /* Opcode: Delete P1 P2 * P4 * |
| | @@ -67683,51 +67738,51 @@ |
| 67683 | 67738 | ** pointing to. The update hook will be invoked, if it exists. |
| 67684 | 67739 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 67685 | 67740 | ** using OP_NotFound prior to invoking this opcode. |
| 67686 | 67741 | */ |
| 67687 | 67742 | case OP_Delete: { |
| 67688 | | -#if 0 /* local variables moved into u.bi */ |
| 67743 | +#if 0 /* local variables moved into u.bj */ |
| 67689 | 67744 | i64 iKey; |
| 67690 | 67745 | VdbeCursor *pC; |
| 67691 | | -#endif /* local variables moved into u.bi */ |
| 67746 | +#endif /* local variables moved into u.bj */ |
| 67692 | 67747 | |
| 67693 | | - u.bi.iKey = 0; |
| 67748 | + u.bj.iKey = 0; |
| 67694 | 67749 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67695 | | - u.bi.pC = p->apCsr[pOp->p1]; |
| 67696 | | - assert( u.bi.pC!=0 ); |
| 67697 | | - assert( u.bi.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 67750 | + u.bj.pC = p->apCsr[pOp->p1]; |
| 67751 | + assert( u.bj.pC!=0 ); |
| 67752 | + assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 67698 | 67753 | |
| 67699 | | - /* If the update-hook will be invoked, set u.bi.iKey to the rowid of the |
| 67754 | + /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the |
| 67700 | 67755 | ** row being deleted. |
| 67701 | 67756 | */ |
| 67702 | 67757 | if( db->xUpdateCallback && pOp->p4.z ){ |
| 67703 | | - assert( u.bi.pC->isTable ); |
| 67704 | | - assert( u.bi.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 67705 | | - u.bi.iKey = u.bi.pC->lastRowid; |
| 67758 | + assert( u.bj.pC->isTable ); |
| 67759 | + assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 67760 | + u.bj.iKey = u.bj.pC->lastRowid; |
| 67706 | 67761 | } |
| 67707 | 67762 | |
| 67708 | 67763 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 67709 | 67764 | ** OP_Column on the same table without any intervening operations that |
| 67710 | | - ** might move or invalidate the cursor. Hence cursor u.bi.pC is always pointing |
| 67765 | + ** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing |
| 67711 | 67766 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 67712 | 67767 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 67713 | 67768 | ** to guard against future changes to the code generator. |
| 67714 | 67769 | **/ |
| 67715 | | - assert( u.bi.pC->deferredMoveto==0 ); |
| 67716 | | - rc = sqlite3VdbeCursorMoveto(u.bi.pC); |
| 67770 | + assert( u.bj.pC->deferredMoveto==0 ); |
| 67771 | + rc = sqlite3VdbeCursorMoveto(u.bj.pC); |
| 67717 | 67772 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67718 | 67773 | |
| 67719 | | - sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0); |
| 67720 | | - rc = sqlite3BtreeDelete(u.bi.pC->pCursor); |
| 67721 | | - u.bi.pC->cacheStatus = CACHE_STALE; |
| 67774 | + sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0); |
| 67775 | + rc = sqlite3BtreeDelete(u.bj.pC->pCursor); |
| 67776 | + u.bj.pC->cacheStatus = CACHE_STALE; |
| 67722 | 67777 | |
| 67723 | 67778 | /* Invoke the update-hook if required. */ |
| 67724 | 67779 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67725 | | - const char *zDb = db->aDb[u.bi.pC->iDb].zName; |
| 67780 | + const char *zDb = db->aDb[u.bj.pC->iDb].zName; |
| 67726 | 67781 | const char *zTbl = pOp->p4.z; |
| 67727 | | - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bi.iKey); |
| 67728 | | - assert( u.bi.pC->iDb>=0 ); |
| 67782 | + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey); |
| 67783 | + assert( u.bj.pC->iDb>=0 ); |
| 67729 | 67784 | } |
| 67730 | 67785 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 67731 | 67786 | break; |
| 67732 | 67787 | } |
| 67733 | 67788 | /* Opcode: ResetCount * * * * * |
| | @@ -67749,20 +67804,20 @@ |
| 67749 | 67804 | ** register P3 with the entry that the sorter cursor currently points to. |
| 67750 | 67805 | ** If, excluding the rowid fields at the end, the two records are a match, |
| 67751 | 67806 | ** fall through to the next instruction. Otherwise, jump to instruction P2. |
| 67752 | 67807 | */ |
| 67753 | 67808 | case OP_SorterCompare: { |
| 67754 | | -#if 0 /* local variables moved into u.bj */ |
| 67809 | +#if 0 /* local variables moved into u.bk */ |
| 67755 | 67810 | VdbeCursor *pC; |
| 67756 | 67811 | int res; |
| 67757 | | -#endif /* local variables moved into u.bj */ |
| 67812 | +#endif /* local variables moved into u.bk */ |
| 67758 | 67813 | |
| 67759 | | - u.bj.pC = p->apCsr[pOp->p1]; |
| 67760 | | - assert( isSorter(u.bj.pC) ); |
| 67814 | + u.bk.pC = p->apCsr[pOp->p1]; |
| 67815 | + assert( isSorter(u.bk.pC) ); |
| 67761 | 67816 | pIn3 = &aMem[pOp->p3]; |
| 67762 | | - rc = sqlite3VdbeSorterCompare(u.bj.pC, pIn3, &u.bj.res); |
| 67763 | | - if( u.bj.res ){ |
| 67817 | + rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res); |
| 67818 | + if( u.bk.res ){ |
| 67764 | 67819 | pc = pOp->p2-1; |
| 67765 | 67820 | } |
| 67766 | 67821 | break; |
| 67767 | 67822 | }; |
| 67768 | 67823 | |
| | @@ -67769,18 +67824,19 @@ |
| 67769 | 67824 | /* Opcode: SorterData P1 P2 * * * |
| 67770 | 67825 | ** |
| 67771 | 67826 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 67772 | 67827 | */ |
| 67773 | 67828 | case OP_SorterData: { |
| 67774 | | -#if 0 /* local variables moved into u.bk */ |
| 67829 | +#if 0 /* local variables moved into u.bl */ |
| 67775 | 67830 | VdbeCursor *pC; |
| 67776 | | -#endif /* local variables moved into u.bk */ |
| 67831 | +#endif /* local variables moved into u.bl */ |
| 67832 | + |
| 67777 | 67833 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 67778 | 67834 | pOut = &aMem[pOp->p2]; |
| 67779 | | - u.bk.pC = p->apCsr[pOp->p1]; |
| 67780 | | - assert( u.bk.pC->isSorter ); |
| 67781 | | - rc = sqlite3VdbeSorterRowkey(u.bk.pC, pOut); |
| 67835 | + u.bl.pC = p->apCsr[pOp->p1]; |
| 67836 | + assert( u.bl.pC->isSorter ); |
| 67837 | + rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut); |
| 67782 | 67838 | #else |
| 67783 | 67839 | pOp->opcode = OP_RowKey; |
| 67784 | 67840 | pc--; |
| 67785 | 67841 | #endif |
| 67786 | 67842 | break; |
| | @@ -67806,66 +67862,66 @@ |
| 67806 | 67862 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 67807 | 67863 | ** of a real table, not a pseudo-table. |
| 67808 | 67864 | */ |
| 67809 | 67865 | case OP_RowKey: |
| 67810 | 67866 | case OP_RowData: { |
| 67811 | | -#if 0 /* local variables moved into u.bl */ |
| 67867 | +#if 0 /* local variables moved into u.bm */ |
| 67812 | 67868 | VdbeCursor *pC; |
| 67813 | 67869 | BtCursor *pCrsr; |
| 67814 | 67870 | u32 n; |
| 67815 | 67871 | i64 n64; |
| 67816 | | -#endif /* local variables moved into u.bl */ |
| 67872 | +#endif /* local variables moved into u.bm */ |
| 67817 | 67873 | |
| 67818 | 67874 | pOut = &aMem[pOp->p2]; |
| 67819 | 67875 | memAboutToChange(p, pOut); |
| 67820 | 67876 | |
| 67821 | 67877 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 67822 | 67878 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67823 | | - u.bl.pC = p->apCsr[pOp->p1]; |
| 67824 | | - assert( u.bl.pC->isSorter==0 ); |
| 67825 | | - assert( u.bl.pC->isTable || pOp->opcode!=OP_RowData ); |
| 67826 | | - assert( u.bl.pC->isIndex || pOp->opcode==OP_RowData ); |
| 67827 | | - assert( u.bl.pC!=0 ); |
| 67828 | | - assert( u.bl.pC->nullRow==0 ); |
| 67829 | | - assert( u.bl.pC->pseudoTableReg==0 ); |
| 67830 | | - assert( u.bl.pC->pCursor!=0 ); |
| 67831 | | - u.bl.pCrsr = u.bl.pC->pCursor; |
| 67832 | | - assert( sqlite3BtreeCursorIsValid(u.bl.pCrsr) ); |
| 67879 | + u.bm.pC = p->apCsr[pOp->p1]; |
| 67880 | + assert( u.bm.pC->isSorter==0 ); |
| 67881 | + assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData ); |
| 67882 | + assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData ); |
| 67883 | + assert( u.bm.pC!=0 ); |
| 67884 | + assert( u.bm.pC->nullRow==0 ); |
| 67885 | + assert( u.bm.pC->pseudoTableReg==0 ); |
| 67886 | + assert( u.bm.pC->pCursor!=0 ); |
| 67887 | + u.bm.pCrsr = u.bm.pC->pCursor; |
| 67888 | + assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) ); |
| 67833 | 67889 | |
| 67834 | 67890 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 67835 | 67891 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 67836 | 67892 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 67837 | 67893 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 67838 | 67894 | */ |
| 67839 | | - assert( u.bl.pC->deferredMoveto==0 ); |
| 67840 | | - rc = sqlite3VdbeCursorMoveto(u.bl.pC); |
| 67841 | | - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67842 | | - |
| 67843 | | - if( u.bl.pC->isIndex ){ |
| 67844 | | - assert( !u.bl.pC->isTable ); |
| 67845 | | - VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bl.pCrsr, &u.bl.n64); |
| 67846 | | - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 67847 | | - if( u.bl.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67848 | | - goto too_big; |
| 67849 | | - } |
| 67850 | | - u.bl.n = (u32)u.bl.n64; |
| 67851 | | - }else{ |
| 67852 | | - VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bl.pCrsr, &u.bl.n); |
| 67853 | | - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 67854 | | - if( u.bl.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67855 | | - goto too_big; |
| 67856 | | - } |
| 67857 | | - } |
| 67858 | | - if( sqlite3VdbeMemGrow(pOut, u.bl.n, 0) ){ |
| 67859 | | - goto no_mem; |
| 67860 | | - } |
| 67861 | | - pOut->n = u.bl.n; |
| 67862 | | - MemSetTypeFlag(pOut, MEM_Blob); |
| 67863 | | - if( u.bl.pC->isIndex ){ |
| 67864 | | - rc = sqlite3BtreeKey(u.bl.pCrsr, 0, u.bl.n, pOut->z); |
| 67865 | | - }else{ |
| 67866 | | - rc = sqlite3BtreeData(u.bl.pCrsr, 0, u.bl.n, pOut->z); |
| 67895 | + assert( u.bm.pC->deferredMoveto==0 ); |
| 67896 | + rc = sqlite3VdbeCursorMoveto(u.bm.pC); |
| 67897 | + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67898 | + |
| 67899 | + if( u.bm.pC->isIndex ){ |
| 67900 | + assert( !u.bm.pC->isTable ); |
| 67901 | + VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64); |
| 67902 | + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 67903 | + if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67904 | + goto too_big; |
| 67905 | + } |
| 67906 | + u.bm.n = (u32)u.bm.n64; |
| 67907 | + }else{ |
| 67908 | + VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n); |
| 67909 | + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 67910 | + if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67911 | + goto too_big; |
| 67912 | + } |
| 67913 | + } |
| 67914 | + if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){ |
| 67915 | + goto no_mem; |
| 67916 | + } |
| 67917 | + pOut->n = u.bm.n; |
| 67918 | + MemSetTypeFlag(pOut, MEM_Blob); |
| 67919 | + if( u.bm.pC->isIndex ){ |
| 67920 | + rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z); |
| 67921 | + }else{ |
| 67922 | + rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z); |
| 67867 | 67923 | } |
| 67868 | 67924 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 67869 | 67925 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67870 | 67926 | break; |
| 67871 | 67927 | } |
| | @@ -67878,46 +67934,46 @@ |
| 67878 | 67934 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 67879 | 67935 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 67880 | 67936 | ** one opcode now works for both table types. |
| 67881 | 67937 | */ |
| 67882 | 67938 | case OP_Rowid: { /* out2-prerelease */ |
| 67883 | | -#if 0 /* local variables moved into u.bm */ |
| 67939 | +#if 0 /* local variables moved into u.bn */ |
| 67884 | 67940 | VdbeCursor *pC; |
| 67885 | 67941 | i64 v; |
| 67886 | 67942 | sqlite3_vtab *pVtab; |
| 67887 | 67943 | const sqlite3_module *pModule; |
| 67888 | | -#endif /* local variables moved into u.bm */ |
| 67944 | +#endif /* local variables moved into u.bn */ |
| 67889 | 67945 | |
| 67890 | 67946 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67891 | | - u.bm.pC = p->apCsr[pOp->p1]; |
| 67892 | | - assert( u.bm.pC!=0 ); |
| 67893 | | - assert( u.bm.pC->pseudoTableReg==0 ); |
| 67894 | | - if( u.bm.pC->nullRow ){ |
| 67947 | + u.bn.pC = p->apCsr[pOp->p1]; |
| 67948 | + assert( u.bn.pC!=0 ); |
| 67949 | + assert( u.bn.pC->pseudoTableReg==0 ); |
| 67950 | + if( u.bn.pC->nullRow ){ |
| 67895 | 67951 | pOut->flags = MEM_Null; |
| 67896 | 67952 | break; |
| 67897 | | - }else if( u.bm.pC->deferredMoveto ){ |
| 67898 | | - u.bm.v = u.bm.pC->movetoTarget; |
| 67953 | + }else if( u.bn.pC->deferredMoveto ){ |
| 67954 | + u.bn.v = u.bn.pC->movetoTarget; |
| 67899 | 67955 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 67900 | | - }else if( u.bm.pC->pVtabCursor ){ |
| 67901 | | - u.bm.pVtab = u.bm.pC->pVtabCursor->pVtab; |
| 67902 | | - u.bm.pModule = u.bm.pVtab->pModule; |
| 67903 | | - assert( u.bm.pModule->xRowid ); |
| 67904 | | - rc = u.bm.pModule->xRowid(u.bm.pC->pVtabCursor, &u.bm.v); |
| 67905 | | - importVtabErrMsg(p, u.bm.pVtab); |
| 67956 | + }else if( u.bn.pC->pVtabCursor ){ |
| 67957 | + u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab; |
| 67958 | + u.bn.pModule = u.bn.pVtab->pModule; |
| 67959 | + assert( u.bn.pModule->xRowid ); |
| 67960 | + rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v); |
| 67961 | + importVtabErrMsg(p, u.bn.pVtab); |
| 67906 | 67962 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 67907 | 67963 | }else{ |
| 67908 | | - assert( u.bm.pC->pCursor!=0 ); |
| 67909 | | - rc = sqlite3VdbeCursorMoveto(u.bm.pC); |
| 67964 | + assert( u.bn.pC->pCursor!=0 ); |
| 67965 | + rc = sqlite3VdbeCursorMoveto(u.bn.pC); |
| 67910 | 67966 | if( rc ) goto abort_due_to_error; |
| 67911 | | - if( u.bm.pC->rowidIsValid ){ |
| 67912 | | - u.bm.v = u.bm.pC->lastRowid; |
| 67967 | + if( u.bn.pC->rowidIsValid ){ |
| 67968 | + u.bn.v = u.bn.pC->lastRowid; |
| 67913 | 67969 | }else{ |
| 67914 | | - rc = sqlite3BtreeKeySize(u.bm.pC->pCursor, &u.bm.v); |
| 67970 | + rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v); |
| 67915 | 67971 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 67916 | 67972 | } |
| 67917 | 67973 | } |
| 67918 | | - pOut->u.i = u.bm.v; |
| 67974 | + pOut->u.i = u.bn.v; |
| 67919 | 67975 | break; |
| 67920 | 67976 | } |
| 67921 | 67977 | |
| 67922 | 67978 | /* Opcode: NullRow P1 * * * * |
| 67923 | 67979 | ** |
| | @@ -67924,22 +67980,22 @@ |
| 67924 | 67980 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 67925 | 67981 | ** that occur while the cursor is on the null row will always |
| 67926 | 67982 | ** write a NULL. |
| 67927 | 67983 | */ |
| 67928 | 67984 | case OP_NullRow: { |
| 67929 | | -#if 0 /* local variables moved into u.bn */ |
| 67985 | +#if 0 /* local variables moved into u.bo */ |
| 67930 | 67986 | VdbeCursor *pC; |
| 67931 | | -#endif /* local variables moved into u.bn */ |
| 67987 | +#endif /* local variables moved into u.bo */ |
| 67932 | 67988 | |
| 67933 | 67989 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67934 | | - u.bn.pC = p->apCsr[pOp->p1]; |
| 67935 | | - assert( u.bn.pC!=0 ); |
| 67936 | | - u.bn.pC->nullRow = 1; |
| 67937 | | - u.bn.pC->rowidIsValid = 0; |
| 67938 | | - assert( u.bn.pC->pCursor || u.bn.pC->pVtabCursor ); |
| 67939 | | - if( u.bn.pC->pCursor ){ |
| 67940 | | - sqlite3BtreeClearCursor(u.bn.pC->pCursor); |
| 67990 | + u.bo.pC = p->apCsr[pOp->p1]; |
| 67991 | + assert( u.bo.pC!=0 ); |
| 67992 | + u.bo.pC->nullRow = 1; |
| 67993 | + u.bo.pC->rowidIsValid = 0; |
| 67994 | + assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor ); |
| 67995 | + if( u.bo.pC->pCursor ){ |
| 67996 | + sqlite3BtreeClearCursor(u.bo.pC->pCursor); |
| 67941 | 67997 | } |
| 67942 | 67998 | break; |
| 67943 | 67999 | } |
| 67944 | 68000 | |
| 67945 | 68001 | /* Opcode: Last P1 P2 * * * |
| | @@ -67949,29 +68005,29 @@ |
| 67949 | 68005 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67950 | 68006 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67951 | 68007 | ** to the following instruction. |
| 67952 | 68008 | */ |
| 67953 | 68009 | case OP_Last: { /* jump */ |
| 67954 | | -#if 0 /* local variables moved into u.bo */ |
| 68010 | +#if 0 /* local variables moved into u.bp */ |
| 67955 | 68011 | VdbeCursor *pC; |
| 67956 | 68012 | BtCursor *pCrsr; |
| 67957 | 68013 | int res; |
| 67958 | | -#endif /* local variables moved into u.bo */ |
| 68014 | +#endif /* local variables moved into u.bp */ |
| 67959 | 68015 | |
| 67960 | 68016 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67961 | | - u.bo.pC = p->apCsr[pOp->p1]; |
| 67962 | | - assert( u.bo.pC!=0 ); |
| 67963 | | - u.bo.pCrsr = u.bo.pC->pCursor; |
| 67964 | | - u.bo.res = 0; |
| 67965 | | - if( ALWAYS(u.bo.pCrsr!=0) ){ |
| 67966 | | - rc = sqlite3BtreeLast(u.bo.pCrsr, &u.bo.res); |
| 67967 | | - } |
| 67968 | | - u.bo.pC->nullRow = (u8)u.bo.res; |
| 67969 | | - u.bo.pC->deferredMoveto = 0; |
| 67970 | | - u.bo.pC->rowidIsValid = 0; |
| 67971 | | - u.bo.pC->cacheStatus = CACHE_STALE; |
| 67972 | | - if( pOp->p2>0 && u.bo.res ){ |
| 68017 | + u.bp.pC = p->apCsr[pOp->p1]; |
| 68018 | + assert( u.bp.pC!=0 ); |
| 68019 | + u.bp.pCrsr = u.bp.pC->pCursor; |
| 68020 | + u.bp.res = 0; |
| 68021 | + if( ALWAYS(u.bp.pCrsr!=0) ){ |
| 68022 | + rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res); |
| 68023 | + } |
| 68024 | + u.bp.pC->nullRow = (u8)u.bp.res; |
| 68025 | + u.bp.pC->deferredMoveto = 0; |
| 68026 | + u.bp.pC->rowidIsValid = 0; |
| 68027 | + u.bp.pC->cacheStatus = CACHE_STALE; |
| 68028 | + if( pOp->p2>0 && u.bp.res ){ |
| 67973 | 68029 | pc = pOp->p2 - 1; |
| 67974 | 68030 | } |
| 67975 | 68031 | break; |
| 67976 | 68032 | } |
| 67977 | 68033 | |
| | @@ -68007,35 +68063,35 @@ |
| 68007 | 68063 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 68008 | 68064 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 68009 | 68065 | ** to the following instruction. |
| 68010 | 68066 | */ |
| 68011 | 68067 | case OP_Rewind: { /* jump */ |
| 68012 | | -#if 0 /* local variables moved into u.bp */ |
| 68068 | +#if 0 /* local variables moved into u.bq */ |
| 68013 | 68069 | VdbeCursor *pC; |
| 68014 | 68070 | BtCursor *pCrsr; |
| 68015 | 68071 | int res; |
| 68016 | | -#endif /* local variables moved into u.bp */ |
| 68072 | +#endif /* local variables moved into u.bq */ |
| 68017 | 68073 | |
| 68018 | 68074 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68019 | | - u.bp.pC = p->apCsr[pOp->p1]; |
| 68020 | | - assert( u.bp.pC!=0 ); |
| 68021 | | - assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterSort) ); |
| 68022 | | - u.bp.res = 1; |
| 68023 | | - if( isSorter(u.bp.pC) ){ |
| 68024 | | - rc = sqlite3VdbeSorterRewind(db, u.bp.pC, &u.bp.res); |
| 68075 | + u.bq.pC = p->apCsr[pOp->p1]; |
| 68076 | + assert( u.bq.pC!=0 ); |
| 68077 | + assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) ); |
| 68078 | + u.bq.res = 1; |
| 68079 | + if( isSorter(u.bq.pC) ){ |
| 68080 | + rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res); |
| 68025 | 68081 | }else{ |
| 68026 | | - u.bp.pCrsr = u.bp.pC->pCursor; |
| 68027 | | - assert( u.bp.pCrsr ); |
| 68028 | | - rc = sqlite3BtreeFirst(u.bp.pCrsr, &u.bp.res); |
| 68029 | | - u.bp.pC->atFirst = u.bp.res==0 ?1:0; |
| 68030 | | - u.bp.pC->deferredMoveto = 0; |
| 68031 | | - u.bp.pC->cacheStatus = CACHE_STALE; |
| 68032 | | - u.bp.pC->rowidIsValid = 0; |
| 68033 | | - } |
| 68034 | | - u.bp.pC->nullRow = (u8)u.bp.res; |
| 68082 | + u.bq.pCrsr = u.bq.pC->pCursor; |
| 68083 | + assert( u.bq.pCrsr ); |
| 68084 | + rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res); |
| 68085 | + u.bq.pC->atFirst = u.bq.res==0 ?1:0; |
| 68086 | + u.bq.pC->deferredMoveto = 0; |
| 68087 | + u.bq.pC->cacheStatus = CACHE_STALE; |
| 68088 | + u.bq.pC->rowidIsValid = 0; |
| 68089 | + } |
| 68090 | + u.bq.pC->nullRow = (u8)u.bq.res; |
| 68035 | 68091 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 68036 | | - if( u.bp.res ){ |
| 68092 | + if( u.bq.res ){ |
| 68037 | 68093 | pc = pOp->p2 - 1; |
| 68038 | 68094 | } |
| 68039 | 68095 | break; |
| 68040 | 68096 | } |
| 68041 | 68097 | |
| | @@ -68075,44 +68131,44 @@ |
| 68075 | 68131 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 68076 | 68132 | pOp->opcode = OP_Next; |
| 68077 | 68133 | #endif |
| 68078 | 68134 | case OP_Prev: /* jump */ |
| 68079 | 68135 | case OP_Next: { /* jump */ |
| 68080 | | -#if 0 /* local variables moved into u.bq */ |
| 68136 | +#if 0 /* local variables moved into u.br */ |
| 68081 | 68137 | VdbeCursor *pC; |
| 68082 | 68138 | int res; |
| 68083 | | -#endif /* local variables moved into u.bq */ |
| 68139 | +#endif /* local variables moved into u.br */ |
| 68084 | 68140 | |
| 68085 | 68141 | CHECK_FOR_INTERRUPT; |
| 68086 | 68142 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68087 | 68143 | assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 68088 | | - u.bq.pC = p->apCsr[pOp->p1]; |
| 68089 | | - if( u.bq.pC==0 ){ |
| 68144 | + u.br.pC = p->apCsr[pOp->p1]; |
| 68145 | + if( u.br.pC==0 ){ |
| 68090 | 68146 | break; /* See ticket #2273 */ |
| 68091 | 68147 | } |
| 68092 | | - assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 68093 | | - if( isSorter(u.bq.pC) ){ |
| 68148 | + assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 68149 | + if( isSorter(u.br.pC) ){ |
| 68094 | 68150 | assert( pOp->opcode==OP_SorterNext ); |
| 68095 | | - rc = sqlite3VdbeSorterNext(db, u.bq.pC, &u.bq.res); |
| 68151 | + rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res); |
| 68096 | 68152 | }else{ |
| 68097 | | - u.bq.res = 1; |
| 68098 | | - assert( u.bq.pC->deferredMoveto==0 ); |
| 68099 | | - assert( u.bq.pC->pCursor ); |
| 68153 | + u.br.res = 1; |
| 68154 | + assert( u.br.pC->deferredMoveto==0 ); |
| 68155 | + assert( u.br.pC->pCursor ); |
| 68100 | 68156 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 68101 | 68157 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 68102 | | - rc = pOp->p4.xAdvance(u.bq.pC->pCursor, &u.bq.res); |
| 68158 | + rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res); |
| 68103 | 68159 | } |
| 68104 | | - u.bq.pC->nullRow = (u8)u.bq.res; |
| 68105 | | - u.bq.pC->cacheStatus = CACHE_STALE; |
| 68106 | | - if( u.bq.res==0 ){ |
| 68160 | + u.br.pC->nullRow = (u8)u.br.res; |
| 68161 | + u.br.pC->cacheStatus = CACHE_STALE; |
| 68162 | + if( u.br.res==0 ){ |
| 68107 | 68163 | pc = pOp->p2 - 1; |
| 68108 | 68164 | if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 68109 | 68165 | #ifdef SQLITE_TEST |
| 68110 | 68166 | sqlite3_search_count++; |
| 68111 | 68167 | #endif |
| 68112 | 68168 | } |
| 68113 | | - u.bq.pC->rowidIsValid = 0; |
| 68169 | + u.br.pC->rowidIsValid = 0; |
| 68114 | 68170 | break; |
| 68115 | 68171 | } |
| 68116 | 68172 | |
| 68117 | 68173 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 68118 | 68174 | ** |
| | @@ -68129,38 +68185,38 @@ |
| 68129 | 68185 | case OP_SorterInsert: /* in2 */ |
| 68130 | 68186 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 68131 | 68187 | pOp->opcode = OP_IdxInsert; |
| 68132 | 68188 | #endif |
| 68133 | 68189 | case OP_IdxInsert: { /* in2 */ |
| 68134 | | -#if 0 /* local variables moved into u.br */ |
| 68190 | +#if 0 /* local variables moved into u.bs */ |
| 68135 | 68191 | VdbeCursor *pC; |
| 68136 | 68192 | BtCursor *pCrsr; |
| 68137 | 68193 | int nKey; |
| 68138 | 68194 | const char *zKey; |
| 68139 | | -#endif /* local variables moved into u.br */ |
| 68195 | +#endif /* local variables moved into u.bs */ |
| 68140 | 68196 | |
| 68141 | 68197 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68142 | | - u.br.pC = p->apCsr[pOp->p1]; |
| 68143 | | - assert( u.br.pC!=0 ); |
| 68144 | | - assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); |
| 68198 | + u.bs.pC = p->apCsr[pOp->p1]; |
| 68199 | + assert( u.bs.pC!=0 ); |
| 68200 | + assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); |
| 68145 | 68201 | pIn2 = &aMem[pOp->p2]; |
| 68146 | 68202 | assert( pIn2->flags & MEM_Blob ); |
| 68147 | | - u.br.pCrsr = u.br.pC->pCursor; |
| 68148 | | - if( ALWAYS(u.br.pCrsr!=0) ){ |
| 68149 | | - assert( u.br.pC->isTable==0 ); |
| 68203 | + u.bs.pCrsr = u.bs.pC->pCursor; |
| 68204 | + if( ALWAYS(u.bs.pCrsr!=0) ){ |
| 68205 | + assert( u.bs.pC->isTable==0 ); |
| 68150 | 68206 | rc = ExpandBlob(pIn2); |
| 68151 | 68207 | if( rc==SQLITE_OK ){ |
| 68152 | | - if( isSorter(u.br.pC) ){ |
| 68153 | | - rc = sqlite3VdbeSorterWrite(db, u.br.pC, pIn2); |
| 68208 | + if( isSorter(u.bs.pC) ){ |
| 68209 | + rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2); |
| 68154 | 68210 | }else{ |
| 68155 | | - u.br.nKey = pIn2->n; |
| 68156 | | - u.br.zKey = pIn2->z; |
| 68157 | | - rc = sqlite3BtreeInsert(u.br.pCrsr, u.br.zKey, u.br.nKey, "", 0, 0, pOp->p3, |
| 68158 | | - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.br.pC->seekResult : 0) |
| 68211 | + u.bs.nKey = pIn2->n; |
| 68212 | + u.bs.zKey = pIn2->z; |
| 68213 | + rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3, |
| 68214 | + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0) |
| 68159 | 68215 | ); |
| 68160 | | - assert( u.br.pC->deferredMoveto==0 ); |
| 68161 | | - u.br.pC->cacheStatus = CACHE_STALE; |
| 68216 | + assert( u.bs.pC->deferredMoveto==0 ); |
| 68217 | + u.bs.pC->cacheStatus = CACHE_STALE; |
| 68162 | 68218 | } |
| 68163 | 68219 | } |
| 68164 | 68220 | } |
| 68165 | 68221 | break; |
| 68166 | 68222 | } |
| | @@ -68170,37 +68226,37 @@ |
| 68170 | 68226 | ** The content of P3 registers starting at register P2 form |
| 68171 | 68227 | ** an unpacked index key. This opcode removes that entry from the |
| 68172 | 68228 | ** index opened by cursor P1. |
| 68173 | 68229 | */ |
| 68174 | 68230 | case OP_IdxDelete: { |
| 68175 | | -#if 0 /* local variables moved into u.bs */ |
| 68231 | +#if 0 /* local variables moved into u.bt */ |
| 68176 | 68232 | VdbeCursor *pC; |
| 68177 | 68233 | BtCursor *pCrsr; |
| 68178 | 68234 | int res; |
| 68179 | 68235 | UnpackedRecord r; |
| 68180 | | -#endif /* local variables moved into u.bs */ |
| 68236 | +#endif /* local variables moved into u.bt */ |
| 68181 | 68237 | |
| 68182 | 68238 | assert( pOp->p3>0 ); |
| 68183 | 68239 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 68184 | 68240 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68185 | | - u.bs.pC = p->apCsr[pOp->p1]; |
| 68186 | | - assert( u.bs.pC!=0 ); |
| 68187 | | - u.bs.pCrsr = u.bs.pC->pCursor; |
| 68188 | | - if( ALWAYS(u.bs.pCrsr!=0) ){ |
| 68189 | | - u.bs.r.pKeyInfo = u.bs.pC->pKeyInfo; |
| 68190 | | - u.bs.r.nField = (u16)pOp->p3; |
| 68191 | | - u.bs.r.flags = 0; |
| 68192 | | - u.bs.r.aMem = &aMem[pOp->p2]; |
| 68241 | + u.bt.pC = p->apCsr[pOp->p1]; |
| 68242 | + assert( u.bt.pC!=0 ); |
| 68243 | + u.bt.pCrsr = u.bt.pC->pCursor; |
| 68244 | + if( ALWAYS(u.bt.pCrsr!=0) ){ |
| 68245 | + u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; |
| 68246 | + u.bt.r.nField = (u16)pOp->p3; |
| 68247 | + u.bt.r.flags = 0; |
| 68248 | + u.bt.r.aMem = &aMem[pOp->p2]; |
| 68193 | 68249 | #ifdef SQLITE_DEBUG |
| 68194 | | - { int i; for(i=0; i<u.bs.r.nField; i++) assert( memIsValid(&u.bs.r.aMem[i]) ); } |
| 68250 | + { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } |
| 68195 | 68251 | #endif |
| 68196 | | - rc = sqlite3BtreeMovetoUnpacked(u.bs.pCrsr, &u.bs.r, 0, 0, &u.bs.res); |
| 68197 | | - if( rc==SQLITE_OK && u.bs.res==0 ){ |
| 68198 | | - rc = sqlite3BtreeDelete(u.bs.pCrsr); |
| 68252 | + rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res); |
| 68253 | + if( rc==SQLITE_OK && u.bt.res==0 ){ |
| 68254 | + rc = sqlite3BtreeDelete(u.bt.pCrsr); |
| 68199 | 68255 | } |
| 68200 | | - assert( u.bs.pC->deferredMoveto==0 ); |
| 68201 | | - u.bs.pC->cacheStatus = CACHE_STALE; |
| 68256 | + assert( u.bt.pC->deferredMoveto==0 ); |
| 68257 | + u.bt.pC->cacheStatus = CACHE_STALE; |
| 68202 | 68258 | } |
| 68203 | 68259 | break; |
| 68204 | 68260 | } |
| 68205 | 68261 | |
| 68206 | 68262 | /* Opcode: IdxRowid P1 P2 * * * |
| | @@ -68210,32 +68266,32 @@ |
| 68210 | 68266 | ** the rowid of the table entry to which this index entry points. |
| 68211 | 68267 | ** |
| 68212 | 68268 | ** See also: Rowid, MakeRecord. |
| 68213 | 68269 | */ |
| 68214 | 68270 | case OP_IdxRowid: { /* out2-prerelease */ |
| 68215 | | -#if 0 /* local variables moved into u.bt */ |
| 68271 | +#if 0 /* local variables moved into u.bu */ |
| 68216 | 68272 | BtCursor *pCrsr; |
| 68217 | 68273 | VdbeCursor *pC; |
| 68218 | 68274 | i64 rowid; |
| 68219 | | -#endif /* local variables moved into u.bt */ |
| 68275 | +#endif /* local variables moved into u.bu */ |
| 68220 | 68276 | |
| 68221 | 68277 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68222 | | - u.bt.pC = p->apCsr[pOp->p1]; |
| 68223 | | - assert( u.bt.pC!=0 ); |
| 68224 | | - u.bt.pCrsr = u.bt.pC->pCursor; |
| 68278 | + u.bu.pC = p->apCsr[pOp->p1]; |
| 68279 | + assert( u.bu.pC!=0 ); |
| 68280 | + u.bu.pCrsr = u.bu.pC->pCursor; |
| 68225 | 68281 | pOut->flags = MEM_Null; |
| 68226 | | - if( ALWAYS(u.bt.pCrsr!=0) ){ |
| 68227 | | - rc = sqlite3VdbeCursorMoveto(u.bt.pC); |
| 68282 | + if( ALWAYS(u.bu.pCrsr!=0) ){ |
| 68283 | + rc = sqlite3VdbeCursorMoveto(u.bu.pC); |
| 68228 | 68284 | if( NEVER(rc) ) goto abort_due_to_error; |
| 68229 | | - assert( u.bt.pC->deferredMoveto==0 ); |
| 68230 | | - assert( u.bt.pC->isTable==0 ); |
| 68231 | | - if( !u.bt.pC->nullRow ){ |
| 68232 | | - rc = sqlite3VdbeIdxRowid(db, u.bt.pCrsr, &u.bt.rowid); |
| 68285 | + assert( u.bu.pC->deferredMoveto==0 ); |
| 68286 | + assert( u.bu.pC->isTable==0 ); |
| 68287 | + if( !u.bu.pC->nullRow ){ |
| 68288 | + rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid); |
| 68233 | 68289 | if( rc!=SQLITE_OK ){ |
| 68234 | 68290 | goto abort_due_to_error; |
| 68235 | 68291 | } |
| 68236 | | - pOut->u.i = u.bt.rowid; |
| 68292 | + pOut->u.i = u.bu.rowid; |
| 68237 | 68293 | pOut->flags = MEM_Int; |
| 68238 | 68294 | } |
| 68239 | 68295 | } |
| 68240 | 68296 | break; |
| 68241 | 68297 | } |
| | @@ -68266,43 +68322,43 @@ |
| 68266 | 68322 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 68267 | 68323 | ** to the comparison. This makes the opcode work like IdxLE. |
| 68268 | 68324 | */ |
| 68269 | 68325 | case OP_IdxLT: /* jump */ |
| 68270 | 68326 | case OP_IdxGE: { /* jump */ |
| 68271 | | -#if 0 /* local variables moved into u.bu */ |
| 68327 | +#if 0 /* local variables moved into u.bv */ |
| 68272 | 68328 | VdbeCursor *pC; |
| 68273 | 68329 | int res; |
| 68274 | 68330 | UnpackedRecord r; |
| 68275 | | -#endif /* local variables moved into u.bu */ |
| 68331 | +#endif /* local variables moved into u.bv */ |
| 68276 | 68332 | |
| 68277 | 68333 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68278 | | - u.bu.pC = p->apCsr[pOp->p1]; |
| 68279 | | - assert( u.bu.pC!=0 ); |
| 68280 | | - assert( u.bu.pC->isOrdered ); |
| 68281 | | - if( ALWAYS(u.bu.pC->pCursor!=0) ){ |
| 68282 | | - assert( u.bu.pC->deferredMoveto==0 ); |
| 68334 | + u.bv.pC = p->apCsr[pOp->p1]; |
| 68335 | + assert( u.bv.pC!=0 ); |
| 68336 | + assert( u.bv.pC->isOrdered ); |
| 68337 | + if( ALWAYS(u.bv.pC->pCursor!=0) ){ |
| 68338 | + assert( u.bv.pC->deferredMoveto==0 ); |
| 68283 | 68339 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 68284 | 68340 | assert( pOp->p4type==P4_INT32 ); |
| 68285 | | - u.bu.r.pKeyInfo = u.bu.pC->pKeyInfo; |
| 68286 | | - u.bu.r.nField = (u16)pOp->p4.i; |
| 68341 | + u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo; |
| 68342 | + u.bv.r.nField = (u16)pOp->p4.i; |
| 68287 | 68343 | if( pOp->p5 ){ |
| 68288 | | - u.bu.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; |
| 68344 | + u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; |
| 68289 | 68345 | }else{ |
| 68290 | | - u.bu.r.flags = UNPACKED_PREFIX_MATCH; |
| 68346 | + u.bv.r.flags = UNPACKED_PREFIX_MATCH; |
| 68291 | 68347 | } |
| 68292 | | - u.bu.r.aMem = &aMem[pOp->p3]; |
| 68348 | + u.bv.r.aMem = &aMem[pOp->p3]; |
| 68293 | 68349 | #ifdef SQLITE_DEBUG |
| 68294 | | - { int i; for(i=0; i<u.bu.r.nField; i++) assert( memIsValid(&u.bu.r.aMem[i]) ); } |
| 68350 | + { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); } |
| 68295 | 68351 | #endif |
| 68296 | | - rc = sqlite3VdbeIdxKeyCompare(u.bu.pC, &u.bu.r, &u.bu.res); |
| 68352 | + rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res); |
| 68297 | 68353 | if( pOp->opcode==OP_IdxLT ){ |
| 68298 | | - u.bu.res = -u.bu.res; |
| 68354 | + u.bv.res = -u.bv.res; |
| 68299 | 68355 | }else{ |
| 68300 | 68356 | assert( pOp->opcode==OP_IdxGE ); |
| 68301 | | - u.bu.res++; |
| 68357 | + u.bv.res++; |
| 68302 | 68358 | } |
| 68303 | | - if( u.bu.res>0 ){ |
| 68359 | + if( u.bv.res>0 ){ |
| 68304 | 68360 | pc = pOp->p2 - 1 ; |
| 68305 | 68361 | } |
| 68306 | 68362 | } |
| 68307 | 68363 | break; |
| 68308 | 68364 | } |
| | @@ -68326,43 +68382,44 @@ |
| 68326 | 68382 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 68327 | 68383 | ** |
| 68328 | 68384 | ** See also: Clear |
| 68329 | 68385 | */ |
| 68330 | 68386 | case OP_Destroy: { /* out2-prerelease */ |
| 68331 | | -#if 0 /* local variables moved into u.bv */ |
| 68387 | +#if 0 /* local variables moved into u.bw */ |
| 68332 | 68388 | int iMoved; |
| 68333 | 68389 | int iCnt; |
| 68334 | 68390 | Vdbe *pVdbe; |
| 68335 | 68391 | int iDb; |
| 68336 | | -#endif /* local variables moved into u.bv */ |
| 68392 | +#endif /* local variables moved into u.bw */ |
| 68393 | + |
| 68337 | 68394 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 68338 | | - u.bv.iCnt = 0; |
| 68339 | | - for(u.bv.pVdbe=db->pVdbe; u.bv.pVdbe; u.bv.pVdbe = u.bv.pVdbe->pNext){ |
| 68340 | | - if( u.bv.pVdbe->magic==VDBE_MAGIC_RUN && u.bv.pVdbe->inVtabMethod<2 && u.bv.pVdbe->pc>=0 ){ |
| 68341 | | - u.bv.iCnt++; |
| 68395 | + u.bw.iCnt = 0; |
| 68396 | + for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){ |
| 68397 | + if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){ |
| 68398 | + u.bw.iCnt++; |
| 68342 | 68399 | } |
| 68343 | 68400 | } |
| 68344 | 68401 | #else |
| 68345 | | - u.bv.iCnt = db->activeVdbeCnt; |
| 68402 | + u.bw.iCnt = db->activeVdbeCnt; |
| 68346 | 68403 | #endif |
| 68347 | 68404 | pOut->flags = MEM_Null; |
| 68348 | | - if( u.bv.iCnt>1 ){ |
| 68405 | + if( u.bw.iCnt>1 ){ |
| 68349 | 68406 | rc = SQLITE_LOCKED; |
| 68350 | 68407 | p->errorAction = OE_Abort; |
| 68351 | 68408 | }else{ |
| 68352 | | - u.bv.iDb = pOp->p3; |
| 68353 | | - assert( u.bv.iCnt==1 ); |
| 68354 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.bv.iDb))!=0 ); |
| 68355 | | - rc = sqlite3BtreeDropTable(db->aDb[u.bv.iDb].pBt, pOp->p1, &u.bv.iMoved); |
| 68409 | + u.bw.iDb = pOp->p3; |
| 68410 | + assert( u.bw.iCnt==1 ); |
| 68411 | + assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 ); |
| 68412 | + rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved); |
| 68356 | 68413 | pOut->flags = MEM_Int; |
| 68357 | | - pOut->u.i = u.bv.iMoved; |
| 68414 | + pOut->u.i = u.bw.iMoved; |
| 68358 | 68415 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 68359 | | - if( rc==SQLITE_OK && u.bv.iMoved!=0 ){ |
| 68360 | | - sqlite3RootPageMoved(db, u.bv.iDb, u.bv.iMoved, pOp->p1); |
| 68416 | + if( rc==SQLITE_OK && u.bw.iMoved!=0 ){ |
| 68417 | + sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1); |
| 68361 | 68418 | /* All OP_Destroy operations occur on the same btree */ |
| 68362 | | - assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bv.iDb+1 ); |
| 68363 | | - resetSchemaOnFault = u.bv.iDb+1; |
| 68419 | + assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 ); |
| 68420 | + resetSchemaOnFault = u.bw.iDb+1; |
| 68364 | 68421 | } |
| 68365 | 68422 | #endif |
| 68366 | 68423 | } |
| 68367 | 68424 | break; |
| 68368 | 68425 | } |
| | @@ -68384,25 +68441,25 @@ |
| 68384 | 68441 | ** also incremented by the number of rows in the table being cleared. |
| 68385 | 68442 | ** |
| 68386 | 68443 | ** See also: Destroy |
| 68387 | 68444 | */ |
| 68388 | 68445 | case OP_Clear: { |
| 68389 | | -#if 0 /* local variables moved into u.bw */ |
| 68446 | +#if 0 /* local variables moved into u.bx */ |
| 68390 | 68447 | int nChange; |
| 68391 | | -#endif /* local variables moved into u.bw */ |
| 68448 | +#endif /* local variables moved into u.bx */ |
| 68392 | 68449 | |
| 68393 | | - u.bw.nChange = 0; |
| 68450 | + u.bx.nChange = 0; |
| 68394 | 68451 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 68395 | 68452 | rc = sqlite3BtreeClearTable( |
| 68396 | | - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bw.nChange : 0) |
| 68453 | + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 68397 | 68454 | ); |
| 68398 | 68455 | if( pOp->p3 ){ |
| 68399 | | - p->nChange += u.bw.nChange; |
| 68456 | + p->nChange += u.bx.nChange; |
| 68400 | 68457 | if( pOp->p3>0 ){ |
| 68401 | 68458 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 68402 | 68459 | memAboutToChange(p, &aMem[pOp->p3]); |
| 68403 | | - aMem[pOp->p3].u.i += u.bw.nChange; |
| 68460 | + aMem[pOp->p3].u.i += u.bx.nChange; |
| 68404 | 68461 | } |
| 68405 | 68462 | } |
| 68406 | 68463 | break; |
| 68407 | 68464 | } |
| 68408 | 68465 | |
| | @@ -68428,29 +68485,29 @@ |
| 68428 | 68485 | ** |
| 68429 | 68486 | ** See documentation on OP_CreateTable for additional information. |
| 68430 | 68487 | */ |
| 68431 | 68488 | case OP_CreateIndex: /* out2-prerelease */ |
| 68432 | 68489 | case OP_CreateTable: { /* out2-prerelease */ |
| 68433 | | -#if 0 /* local variables moved into u.bx */ |
| 68490 | +#if 0 /* local variables moved into u.by */ |
| 68434 | 68491 | int pgno; |
| 68435 | 68492 | int flags; |
| 68436 | 68493 | Db *pDb; |
| 68437 | | -#endif /* local variables moved into u.bx */ |
| 68494 | +#endif /* local variables moved into u.by */ |
| 68438 | 68495 | |
| 68439 | | - u.bx.pgno = 0; |
| 68496 | + u.by.pgno = 0; |
| 68440 | 68497 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68441 | 68498 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68442 | | - u.bx.pDb = &db->aDb[pOp->p1]; |
| 68443 | | - assert( u.bx.pDb->pBt!=0 ); |
| 68499 | + u.by.pDb = &db->aDb[pOp->p1]; |
| 68500 | + assert( u.by.pDb->pBt!=0 ); |
| 68444 | 68501 | if( pOp->opcode==OP_CreateTable ){ |
| 68445 | | - /* u.bx.flags = BTREE_INTKEY; */ |
| 68446 | | - u.bx.flags = BTREE_INTKEY; |
| 68502 | + /* u.by.flags = BTREE_INTKEY; */ |
| 68503 | + u.by.flags = BTREE_INTKEY; |
| 68447 | 68504 | }else{ |
| 68448 | | - u.bx.flags = BTREE_BLOBKEY; |
| 68505 | + u.by.flags = BTREE_BLOBKEY; |
| 68449 | 68506 | } |
| 68450 | | - rc = sqlite3BtreeCreateTable(u.bx.pDb->pBt, &u.bx.pgno, u.bx.flags); |
| 68451 | | - pOut->u.i = u.bx.pgno; |
| 68507 | + rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags); |
| 68508 | + pOut->u.i = u.by.pgno; |
| 68452 | 68509 | break; |
| 68453 | 68510 | } |
| 68454 | 68511 | |
| 68455 | 68512 | /* Opcode: ParseSchema P1 * * P4 * |
| 68456 | 68513 | ** |
| | @@ -68459,48 +68516,48 @@ |
| 68459 | 68516 | ** |
| 68460 | 68517 | ** This opcode invokes the parser to create a new virtual machine, |
| 68461 | 68518 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 68462 | 68519 | */ |
| 68463 | 68520 | case OP_ParseSchema: { |
| 68464 | | -#if 0 /* local variables moved into u.by */ |
| 68521 | +#if 0 /* local variables moved into u.bz */ |
| 68465 | 68522 | int iDb; |
| 68466 | 68523 | const char *zMaster; |
| 68467 | 68524 | char *zSql; |
| 68468 | 68525 | InitData initData; |
| 68469 | | -#endif /* local variables moved into u.by */ |
| 68526 | +#endif /* local variables moved into u.bz */ |
| 68470 | 68527 | |
| 68471 | 68528 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 68472 | 68529 | ** on every btree. This is a prerequisite for invoking |
| 68473 | 68530 | ** sqlite3InitCallback(). |
| 68474 | 68531 | */ |
| 68475 | 68532 | #ifdef SQLITE_DEBUG |
| 68476 | | - for(u.by.iDb=0; u.by.iDb<db->nDb; u.by.iDb++){ |
| 68477 | | - assert( u.by.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.by.iDb].pBt) ); |
| 68533 | + for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){ |
| 68534 | + assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) ); |
| 68478 | 68535 | } |
| 68479 | 68536 | #endif |
| 68480 | 68537 | |
| 68481 | | - u.by.iDb = pOp->p1; |
| 68482 | | - assert( u.by.iDb>=0 && u.by.iDb<db->nDb ); |
| 68483 | | - assert( DbHasProperty(db, u.by.iDb, DB_SchemaLoaded) ); |
| 68538 | + u.bz.iDb = pOp->p1; |
| 68539 | + assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb ); |
| 68540 | + assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) ); |
| 68484 | 68541 | /* Used to be a conditional */ { |
| 68485 | | - u.by.zMaster = SCHEMA_TABLE(u.by.iDb); |
| 68486 | | - u.by.initData.db = db; |
| 68487 | | - u.by.initData.iDb = pOp->p1; |
| 68488 | | - u.by.initData.pzErrMsg = &p->zErrMsg; |
| 68489 | | - u.by.zSql = sqlite3MPrintf(db, |
| 68542 | + u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb); |
| 68543 | + u.bz.initData.db = db; |
| 68544 | + u.bz.initData.iDb = pOp->p1; |
| 68545 | + u.bz.initData.pzErrMsg = &p->zErrMsg; |
| 68546 | + u.bz.zSql = sqlite3MPrintf(db, |
| 68490 | 68547 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| 68491 | | - db->aDb[u.by.iDb].zName, u.by.zMaster, pOp->p4.z); |
| 68492 | | - if( u.by.zSql==0 ){ |
| 68548 | + db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z); |
| 68549 | + if( u.bz.zSql==0 ){ |
| 68493 | 68550 | rc = SQLITE_NOMEM; |
| 68494 | 68551 | }else{ |
| 68495 | 68552 | assert( db->init.busy==0 ); |
| 68496 | 68553 | db->init.busy = 1; |
| 68497 | | - u.by.initData.rc = SQLITE_OK; |
| 68554 | + u.bz.initData.rc = SQLITE_OK; |
| 68498 | 68555 | assert( !db->mallocFailed ); |
| 68499 | | - rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0); |
| 68500 | | - if( rc==SQLITE_OK ) rc = u.by.initData.rc; |
| 68501 | | - sqlite3DbFree(db, u.by.zSql); |
| 68556 | + rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0); |
| 68557 | + if( rc==SQLITE_OK ) rc = u.bz.initData.rc; |
| 68558 | + sqlite3DbFree(db, u.bz.zSql); |
| 68502 | 68559 | db->init.busy = 0; |
| 68503 | 68560 | } |
| 68504 | 68561 | } |
| 68505 | 68562 | if( rc ) sqlite3ResetAllSchemasOfConnection(db); |
| 68506 | 68563 | if( rc==SQLITE_NOMEM ){ |
| | @@ -68580,45 +68637,45 @@ |
| 68580 | 68637 | ** file, not the main database file. |
| 68581 | 68638 | ** |
| 68582 | 68639 | ** This opcode is used to implement the integrity_check pragma. |
| 68583 | 68640 | */ |
| 68584 | 68641 | case OP_IntegrityCk: { |
| 68585 | | -#if 0 /* local variables moved into u.bz */ |
| 68642 | +#if 0 /* local variables moved into u.ca */ |
| 68586 | 68643 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 68587 | 68644 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 68588 | 68645 | int j; /* Loop counter */ |
| 68589 | 68646 | int nErr; /* Number of errors reported */ |
| 68590 | 68647 | char *z; /* Text of the error report */ |
| 68591 | 68648 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 68592 | | -#endif /* local variables moved into u.bz */ |
| 68649 | +#endif /* local variables moved into u.ca */ |
| 68593 | 68650 | |
| 68594 | | - u.bz.nRoot = pOp->p2; |
| 68595 | | - assert( u.bz.nRoot>0 ); |
| 68596 | | - u.bz.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bz.nRoot+1) ); |
| 68597 | | - if( u.bz.aRoot==0 ) goto no_mem; |
| 68651 | + u.ca.nRoot = pOp->p2; |
| 68652 | + assert( u.ca.nRoot>0 ); |
| 68653 | + u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 68654 | + if( u.ca.aRoot==0 ) goto no_mem; |
| 68598 | 68655 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68599 | | - u.bz.pnErr = &aMem[pOp->p3]; |
| 68600 | | - assert( (u.bz.pnErr->flags & MEM_Int)!=0 ); |
| 68601 | | - assert( (u.bz.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 68656 | + u.ca.pnErr = &aMem[pOp->p3]; |
| 68657 | + assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 68658 | + assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 68602 | 68659 | pIn1 = &aMem[pOp->p1]; |
| 68603 | | - for(u.bz.j=0; u.bz.j<u.bz.nRoot; u.bz.j++){ |
| 68604 | | - u.bz.aRoot[u.bz.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bz.j]); |
| 68660 | + for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| 68661 | + u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]); |
| 68605 | 68662 | } |
| 68606 | | - u.bz.aRoot[u.bz.j] = 0; |
| 68663 | + u.ca.aRoot[u.ca.j] = 0; |
| 68607 | 68664 | assert( pOp->p5<db->nDb ); |
| 68608 | 68665 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 68609 | | - u.bz.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bz.aRoot, u.bz.nRoot, |
| 68610 | | - (int)u.bz.pnErr->u.i, &u.bz.nErr); |
| 68611 | | - sqlite3DbFree(db, u.bz.aRoot); |
| 68612 | | - u.bz.pnErr->u.i -= u.bz.nErr; |
| 68666 | + u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot, |
| 68667 | + (int)u.ca.pnErr->u.i, &u.ca.nErr); |
| 68668 | + sqlite3DbFree(db, u.ca.aRoot); |
| 68669 | + u.ca.pnErr->u.i -= u.ca.nErr; |
| 68613 | 68670 | sqlite3VdbeMemSetNull(pIn1); |
| 68614 | | - if( u.bz.nErr==0 ){ |
| 68615 | | - assert( u.bz.z==0 ); |
| 68616 | | - }else if( u.bz.z==0 ){ |
| 68671 | + if( u.ca.nErr==0 ){ |
| 68672 | + assert( u.ca.z==0 ); |
| 68673 | + }else if( u.ca.z==0 ){ |
| 68617 | 68674 | goto no_mem; |
| 68618 | 68675 | }else{ |
| 68619 | | - sqlite3VdbeMemSetStr(pIn1, u.bz.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68676 | + sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68620 | 68677 | } |
| 68621 | 68678 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 68622 | 68679 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 68623 | 68680 | break; |
| 68624 | 68681 | } |
| | @@ -68648,24 +68705,24 @@ |
| 68648 | 68705 | ** Extract the smallest value from boolean index P1 and put that value into |
| 68649 | 68706 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 68650 | 68707 | ** unchanged and jump to instruction P2. |
| 68651 | 68708 | */ |
| 68652 | 68709 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 68653 | | -#if 0 /* local variables moved into u.ca */ |
| 68710 | +#if 0 /* local variables moved into u.cb */ |
| 68654 | 68711 | i64 val; |
| 68655 | | -#endif /* local variables moved into u.ca */ |
| 68712 | +#endif /* local variables moved into u.cb */ |
| 68656 | 68713 | CHECK_FOR_INTERRUPT; |
| 68657 | 68714 | pIn1 = &aMem[pOp->p1]; |
| 68658 | 68715 | if( (pIn1->flags & MEM_RowSet)==0 |
| 68659 | | - || sqlite3RowSetNext(pIn1->u.pRowSet, &u.ca.val)==0 |
| 68716 | + || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0 |
| 68660 | 68717 | ){ |
| 68661 | 68718 | /* The boolean index is empty */ |
| 68662 | 68719 | sqlite3VdbeMemSetNull(pIn1); |
| 68663 | 68720 | pc = pOp->p2 - 1; |
| 68664 | 68721 | }else{ |
| 68665 | 68722 | /* A value was pulled from the index */ |
| 68666 | | - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.ca.val); |
| 68723 | + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val); |
| 68667 | 68724 | } |
| 68668 | 68725 | break; |
| 68669 | 68726 | } |
| 68670 | 68727 | |
| 68671 | 68728 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| | @@ -68690,18 +68747,18 @@ |
| 68690 | 68747 | ** inserted, there is no need to search to see if the same value was |
| 68691 | 68748 | ** previously inserted as part of set X (only if it was previously |
| 68692 | 68749 | ** inserted as part of some other set). |
| 68693 | 68750 | */ |
| 68694 | 68751 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 68695 | | -#if 0 /* local variables moved into u.cb */ |
| 68752 | +#if 0 /* local variables moved into u.cc */ |
| 68696 | 68753 | int iSet; |
| 68697 | 68754 | int exists; |
| 68698 | | -#endif /* local variables moved into u.cb */ |
| 68755 | +#endif /* local variables moved into u.cc */ |
| 68699 | 68756 | |
| 68700 | 68757 | pIn1 = &aMem[pOp->p1]; |
| 68701 | 68758 | pIn3 = &aMem[pOp->p3]; |
| 68702 | | - u.cb.iSet = pOp->p4.i; |
| 68759 | + u.cc.iSet = pOp->p4.i; |
| 68703 | 68760 | assert( pIn3->flags&MEM_Int ); |
| 68704 | 68761 | |
| 68705 | 68762 | /* If there is anything other than a rowset object in memory cell P1, |
| 68706 | 68763 | ** delete it now and initialize P1 with an empty rowset |
| 68707 | 68764 | */ |
| | @@ -68709,21 +68766,21 @@ |
| 68709 | 68766 | sqlite3VdbeMemSetRowSet(pIn1); |
| 68710 | 68767 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 68711 | 68768 | } |
| 68712 | 68769 | |
| 68713 | 68770 | assert( pOp->p4type==P4_INT32 ); |
| 68714 | | - assert( u.cb.iSet==-1 || u.cb.iSet>=0 ); |
| 68715 | | - if( u.cb.iSet ){ |
| 68716 | | - u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 68717 | | - (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff), |
| 68771 | + assert( u.cc.iSet==-1 || u.cc.iSet>=0 ); |
| 68772 | + if( u.cc.iSet ){ |
| 68773 | + u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 68774 | + (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff), |
| 68718 | 68775 | pIn3->u.i); |
| 68719 | | - if( u.cb.exists ){ |
| 68776 | + if( u.cc.exists ){ |
| 68720 | 68777 | pc = pOp->p2 - 1; |
| 68721 | 68778 | break; |
| 68722 | 68779 | } |
| 68723 | 68780 | } |
| 68724 | | - if( u.cb.iSet>=0 ){ |
| 68781 | + if( u.cc.iSet>=0 ){ |
| 68725 | 68782 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 68726 | 68783 | } |
| 68727 | 68784 | break; |
| 68728 | 68785 | } |
| 68729 | 68786 | |
| | @@ -68742,24 +68799,24 @@ |
| 68742 | 68799 | ** memory required by the sub-vdbe at runtime. |
| 68743 | 68800 | ** |
| 68744 | 68801 | ** P4 is a pointer to the VM containing the trigger program. |
| 68745 | 68802 | */ |
| 68746 | 68803 | case OP_Program: { /* jump */ |
| 68747 | | -#if 0 /* local variables moved into u.cc */ |
| 68804 | +#if 0 /* local variables moved into u.cd */ |
| 68748 | 68805 | int nMem; /* Number of memory registers for sub-program */ |
| 68749 | 68806 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 68750 | 68807 | Mem *pRt; /* Register to allocate runtime space */ |
| 68751 | 68808 | Mem *pMem; /* Used to iterate through memory cells */ |
| 68752 | 68809 | Mem *pEnd; /* Last memory cell in new array */ |
| 68753 | 68810 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 68754 | 68811 | SubProgram *pProgram; /* Sub-program to execute */ |
| 68755 | 68812 | void *t; /* Token identifying trigger */ |
| 68756 | | -#endif /* local variables moved into u.cc */ |
| 68813 | +#endif /* local variables moved into u.cd */ |
| 68757 | 68814 | |
| 68758 | | - u.cc.pProgram = pOp->p4.pProgram; |
| 68759 | | - u.cc.pRt = &aMem[pOp->p3]; |
| 68760 | | - assert( u.cc.pProgram->nOp>0 ); |
| 68815 | + u.cd.pProgram = pOp->p4.pProgram; |
| 68816 | + u.cd.pRt = &aMem[pOp->p3]; |
| 68817 | + assert( u.cd.pProgram->nOp>0 ); |
| 68761 | 68818 | |
| 68762 | 68819 | /* If the p5 flag is clear, then recursive invocation of triggers is |
| 68763 | 68820 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 68764 | 68821 | ** is really a trigger, not a foreign key action, and the flag set |
| 68765 | 68822 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| | @@ -68769,84 +68826,84 @@ |
| 68769 | 68826 | ** SubProgram (if the trigger may be executed with more than one different |
| 68770 | 68827 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 68771 | 68828 | ** single trigger all have the same value for the SubProgram.token |
| 68772 | 68829 | ** variable. */ |
| 68773 | 68830 | if( pOp->p5 ){ |
| 68774 | | - u.cc.t = u.cc.pProgram->token; |
| 68775 | | - for(u.cc.pFrame=p->pFrame; u.cc.pFrame && u.cc.pFrame->token!=u.cc.t; u.cc.pFrame=u.cc.pFrame->pParent); |
| 68776 | | - if( u.cc.pFrame ) break; |
| 68831 | + u.cd.t = u.cd.pProgram->token; |
| 68832 | + for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent); |
| 68833 | + if( u.cd.pFrame ) break; |
| 68777 | 68834 | } |
| 68778 | 68835 | |
| 68779 | 68836 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 68780 | 68837 | rc = SQLITE_ERROR; |
| 68781 | 68838 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 68782 | 68839 | break; |
| 68783 | 68840 | } |
| 68784 | 68841 | |
| 68785 | | - /* Register u.cc.pRt is used to store the memory required to save the state |
| 68842 | + /* Register u.cd.pRt is used to store the memory required to save the state |
| 68786 | 68843 | ** of the current program, and the memory required at runtime to execute |
| 68787 | | - ** the trigger program. If this trigger has been fired before, then u.cc.pRt |
| 68844 | + ** the trigger program. If this trigger has been fired before, then u.cd.pRt |
| 68788 | 68845 | ** is already allocated. Otherwise, it must be initialized. */ |
| 68789 | | - if( (u.cc.pRt->flags&MEM_Frame)==0 ){ |
| 68846 | + if( (u.cd.pRt->flags&MEM_Frame)==0 ){ |
| 68790 | 68847 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 68791 | 68848 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 68792 | 68849 | ** cell is required for each cursor used by the program. Set local |
| 68793 | | - ** variable u.cc.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68850 | + ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68794 | 68851 | */ |
| 68795 | | - u.cc.nMem = u.cc.pProgram->nMem + u.cc.pProgram->nCsr; |
| 68796 | | - u.cc.nByte = ROUND8(sizeof(VdbeFrame)) |
| 68797 | | - + u.cc.nMem * sizeof(Mem) |
| 68798 | | - + u.cc.pProgram->nCsr * sizeof(VdbeCursor *) |
| 68799 | | - + u.cc.pProgram->nOnce * sizeof(u8); |
| 68800 | | - u.cc.pFrame = sqlite3DbMallocZero(db, u.cc.nByte); |
| 68801 | | - if( !u.cc.pFrame ){ |
| 68852 | + u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr; |
| 68853 | + u.cd.nByte = ROUND8(sizeof(VdbeFrame)) |
| 68854 | + + u.cd.nMem * sizeof(Mem) |
| 68855 | + + u.cd.pProgram->nCsr * sizeof(VdbeCursor *) |
| 68856 | + + u.cd.pProgram->nOnce * sizeof(u8); |
| 68857 | + u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte); |
| 68858 | + if( !u.cd.pFrame ){ |
| 68802 | 68859 | goto no_mem; |
| 68803 | 68860 | } |
| 68804 | | - sqlite3VdbeMemRelease(u.cc.pRt); |
| 68805 | | - u.cc.pRt->flags = MEM_Frame; |
| 68806 | | - u.cc.pRt->u.pFrame = u.cc.pFrame; |
| 68807 | | - |
| 68808 | | - u.cc.pFrame->v = p; |
| 68809 | | - u.cc.pFrame->nChildMem = u.cc.nMem; |
| 68810 | | - u.cc.pFrame->nChildCsr = u.cc.pProgram->nCsr; |
| 68811 | | - u.cc.pFrame->pc = pc; |
| 68812 | | - u.cc.pFrame->aMem = p->aMem; |
| 68813 | | - u.cc.pFrame->nMem = p->nMem; |
| 68814 | | - u.cc.pFrame->apCsr = p->apCsr; |
| 68815 | | - u.cc.pFrame->nCursor = p->nCursor; |
| 68816 | | - u.cc.pFrame->aOp = p->aOp; |
| 68817 | | - u.cc.pFrame->nOp = p->nOp; |
| 68818 | | - u.cc.pFrame->token = u.cc.pProgram->token; |
| 68819 | | - u.cc.pFrame->aOnceFlag = p->aOnceFlag; |
| 68820 | | - u.cc.pFrame->nOnceFlag = p->nOnceFlag; |
| 68821 | | - |
| 68822 | | - u.cc.pEnd = &VdbeFrameMem(u.cc.pFrame)[u.cc.pFrame->nChildMem]; |
| 68823 | | - for(u.cc.pMem=VdbeFrameMem(u.cc.pFrame); u.cc.pMem!=u.cc.pEnd; u.cc.pMem++){ |
| 68824 | | - u.cc.pMem->flags = MEM_Invalid; |
| 68825 | | - u.cc.pMem->db = db; |
| 68861 | + sqlite3VdbeMemRelease(u.cd.pRt); |
| 68862 | + u.cd.pRt->flags = MEM_Frame; |
| 68863 | + u.cd.pRt->u.pFrame = u.cd.pFrame; |
| 68864 | + |
| 68865 | + u.cd.pFrame->v = p; |
| 68866 | + u.cd.pFrame->nChildMem = u.cd.nMem; |
| 68867 | + u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr; |
| 68868 | + u.cd.pFrame->pc = pc; |
| 68869 | + u.cd.pFrame->aMem = p->aMem; |
| 68870 | + u.cd.pFrame->nMem = p->nMem; |
| 68871 | + u.cd.pFrame->apCsr = p->apCsr; |
| 68872 | + u.cd.pFrame->nCursor = p->nCursor; |
| 68873 | + u.cd.pFrame->aOp = p->aOp; |
| 68874 | + u.cd.pFrame->nOp = p->nOp; |
| 68875 | + u.cd.pFrame->token = u.cd.pProgram->token; |
| 68876 | + u.cd.pFrame->aOnceFlag = p->aOnceFlag; |
| 68877 | + u.cd.pFrame->nOnceFlag = p->nOnceFlag; |
| 68878 | + |
| 68879 | + u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem]; |
| 68880 | + for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){ |
| 68881 | + u.cd.pMem->flags = MEM_Invalid; |
| 68882 | + u.cd.pMem->db = db; |
| 68826 | 68883 | } |
| 68827 | 68884 | }else{ |
| 68828 | | - u.cc.pFrame = u.cc.pRt->u.pFrame; |
| 68829 | | - assert( u.cc.pProgram->nMem+u.cc.pProgram->nCsr==u.cc.pFrame->nChildMem ); |
| 68830 | | - assert( u.cc.pProgram->nCsr==u.cc.pFrame->nChildCsr ); |
| 68831 | | - assert( pc==u.cc.pFrame->pc ); |
| 68885 | + u.cd.pFrame = u.cd.pRt->u.pFrame; |
| 68886 | + assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem ); |
| 68887 | + assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr ); |
| 68888 | + assert( pc==u.cd.pFrame->pc ); |
| 68832 | 68889 | } |
| 68833 | 68890 | |
| 68834 | 68891 | p->nFrame++; |
| 68835 | | - u.cc.pFrame->pParent = p->pFrame; |
| 68836 | | - u.cc.pFrame->lastRowid = lastRowid; |
| 68837 | | - u.cc.pFrame->nChange = p->nChange; |
| 68892 | + u.cd.pFrame->pParent = p->pFrame; |
| 68893 | + u.cd.pFrame->lastRowid = lastRowid; |
| 68894 | + u.cd.pFrame->nChange = p->nChange; |
| 68838 | 68895 | p->nChange = 0; |
| 68839 | | - p->pFrame = u.cc.pFrame; |
| 68840 | | - p->aMem = aMem = &VdbeFrameMem(u.cc.pFrame)[-1]; |
| 68841 | | - p->nMem = u.cc.pFrame->nChildMem; |
| 68842 | | - p->nCursor = (u16)u.cc.pFrame->nChildCsr; |
| 68896 | + p->pFrame = u.cd.pFrame; |
| 68897 | + p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1]; |
| 68898 | + p->nMem = u.cd.pFrame->nChildMem; |
| 68899 | + p->nCursor = (u16)u.cd.pFrame->nChildCsr; |
| 68843 | 68900 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 68844 | | - p->aOp = aOp = u.cc.pProgram->aOp; |
| 68845 | | - p->nOp = u.cc.pProgram->nOp; |
| 68901 | + p->aOp = aOp = u.cd.pProgram->aOp; |
| 68902 | + p->nOp = u.cd.pProgram->nOp; |
| 68846 | 68903 | p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; |
| 68847 | | - p->nOnceFlag = u.cc.pProgram->nOnce; |
| 68904 | + p->nOnceFlag = u.cd.pProgram->nOnce; |
| 68848 | 68905 | pc = -1; |
| 68849 | 68906 | memset(p->aOnceFlag, 0, p->nOnceFlag); |
| 68850 | 68907 | |
| 68851 | 68908 | break; |
| 68852 | 68909 | } |
| | @@ -68862,17 +68919,17 @@ |
| 68862 | 68919 | ** The address of the cell in the parent frame is determined by adding |
| 68863 | 68920 | ** the value of the P1 argument to the value of the P1 argument to the |
| 68864 | 68921 | ** calling OP_Program instruction. |
| 68865 | 68922 | */ |
| 68866 | 68923 | case OP_Param: { /* out2-prerelease */ |
| 68867 | | -#if 0 /* local variables moved into u.cd */ |
| 68924 | +#if 0 /* local variables moved into u.ce */ |
| 68868 | 68925 | VdbeFrame *pFrame; |
| 68869 | 68926 | Mem *pIn; |
| 68870 | | -#endif /* local variables moved into u.cd */ |
| 68871 | | - u.cd.pFrame = p->pFrame; |
| 68872 | | - u.cd.pIn = &u.cd.pFrame->aMem[pOp->p1 + u.cd.pFrame->aOp[u.cd.pFrame->pc].p1]; |
| 68873 | | - sqlite3VdbeMemShallowCopy(pOut, u.cd.pIn, MEM_Ephem); |
| 68927 | +#endif /* local variables moved into u.ce */ |
| 68928 | + u.ce.pFrame = p->pFrame; |
| 68929 | + u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1]; |
| 68930 | + sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem); |
| 68874 | 68931 | break; |
| 68875 | 68932 | } |
| 68876 | 68933 | |
| 68877 | 68934 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 68878 | 68935 | |
| | @@ -68924,26 +68981,26 @@ |
| 68924 | 68981 | ** |
| 68925 | 68982 | ** This instruction throws an error if the memory cell is not initially |
| 68926 | 68983 | ** an integer. |
| 68927 | 68984 | */ |
| 68928 | 68985 | case OP_MemMax: { /* in2 */ |
| 68929 | | -#if 0 /* local variables moved into u.ce */ |
| 68986 | +#if 0 /* local variables moved into u.cf */ |
| 68930 | 68987 | Mem *pIn1; |
| 68931 | 68988 | VdbeFrame *pFrame; |
| 68932 | | -#endif /* local variables moved into u.ce */ |
| 68989 | +#endif /* local variables moved into u.cf */ |
| 68933 | 68990 | if( p->pFrame ){ |
| 68934 | | - for(u.ce.pFrame=p->pFrame; u.ce.pFrame->pParent; u.ce.pFrame=u.ce.pFrame->pParent); |
| 68935 | | - u.ce.pIn1 = &u.ce.pFrame->aMem[pOp->p1]; |
| 68991 | + for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent); |
| 68992 | + u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1]; |
| 68936 | 68993 | }else{ |
| 68937 | | - u.ce.pIn1 = &aMem[pOp->p1]; |
| 68994 | + u.cf.pIn1 = &aMem[pOp->p1]; |
| 68938 | 68995 | } |
| 68939 | | - assert( memIsValid(u.ce.pIn1) ); |
| 68940 | | - sqlite3VdbeMemIntegerify(u.ce.pIn1); |
| 68996 | + assert( memIsValid(u.cf.pIn1) ); |
| 68997 | + sqlite3VdbeMemIntegerify(u.cf.pIn1); |
| 68941 | 68998 | pIn2 = &aMem[pOp->p2]; |
| 68942 | 68999 | sqlite3VdbeMemIntegerify(pIn2); |
| 68943 | | - if( u.ce.pIn1->u.i<pIn2->u.i){ |
| 68944 | | - u.ce.pIn1->u.i = pIn2->u.i; |
| 69000 | + if( u.cf.pIn1->u.i<pIn2->u.i){ |
| 69001 | + u.cf.pIn1->u.i = pIn2->u.i; |
| 68945 | 69002 | } |
| 68946 | 69003 | break; |
| 68947 | 69004 | } |
| 68948 | 69005 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 68949 | 69006 | |
| | @@ -69006,60 +69063,60 @@ |
| 69006 | 69063 | ** |
| 69007 | 69064 | ** The P5 arguments are taken from register P2 and its |
| 69008 | 69065 | ** successors. |
| 69009 | 69066 | */ |
| 69010 | 69067 | case OP_AggStep: { |
| 69011 | | -#if 0 /* local variables moved into u.cf */ |
| 69068 | +#if 0 /* local variables moved into u.cg */ |
| 69012 | 69069 | int n; |
| 69013 | 69070 | int i; |
| 69014 | 69071 | Mem *pMem; |
| 69015 | 69072 | Mem *pRec; |
| 69016 | 69073 | sqlite3_context ctx; |
| 69017 | 69074 | sqlite3_value **apVal; |
| 69018 | | -#endif /* local variables moved into u.cf */ |
| 69019 | | - |
| 69020 | | - u.cf.n = pOp->p5; |
| 69021 | | - assert( u.cf.n>=0 ); |
| 69022 | | - u.cf.pRec = &aMem[pOp->p2]; |
| 69023 | | - u.cf.apVal = p->apArg; |
| 69024 | | - assert( u.cf.apVal || u.cf.n==0 ); |
| 69025 | | - for(u.cf.i=0; u.cf.i<u.cf.n; u.cf.i++, u.cf.pRec++){ |
| 69026 | | - assert( memIsValid(u.cf.pRec) ); |
| 69027 | | - u.cf.apVal[u.cf.i] = u.cf.pRec; |
| 69028 | | - memAboutToChange(p, u.cf.pRec); |
| 69029 | | - sqlite3VdbeMemStoreType(u.cf.pRec); |
| 69030 | | - } |
| 69031 | | - u.cf.ctx.pFunc = pOp->p4.pFunc; |
| 69075 | +#endif /* local variables moved into u.cg */ |
| 69076 | + |
| 69077 | + u.cg.n = pOp->p5; |
| 69078 | + assert( u.cg.n>=0 ); |
| 69079 | + u.cg.pRec = &aMem[pOp->p2]; |
| 69080 | + u.cg.apVal = p->apArg; |
| 69081 | + assert( u.cg.apVal || u.cg.n==0 ); |
| 69082 | + for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){ |
| 69083 | + assert( memIsValid(u.cg.pRec) ); |
| 69084 | + u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 69085 | + memAboutToChange(p, u.cg.pRec); |
| 69086 | + sqlite3VdbeMemStoreType(u.cg.pRec); |
| 69087 | + } |
| 69088 | + u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 69032 | 69089 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69033 | | - u.cf.ctx.pMem = u.cf.pMem = &aMem[pOp->p3]; |
| 69034 | | - u.cf.pMem->n++; |
| 69035 | | - u.cf.ctx.s.flags = MEM_Null; |
| 69036 | | - u.cf.ctx.s.z = 0; |
| 69037 | | - u.cf.ctx.s.zMalloc = 0; |
| 69038 | | - u.cf.ctx.s.xDel = 0; |
| 69039 | | - u.cf.ctx.s.db = db; |
| 69040 | | - u.cf.ctx.isError = 0; |
| 69041 | | - u.cf.ctx.pColl = 0; |
| 69042 | | - u.cf.ctx.skipFlag = 0; |
| 69043 | | - if( u.cf.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 69090 | + u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 69091 | + u.cg.pMem->n++; |
| 69092 | + u.cg.ctx.s.flags = MEM_Null; |
| 69093 | + u.cg.ctx.s.z = 0; |
| 69094 | + u.cg.ctx.s.zMalloc = 0; |
| 69095 | + u.cg.ctx.s.xDel = 0; |
| 69096 | + u.cg.ctx.s.db = db; |
| 69097 | + u.cg.ctx.isError = 0; |
| 69098 | + u.cg.ctx.pColl = 0; |
| 69099 | + u.cg.ctx.skipFlag = 0; |
| 69100 | + if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 69044 | 69101 | assert( pOp>p->aOp ); |
| 69045 | 69102 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 69046 | 69103 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 69047 | | - u.cf.ctx.pColl = pOp[-1].p4.pColl; |
| 69048 | | - } |
| 69049 | | - (u.cf.ctx.pFunc->xStep)(&u.cf.ctx, u.cf.n, u.cf.apVal); /* IMP: R-24505-23230 */ |
| 69050 | | - if( u.cf.ctx.isError ){ |
| 69051 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cf.ctx.s)); |
| 69052 | | - rc = u.cf.ctx.isError; |
| 69053 | | - } |
| 69054 | | - if( u.cf.ctx.skipFlag ){ |
| 69104 | + u.cg.ctx.pColl = pOp[-1].p4.pColl; |
| 69105 | + } |
| 69106 | + (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */ |
| 69107 | + if( u.cg.ctx.isError ){ |
| 69108 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s)); |
| 69109 | + rc = u.cg.ctx.isError; |
| 69110 | + } |
| 69111 | + if( u.cg.ctx.skipFlag ){ |
| 69055 | 69112 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 69056 | | - u.cf.i = pOp[-1].p1; |
| 69057 | | - if( u.cf.i ) sqlite3VdbeMemSetInt64(&aMem[u.cf.i], 1); |
| 69113 | + u.cg.i = pOp[-1].p1; |
| 69114 | + if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1); |
| 69058 | 69115 | } |
| 69059 | 69116 | |
| 69060 | | - sqlite3VdbeMemRelease(&u.cf.ctx.s); |
| 69117 | + sqlite3VdbeMemRelease(&u.cg.ctx.s); |
| 69061 | 69118 | |
| 69062 | 69119 | break; |
| 69063 | 69120 | } |
| 69064 | 69121 | |
| 69065 | 69122 | /* Opcode: AggFinal P1 P2 * P4 * |
| | @@ -69073,23 +69130,23 @@ |
| 69073 | 69130 | ** functions that can take varying numbers of arguments. The |
| 69074 | 69131 | ** P4 argument is only needed for the degenerate case where |
| 69075 | 69132 | ** the step function was not previously called. |
| 69076 | 69133 | */ |
| 69077 | 69134 | case OP_AggFinal: { |
| 69078 | | -#if 0 /* local variables moved into u.cg */ |
| 69135 | +#if 0 /* local variables moved into u.ch */ |
| 69079 | 69136 | Mem *pMem; |
| 69080 | | -#endif /* local variables moved into u.cg */ |
| 69137 | +#endif /* local variables moved into u.ch */ |
| 69081 | 69138 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 69082 | | - u.cg.pMem = &aMem[pOp->p1]; |
| 69083 | | - assert( (u.cg.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 69084 | | - rc = sqlite3VdbeMemFinalize(u.cg.pMem, pOp->p4.pFunc); |
| 69139 | + u.ch.pMem = &aMem[pOp->p1]; |
| 69140 | + assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 69141 | + rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 69085 | 69142 | if( rc ){ |
| 69086 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cg.pMem)); |
| 69143 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| 69087 | 69144 | } |
| 69088 | | - sqlite3VdbeChangeEncoding(u.cg.pMem, encoding); |
| 69089 | | - UPDATE_MAX_BLOBSIZE(u.cg.pMem); |
| 69090 | | - if( sqlite3VdbeMemTooBig(u.cg.pMem) ){ |
| 69145 | + sqlite3VdbeChangeEncoding(u.ch.pMem, encoding); |
| 69146 | + UPDATE_MAX_BLOBSIZE(u.ch.pMem); |
| 69147 | + if( sqlite3VdbeMemTooBig(u.ch.pMem) ){ |
| 69091 | 69148 | goto too_big; |
| 69092 | 69149 | } |
| 69093 | 69150 | break; |
| 69094 | 69151 | } |
| 69095 | 69152 | |
| | @@ -69104,29 +69161,29 @@ |
| 69104 | 69161 | ** in the WAL that have been checkpointed after the checkpoint |
| 69105 | 69162 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 69106 | 69163 | ** mem[P3+2] are initialized to -1. |
| 69107 | 69164 | */ |
| 69108 | 69165 | case OP_Checkpoint: { |
| 69109 | | -#if 0 /* local variables moved into u.ch */ |
| 69166 | +#if 0 /* local variables moved into u.ci */ |
| 69110 | 69167 | int i; /* Loop counter */ |
| 69111 | 69168 | int aRes[3]; /* Results */ |
| 69112 | 69169 | Mem *pMem; /* Write results here */ |
| 69113 | | -#endif /* local variables moved into u.ch */ |
| 69170 | +#endif /* local variables moved into u.ci */ |
| 69114 | 69171 | |
| 69115 | | - u.ch.aRes[0] = 0; |
| 69116 | | - u.ch.aRes[1] = u.ch.aRes[2] = -1; |
| 69172 | + u.ci.aRes[0] = 0; |
| 69173 | + u.ci.aRes[1] = u.ci.aRes[2] = -1; |
| 69117 | 69174 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 69118 | 69175 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 69119 | 69176 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 69120 | 69177 | ); |
| 69121 | | - rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ch.aRes[1], &u.ch.aRes[2]); |
| 69178 | + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]); |
| 69122 | 69179 | if( rc==SQLITE_BUSY ){ |
| 69123 | 69180 | rc = SQLITE_OK; |
| 69124 | | - u.ch.aRes[0] = 1; |
| 69181 | + u.ci.aRes[0] = 1; |
| 69125 | 69182 | } |
| 69126 | | - for(u.ch.i=0, u.ch.pMem = &aMem[pOp->p3]; u.ch.i<3; u.ch.i++, u.ch.pMem++){ |
| 69127 | | - sqlite3VdbeMemSetInt64(u.ch.pMem, (i64)u.ch.aRes[u.ch.i]); |
| 69183 | + for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){ |
| 69184 | + sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]); |
| 69128 | 69185 | } |
| 69129 | 69186 | break; |
| 69130 | 69187 | }; |
| 69131 | 69188 | #endif |
| 69132 | 69189 | |
| | @@ -69141,97 +69198,97 @@ |
| 69141 | 69198 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 69142 | 69199 | ** |
| 69143 | 69200 | ** Write a string containing the final journal-mode to register P2. |
| 69144 | 69201 | */ |
| 69145 | 69202 | case OP_JournalMode: { /* out2-prerelease */ |
| 69146 | | -#if 0 /* local variables moved into u.ci */ |
| 69203 | +#if 0 /* local variables moved into u.cj */ |
| 69147 | 69204 | Btree *pBt; /* Btree to change journal mode of */ |
| 69148 | 69205 | Pager *pPager; /* Pager associated with pBt */ |
| 69149 | 69206 | int eNew; /* New journal mode */ |
| 69150 | 69207 | int eOld; /* The old journal mode */ |
| 69151 | | -#endif /* local variables moved into u.ci */ |
| 69152 | 69208 | #ifndef SQLITE_OMIT_WAL |
| 69153 | | - const char *zFilename; /* Name of database file for u.ci.pPager */ |
| 69209 | + const char *zFilename; /* Name of database file for pPager */ |
| 69154 | 69210 | #endif |
| 69155 | | - |
| 69156 | | - u.ci.eNew = pOp->p3; |
| 69157 | | - assert( u.ci.eNew==PAGER_JOURNALMODE_DELETE |
| 69158 | | - || u.ci.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 69159 | | - || u.ci.eNew==PAGER_JOURNALMODE_PERSIST |
| 69160 | | - || u.ci.eNew==PAGER_JOURNALMODE_OFF |
| 69161 | | - || u.ci.eNew==PAGER_JOURNALMODE_MEMORY |
| 69162 | | - || u.ci.eNew==PAGER_JOURNALMODE_WAL |
| 69163 | | - || u.ci.eNew==PAGER_JOURNALMODE_QUERY |
| 69211 | +#endif /* local variables moved into u.cj */ |
| 69212 | + |
| 69213 | + u.cj.eNew = pOp->p3; |
| 69214 | + assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE |
| 69215 | + || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 69216 | + || u.cj.eNew==PAGER_JOURNALMODE_PERSIST |
| 69217 | + || u.cj.eNew==PAGER_JOURNALMODE_OFF |
| 69218 | + || u.cj.eNew==PAGER_JOURNALMODE_MEMORY |
| 69219 | + || u.cj.eNew==PAGER_JOURNALMODE_WAL |
| 69220 | + || u.cj.eNew==PAGER_JOURNALMODE_QUERY |
| 69164 | 69221 | ); |
| 69165 | 69222 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69166 | 69223 | |
| 69167 | | - u.ci.pBt = db->aDb[pOp->p1].pBt; |
| 69168 | | - u.ci.pPager = sqlite3BtreePager(u.ci.pBt); |
| 69169 | | - u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager); |
| 69170 | | - if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld; |
| 69171 | | - if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld; |
| 69224 | + u.cj.pBt = db->aDb[pOp->p1].pBt; |
| 69225 | + u.cj.pPager = sqlite3BtreePager(u.cj.pBt); |
| 69226 | + u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager); |
| 69227 | + if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld; |
| 69228 | + if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld; |
| 69172 | 69229 | |
| 69173 | 69230 | #ifndef SQLITE_OMIT_WAL |
| 69174 | | - zFilename = sqlite3PagerFilename(u.ci.pPager, 1); |
| 69231 | + u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1); |
| 69175 | 69232 | |
| 69176 | 69233 | /* Do not allow a transition to journal_mode=WAL for a database |
| 69177 | 69234 | ** in temporary storage or if the VFS does not support shared memory |
| 69178 | 69235 | */ |
| 69179 | | - if( u.ci.eNew==PAGER_JOURNALMODE_WAL |
| 69180 | | - && (sqlite3Strlen30(zFilename)==0 /* Temp file */ |
| 69181 | | - || !sqlite3PagerWalSupported(u.ci.pPager)) /* No shared-memory support */ |
| 69236 | + if( u.cj.eNew==PAGER_JOURNALMODE_WAL |
| 69237 | + && (sqlite3Strlen30(u.cj.zFilename)==0 /* Temp file */ |
| 69238 | + || !sqlite3PagerWalSupported(u.cj.pPager)) /* No shared-memory support */ |
| 69182 | 69239 | ){ |
| 69183 | | - u.ci.eNew = u.ci.eOld; |
| 69240 | + u.cj.eNew = u.cj.eOld; |
| 69184 | 69241 | } |
| 69185 | 69242 | |
| 69186 | | - if( (u.ci.eNew!=u.ci.eOld) |
| 69187 | | - && (u.ci.eOld==PAGER_JOURNALMODE_WAL || u.ci.eNew==PAGER_JOURNALMODE_WAL) |
| 69243 | + if( (u.cj.eNew!=u.cj.eOld) |
| 69244 | + && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL) |
| 69188 | 69245 | ){ |
| 69189 | 69246 | if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 69190 | 69247 | rc = SQLITE_ERROR; |
| 69191 | 69248 | sqlite3SetString(&p->zErrMsg, db, |
| 69192 | 69249 | "cannot change %s wal mode from within a transaction", |
| 69193 | | - (u.ci.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69250 | + (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69194 | 69251 | ); |
| 69195 | 69252 | break; |
| 69196 | 69253 | }else{ |
| 69197 | 69254 | |
| 69198 | | - if( u.ci.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69255 | + if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69199 | 69256 | /* If leaving WAL mode, close the log file. If successful, the call |
| 69200 | 69257 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 69201 | 69258 | ** file. An EXCLUSIVE lock may still be held on the database file |
| 69202 | 69259 | ** after a successful return. |
| 69203 | 69260 | */ |
| 69204 | | - rc = sqlite3PagerCloseWal(u.ci.pPager); |
| 69261 | + rc = sqlite3PagerCloseWal(u.cj.pPager); |
| 69205 | 69262 | if( rc==SQLITE_OK ){ |
| 69206 | | - sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew); |
| 69263 | + sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew); |
| 69207 | 69264 | } |
| 69208 | | - }else if( u.ci.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69265 | + }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69209 | 69266 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 69210 | 69267 | ** as an intermediate */ |
| 69211 | | - sqlite3PagerSetJournalMode(u.ci.pPager, PAGER_JOURNALMODE_OFF); |
| 69268 | + sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF); |
| 69212 | 69269 | } |
| 69213 | 69270 | |
| 69214 | 69271 | /* Open a transaction on the database file. Regardless of the journal |
| 69215 | 69272 | ** mode, this transaction always uses a rollback journal. |
| 69216 | 69273 | */ |
| 69217 | | - assert( sqlite3BtreeIsInTrans(u.ci.pBt)==0 ); |
| 69274 | + assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 ); |
| 69218 | 69275 | if( rc==SQLITE_OK ){ |
| 69219 | | - rc = sqlite3BtreeSetVersion(u.ci.pBt, (u.ci.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69276 | + rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69220 | 69277 | } |
| 69221 | 69278 | } |
| 69222 | 69279 | } |
| 69223 | 69280 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 69224 | 69281 | |
| 69225 | 69282 | if( rc ){ |
| 69226 | | - u.ci.eNew = u.ci.eOld; |
| 69283 | + u.cj.eNew = u.cj.eOld; |
| 69227 | 69284 | } |
| 69228 | | - u.ci.eNew = sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew); |
| 69285 | + u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew); |
| 69229 | 69286 | |
| 69230 | 69287 | pOut = &aMem[pOp->p2]; |
| 69231 | 69288 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 69232 | | - pOut->z = (char *)sqlite3JournalModename(u.ci.eNew); |
| 69289 | + pOut->z = (char *)sqlite3JournalModename(u.cj.eNew); |
| 69233 | 69290 | pOut->n = sqlite3Strlen30(pOut->z); |
| 69234 | 69291 | pOut->enc = SQLITE_UTF8; |
| 69235 | 69292 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 69236 | 69293 | break; |
| 69237 | 69294 | }; |
| | @@ -69256,18 +69313,18 @@ |
| 69256 | 69313 | ** Perform a single step of the incremental vacuum procedure on |
| 69257 | 69314 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 69258 | 69315 | ** P2. Otherwise, fall through to the next instruction. |
| 69259 | 69316 | */ |
| 69260 | 69317 | case OP_IncrVacuum: { /* jump */ |
| 69261 | | -#if 0 /* local variables moved into u.cj */ |
| 69318 | +#if 0 /* local variables moved into u.ck */ |
| 69262 | 69319 | Btree *pBt; |
| 69263 | | -#endif /* local variables moved into u.cj */ |
| 69320 | +#endif /* local variables moved into u.ck */ |
| 69264 | 69321 | |
| 69265 | 69322 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69266 | 69323 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69267 | | - u.cj.pBt = db->aDb[pOp->p1].pBt; |
| 69268 | | - rc = sqlite3BtreeIncrVacuum(u.cj.pBt); |
| 69324 | + u.ck.pBt = db->aDb[pOp->p1].pBt; |
| 69325 | + rc = sqlite3BtreeIncrVacuum(u.ck.pBt); |
| 69269 | 69326 | if( rc==SQLITE_DONE ){ |
| 69270 | 69327 | pc = pOp->p2 - 1; |
| 69271 | 69328 | rc = SQLITE_OK; |
| 69272 | 69329 | } |
| 69273 | 69330 | break; |
| | @@ -69333,16 +69390,16 @@ |
| 69333 | 69390 | ** Also, whether or not P4 is set, check that this is not being called from |
| 69334 | 69391 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 69335 | 69392 | ** code will be set to SQLITE_LOCKED. |
| 69336 | 69393 | */ |
| 69337 | 69394 | case OP_VBegin: { |
| 69338 | | -#if 0 /* local variables moved into u.ck */ |
| 69395 | +#if 0 /* local variables moved into u.cl */ |
| 69339 | 69396 | VTable *pVTab; |
| 69340 | | -#endif /* local variables moved into u.ck */ |
| 69341 | | - u.ck.pVTab = pOp->p4.pVtab; |
| 69342 | | - rc = sqlite3VtabBegin(db, u.ck.pVTab); |
| 69343 | | - if( u.ck.pVTab ) importVtabErrMsg(p, u.ck.pVTab->pVtab); |
| 69397 | +#endif /* local variables moved into u.cl */ |
| 69398 | + u.cl.pVTab = pOp->p4.pVtab; |
| 69399 | + rc = sqlite3VtabBegin(db, u.cl.pVTab); |
| 69400 | + if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab); |
| 69344 | 69401 | break; |
| 69345 | 69402 | } |
| 69346 | 69403 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69347 | 69404 | |
| 69348 | 69405 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -69377,36 +69434,36 @@ |
| 69377 | 69434 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69378 | 69435 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 69379 | 69436 | ** table and stores that cursor in P1. |
| 69380 | 69437 | */ |
| 69381 | 69438 | case OP_VOpen: { |
| 69382 | | -#if 0 /* local variables moved into u.cl */ |
| 69439 | +#if 0 /* local variables moved into u.cm */ |
| 69383 | 69440 | VdbeCursor *pCur; |
| 69384 | 69441 | sqlite3_vtab_cursor *pVtabCursor; |
| 69385 | 69442 | sqlite3_vtab *pVtab; |
| 69386 | 69443 | sqlite3_module *pModule; |
| 69387 | | -#endif /* local variables moved into u.cl */ |
| 69388 | | - |
| 69389 | | - u.cl.pCur = 0; |
| 69390 | | - u.cl.pVtabCursor = 0; |
| 69391 | | - u.cl.pVtab = pOp->p4.pVtab->pVtab; |
| 69392 | | - u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule; |
| 69393 | | - assert(u.cl.pVtab && u.cl.pModule); |
| 69394 | | - rc = u.cl.pModule->xOpen(u.cl.pVtab, &u.cl.pVtabCursor); |
| 69395 | | - importVtabErrMsg(p, u.cl.pVtab); |
| 69444 | +#endif /* local variables moved into u.cm */ |
| 69445 | + |
| 69446 | + u.cm.pCur = 0; |
| 69447 | + u.cm.pVtabCursor = 0; |
| 69448 | + u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 69449 | + u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 69450 | + assert(u.cm.pVtab && u.cm.pModule); |
| 69451 | + rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor); |
| 69452 | + importVtabErrMsg(p, u.cm.pVtab); |
| 69396 | 69453 | if( SQLITE_OK==rc ){ |
| 69397 | 69454 | /* Initialize sqlite3_vtab_cursor base class */ |
| 69398 | | - u.cl.pVtabCursor->pVtab = u.cl.pVtab; |
| 69455 | + u.cm.pVtabCursor->pVtab = u.cm.pVtab; |
| 69399 | 69456 | |
| 69400 | 69457 | /* Initialise vdbe cursor object */ |
| 69401 | | - u.cl.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 69402 | | - if( u.cl.pCur ){ |
| 69403 | | - u.cl.pCur->pVtabCursor = u.cl.pVtabCursor; |
| 69404 | | - u.cl.pCur->pModule = u.cl.pVtabCursor->pVtab->pModule; |
| 69458 | + u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 69459 | + if( u.cm.pCur ){ |
| 69460 | + u.cm.pCur->pVtabCursor = u.cm.pVtabCursor; |
| 69461 | + u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule; |
| 69405 | 69462 | }else{ |
| 69406 | 69463 | db->mallocFailed = 1; |
| 69407 | | - u.cl.pModule->xClose(u.cl.pVtabCursor); |
| 69464 | + u.cm.pModule->xClose(u.cm.pVtabCursor); |
| 69408 | 69465 | } |
| 69409 | 69466 | } |
| 69410 | 69467 | break; |
| 69411 | 69468 | } |
| 69412 | 69469 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -69429,11 +69486,11 @@ |
| 69429 | 69486 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 69430 | 69487 | ** |
| 69431 | 69488 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 69432 | 69489 | */ |
| 69433 | 69490 | case OP_VFilter: { /* jump */ |
| 69434 | | -#if 0 /* local variables moved into u.cm */ |
| 69491 | +#if 0 /* local variables moved into u.cn */ |
| 69435 | 69492 | int nArg; |
| 69436 | 69493 | int iQuery; |
| 69437 | 69494 | const sqlite3_module *pModule; |
| 69438 | 69495 | Mem *pQuery; |
| 69439 | 69496 | Mem *pArgc; |
| | @@ -69441,49 +69498,49 @@ |
| 69441 | 69498 | sqlite3_vtab *pVtab; |
| 69442 | 69499 | VdbeCursor *pCur; |
| 69443 | 69500 | int res; |
| 69444 | 69501 | int i; |
| 69445 | 69502 | Mem **apArg; |
| 69446 | | -#endif /* local variables moved into u.cm */ |
| 69447 | | - |
| 69448 | | - u.cm.pQuery = &aMem[pOp->p3]; |
| 69449 | | - u.cm.pArgc = &u.cm.pQuery[1]; |
| 69450 | | - u.cm.pCur = p->apCsr[pOp->p1]; |
| 69451 | | - assert( memIsValid(u.cm.pQuery) ); |
| 69452 | | - REGISTER_TRACE(pOp->p3, u.cm.pQuery); |
| 69453 | | - assert( u.cm.pCur->pVtabCursor ); |
| 69454 | | - u.cm.pVtabCursor = u.cm.pCur->pVtabCursor; |
| 69455 | | - u.cm.pVtab = u.cm.pVtabCursor->pVtab; |
| 69456 | | - u.cm.pModule = u.cm.pVtab->pModule; |
| 69503 | +#endif /* local variables moved into u.cn */ |
| 69504 | + |
| 69505 | + u.cn.pQuery = &aMem[pOp->p3]; |
| 69506 | + u.cn.pArgc = &u.cn.pQuery[1]; |
| 69507 | + u.cn.pCur = p->apCsr[pOp->p1]; |
| 69508 | + assert( memIsValid(u.cn.pQuery) ); |
| 69509 | + REGISTER_TRACE(pOp->p3, u.cn.pQuery); |
| 69510 | + assert( u.cn.pCur->pVtabCursor ); |
| 69511 | + u.cn.pVtabCursor = u.cn.pCur->pVtabCursor; |
| 69512 | + u.cn.pVtab = u.cn.pVtabCursor->pVtab; |
| 69513 | + u.cn.pModule = u.cn.pVtab->pModule; |
| 69457 | 69514 | |
| 69458 | 69515 | /* Grab the index number and argc parameters */ |
| 69459 | | - assert( (u.cm.pQuery->flags&MEM_Int)!=0 && u.cm.pArgc->flags==MEM_Int ); |
| 69460 | | - u.cm.nArg = (int)u.cm.pArgc->u.i; |
| 69461 | | - u.cm.iQuery = (int)u.cm.pQuery->u.i; |
| 69516 | + assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int ); |
| 69517 | + u.cn.nArg = (int)u.cn.pArgc->u.i; |
| 69518 | + u.cn.iQuery = (int)u.cn.pQuery->u.i; |
| 69462 | 69519 | |
| 69463 | 69520 | /* Invoke the xFilter method */ |
| 69464 | 69521 | { |
| 69465 | | - u.cm.res = 0; |
| 69466 | | - u.cm.apArg = p->apArg; |
| 69467 | | - for(u.cm.i = 0; u.cm.i<u.cm.nArg; u.cm.i++){ |
| 69468 | | - u.cm.apArg[u.cm.i] = &u.cm.pArgc[u.cm.i+1]; |
| 69469 | | - sqlite3VdbeMemStoreType(u.cm.apArg[u.cm.i]); |
| 69522 | + u.cn.res = 0; |
| 69523 | + u.cn.apArg = p->apArg; |
| 69524 | + for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){ |
| 69525 | + u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1]; |
| 69526 | + sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]); |
| 69470 | 69527 | } |
| 69471 | 69528 | |
| 69472 | 69529 | p->inVtabMethod = 1; |
| 69473 | | - rc = u.cm.pModule->xFilter(u.cm.pVtabCursor, u.cm.iQuery, pOp->p4.z, u.cm.nArg, u.cm.apArg); |
| 69530 | + rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg); |
| 69474 | 69531 | p->inVtabMethod = 0; |
| 69475 | | - importVtabErrMsg(p, u.cm.pVtab); |
| 69532 | + importVtabErrMsg(p, u.cn.pVtab); |
| 69476 | 69533 | if( rc==SQLITE_OK ){ |
| 69477 | | - u.cm.res = u.cm.pModule->xEof(u.cm.pVtabCursor); |
| 69534 | + u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor); |
| 69478 | 69535 | } |
| 69479 | 69536 | |
| 69480 | | - if( u.cm.res ){ |
| 69537 | + if( u.cn.res ){ |
| 69481 | 69538 | pc = pOp->p2 - 1; |
| 69482 | 69539 | } |
| 69483 | 69540 | } |
| 69484 | | - u.cm.pCur->nullRow = 0; |
| 69541 | + u.cn.pCur->nullRow = 0; |
| 69485 | 69542 | |
| 69486 | 69543 | break; |
| 69487 | 69544 | } |
| 69488 | 69545 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69489 | 69546 | |
| | @@ -69493,55 +69550,55 @@ |
| 69493 | 69550 | ** Store the value of the P2-th column of |
| 69494 | 69551 | ** the row of the virtual-table that the |
| 69495 | 69552 | ** P1 cursor is pointing to into register P3. |
| 69496 | 69553 | */ |
| 69497 | 69554 | case OP_VColumn: { |
| 69498 | | -#if 0 /* local variables moved into u.cn */ |
| 69555 | +#if 0 /* local variables moved into u.co */ |
| 69499 | 69556 | sqlite3_vtab *pVtab; |
| 69500 | 69557 | const sqlite3_module *pModule; |
| 69501 | 69558 | Mem *pDest; |
| 69502 | 69559 | sqlite3_context sContext; |
| 69503 | | -#endif /* local variables moved into u.cn */ |
| 69560 | +#endif /* local variables moved into u.co */ |
| 69504 | 69561 | |
| 69505 | 69562 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 69506 | 69563 | assert( pCur->pVtabCursor ); |
| 69507 | 69564 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69508 | | - u.cn.pDest = &aMem[pOp->p3]; |
| 69509 | | - memAboutToChange(p, u.cn.pDest); |
| 69565 | + u.co.pDest = &aMem[pOp->p3]; |
| 69566 | + memAboutToChange(p, u.co.pDest); |
| 69510 | 69567 | if( pCur->nullRow ){ |
| 69511 | | - sqlite3VdbeMemSetNull(u.cn.pDest); |
| 69568 | + sqlite3VdbeMemSetNull(u.co.pDest); |
| 69512 | 69569 | break; |
| 69513 | 69570 | } |
| 69514 | | - u.cn.pVtab = pCur->pVtabCursor->pVtab; |
| 69515 | | - u.cn.pModule = u.cn.pVtab->pModule; |
| 69516 | | - assert( u.cn.pModule->xColumn ); |
| 69517 | | - memset(&u.cn.sContext, 0, sizeof(u.cn.sContext)); |
| 69571 | + u.co.pVtab = pCur->pVtabCursor->pVtab; |
| 69572 | + u.co.pModule = u.co.pVtab->pModule; |
| 69573 | + assert( u.co.pModule->xColumn ); |
| 69574 | + memset(&u.co.sContext, 0, sizeof(u.co.sContext)); |
| 69518 | 69575 | |
| 69519 | 69576 | /* The output cell may already have a buffer allocated. Move |
| 69520 | | - ** the current contents to u.cn.sContext.s so in case the user-function |
| 69577 | + ** the current contents to u.co.sContext.s so in case the user-function |
| 69521 | 69578 | ** can use the already allocated buffer instead of allocating a |
| 69522 | 69579 | ** new one. |
| 69523 | 69580 | */ |
| 69524 | | - sqlite3VdbeMemMove(&u.cn.sContext.s, u.cn.pDest); |
| 69525 | | - MemSetTypeFlag(&u.cn.sContext.s, MEM_Null); |
| 69581 | + sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest); |
| 69582 | + MemSetTypeFlag(&u.co.sContext.s, MEM_Null); |
| 69526 | 69583 | |
| 69527 | | - rc = u.cn.pModule->xColumn(pCur->pVtabCursor, &u.cn.sContext, pOp->p2); |
| 69528 | | - importVtabErrMsg(p, u.cn.pVtab); |
| 69529 | | - if( u.cn.sContext.isError ){ |
| 69530 | | - rc = u.cn.sContext.isError; |
| 69584 | + rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2); |
| 69585 | + importVtabErrMsg(p, u.co.pVtab); |
| 69586 | + if( u.co.sContext.isError ){ |
| 69587 | + rc = u.co.sContext.isError; |
| 69531 | 69588 | } |
| 69532 | 69589 | |
| 69533 | 69590 | /* Copy the result of the function to the P3 register. We |
| 69534 | 69591 | ** do this regardless of whether or not an error occurred to ensure any |
| 69535 | | - ** dynamic allocation in u.cn.sContext.s (a Mem struct) is released. |
| 69592 | + ** dynamic allocation in u.co.sContext.s (a Mem struct) is released. |
| 69536 | 69593 | */ |
| 69537 | | - sqlite3VdbeChangeEncoding(&u.cn.sContext.s, encoding); |
| 69538 | | - sqlite3VdbeMemMove(u.cn.pDest, &u.cn.sContext.s); |
| 69539 | | - REGISTER_TRACE(pOp->p3, u.cn.pDest); |
| 69540 | | - UPDATE_MAX_BLOBSIZE(u.cn.pDest); |
| 69594 | + sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding); |
| 69595 | + sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s); |
| 69596 | + REGISTER_TRACE(pOp->p3, u.co.pDest); |
| 69597 | + UPDATE_MAX_BLOBSIZE(u.co.pDest); |
| 69541 | 69598 | |
| 69542 | | - if( sqlite3VdbeMemTooBig(u.cn.pDest) ){ |
| 69599 | + if( sqlite3VdbeMemTooBig(u.co.pDest) ){ |
| 69543 | 69600 | goto too_big; |
| 69544 | 69601 | } |
| 69545 | 69602 | break; |
| 69546 | 69603 | } |
| 69547 | 69604 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -69552,42 +69609,42 @@ |
| 69552 | 69609 | ** Advance virtual table P1 to the next row in its result set and |
| 69553 | 69610 | ** jump to instruction P2. Or, if the virtual table has reached |
| 69554 | 69611 | ** the end of its result set, then fall through to the next instruction. |
| 69555 | 69612 | */ |
| 69556 | 69613 | case OP_VNext: { /* jump */ |
| 69557 | | -#if 0 /* local variables moved into u.co */ |
| 69614 | +#if 0 /* local variables moved into u.cp */ |
| 69558 | 69615 | sqlite3_vtab *pVtab; |
| 69559 | 69616 | const sqlite3_module *pModule; |
| 69560 | 69617 | int res; |
| 69561 | 69618 | VdbeCursor *pCur; |
| 69562 | | -#endif /* local variables moved into u.co */ |
| 69619 | +#endif /* local variables moved into u.cp */ |
| 69563 | 69620 | |
| 69564 | | - u.co.res = 0; |
| 69565 | | - u.co.pCur = p->apCsr[pOp->p1]; |
| 69566 | | - assert( u.co.pCur->pVtabCursor ); |
| 69567 | | - if( u.co.pCur->nullRow ){ |
| 69621 | + u.cp.res = 0; |
| 69622 | + u.cp.pCur = p->apCsr[pOp->p1]; |
| 69623 | + assert( u.cp.pCur->pVtabCursor ); |
| 69624 | + if( u.cp.pCur->nullRow ){ |
| 69568 | 69625 | break; |
| 69569 | 69626 | } |
| 69570 | | - u.co.pVtab = u.co.pCur->pVtabCursor->pVtab; |
| 69571 | | - u.co.pModule = u.co.pVtab->pModule; |
| 69572 | | - assert( u.co.pModule->xNext ); |
| 69627 | + u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab; |
| 69628 | + u.cp.pModule = u.cp.pVtab->pModule; |
| 69629 | + assert( u.cp.pModule->xNext ); |
| 69573 | 69630 | |
| 69574 | 69631 | /* Invoke the xNext() method of the module. There is no way for the |
| 69575 | 69632 | ** underlying implementation to return an error if one occurs during |
| 69576 | 69633 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 69577 | 69634 | ** data is available) and the error code returned when xColumn or |
| 69578 | 69635 | ** some other method is next invoked on the save virtual table cursor. |
| 69579 | 69636 | */ |
| 69580 | 69637 | p->inVtabMethod = 1; |
| 69581 | | - rc = u.co.pModule->xNext(u.co.pCur->pVtabCursor); |
| 69638 | + rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor); |
| 69582 | 69639 | p->inVtabMethod = 0; |
| 69583 | | - importVtabErrMsg(p, u.co.pVtab); |
| 69640 | + importVtabErrMsg(p, u.cp.pVtab); |
| 69584 | 69641 | if( rc==SQLITE_OK ){ |
| 69585 | | - u.co.res = u.co.pModule->xEof(u.co.pCur->pVtabCursor); |
| 69642 | + u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor); |
| 69586 | 69643 | } |
| 69587 | 69644 | |
| 69588 | | - if( !u.co.res ){ |
| 69645 | + if( !u.cp.res ){ |
| 69589 | 69646 | /* If there is data, jump to P2 */ |
| 69590 | 69647 | pc = pOp->p2 - 1; |
| 69591 | 69648 | } |
| 69592 | 69649 | break; |
| 69593 | 69650 | } |
| | @@ -69599,28 +69656,28 @@ |
| 69599 | 69656 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69600 | 69657 | ** This opcode invokes the corresponding xRename method. The value |
| 69601 | 69658 | ** in register P1 is passed as the zName argument to the xRename method. |
| 69602 | 69659 | */ |
| 69603 | 69660 | case OP_VRename: { |
| 69604 | | -#if 0 /* local variables moved into u.cp */ |
| 69661 | +#if 0 /* local variables moved into u.cq */ |
| 69605 | 69662 | sqlite3_vtab *pVtab; |
| 69606 | 69663 | Mem *pName; |
| 69607 | | -#endif /* local variables moved into u.cp */ |
| 69608 | | - |
| 69609 | | - u.cp.pVtab = pOp->p4.pVtab->pVtab; |
| 69610 | | - u.cp.pName = &aMem[pOp->p1]; |
| 69611 | | - assert( u.cp.pVtab->pModule->xRename ); |
| 69612 | | - assert( memIsValid(u.cp.pName) ); |
| 69613 | | - REGISTER_TRACE(pOp->p1, u.cp.pName); |
| 69614 | | - assert( u.cp.pName->flags & MEM_Str ); |
| 69615 | | - testcase( u.cp.pName->enc==SQLITE_UTF8 ); |
| 69616 | | - testcase( u.cp.pName->enc==SQLITE_UTF16BE ); |
| 69617 | | - testcase( u.cp.pName->enc==SQLITE_UTF16LE ); |
| 69618 | | - rc = sqlite3VdbeChangeEncoding(u.cp.pName, SQLITE_UTF8); |
| 69619 | | - if( rc==SQLITE_OK ){ |
| 69620 | | - rc = u.cp.pVtab->pModule->xRename(u.cp.pVtab, u.cp.pName->z); |
| 69621 | | - importVtabErrMsg(p, u.cp.pVtab); |
| 69664 | +#endif /* local variables moved into u.cq */ |
| 69665 | + |
| 69666 | + u.cq.pVtab = pOp->p4.pVtab->pVtab; |
| 69667 | + u.cq.pName = &aMem[pOp->p1]; |
| 69668 | + assert( u.cq.pVtab->pModule->xRename ); |
| 69669 | + assert( memIsValid(u.cq.pName) ); |
| 69670 | + REGISTER_TRACE(pOp->p1, u.cq.pName); |
| 69671 | + assert( u.cq.pName->flags & MEM_Str ); |
| 69672 | + testcase( u.cq.pName->enc==SQLITE_UTF8 ); |
| 69673 | + testcase( u.cq.pName->enc==SQLITE_UTF16BE ); |
| 69674 | + testcase( u.cq.pName->enc==SQLITE_UTF16LE ); |
| 69675 | + rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8); |
| 69676 | + if( rc==SQLITE_OK ){ |
| 69677 | + rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z); |
| 69678 | + importVtabErrMsg(p, u.cq.pVtab); |
| 69622 | 69679 | p->expired = 0; |
| 69623 | 69680 | } |
| 69624 | 69681 | break; |
| 69625 | 69682 | } |
| 69626 | 69683 | #endif |
| | @@ -69648,45 +69705,45 @@ |
| 69648 | 69705 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 69649 | 69706 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 69650 | 69707 | ** is set to the value of the rowid for the row just inserted. |
| 69651 | 69708 | */ |
| 69652 | 69709 | case OP_VUpdate: { |
| 69653 | | -#if 0 /* local variables moved into u.cq */ |
| 69710 | +#if 0 /* local variables moved into u.cr */ |
| 69654 | 69711 | sqlite3_vtab *pVtab; |
| 69655 | 69712 | sqlite3_module *pModule; |
| 69656 | 69713 | int nArg; |
| 69657 | 69714 | int i; |
| 69658 | 69715 | sqlite_int64 rowid; |
| 69659 | 69716 | Mem **apArg; |
| 69660 | 69717 | Mem *pX; |
| 69661 | | -#endif /* local variables moved into u.cq */ |
| 69718 | +#endif /* local variables moved into u.cr */ |
| 69662 | 69719 | |
| 69663 | 69720 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 69664 | 69721 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 69665 | 69722 | ); |
| 69666 | | - u.cq.pVtab = pOp->p4.pVtab->pVtab; |
| 69667 | | - u.cq.pModule = (sqlite3_module *)u.cq.pVtab->pModule; |
| 69668 | | - u.cq.nArg = pOp->p2; |
| 69723 | + u.cr.pVtab = pOp->p4.pVtab->pVtab; |
| 69724 | + u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule; |
| 69725 | + u.cr.nArg = pOp->p2; |
| 69669 | 69726 | assert( pOp->p4type==P4_VTAB ); |
| 69670 | | - if( ALWAYS(u.cq.pModule->xUpdate) ){ |
| 69727 | + if( ALWAYS(u.cr.pModule->xUpdate) ){ |
| 69671 | 69728 | u8 vtabOnConflict = db->vtabOnConflict; |
| 69672 | | - u.cq.apArg = p->apArg; |
| 69673 | | - u.cq.pX = &aMem[pOp->p3]; |
| 69674 | | - for(u.cq.i=0; u.cq.i<u.cq.nArg; u.cq.i++){ |
| 69675 | | - assert( memIsValid(u.cq.pX) ); |
| 69676 | | - memAboutToChange(p, u.cq.pX); |
| 69677 | | - sqlite3VdbeMemStoreType(u.cq.pX); |
| 69678 | | - u.cq.apArg[u.cq.i] = u.cq.pX; |
| 69679 | | - u.cq.pX++; |
| 69729 | + u.cr.apArg = p->apArg; |
| 69730 | + u.cr.pX = &aMem[pOp->p3]; |
| 69731 | + for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){ |
| 69732 | + assert( memIsValid(u.cr.pX) ); |
| 69733 | + memAboutToChange(p, u.cr.pX); |
| 69734 | + sqlite3VdbeMemStoreType(u.cr.pX); |
| 69735 | + u.cr.apArg[u.cr.i] = u.cr.pX; |
| 69736 | + u.cr.pX++; |
| 69680 | 69737 | } |
| 69681 | 69738 | db->vtabOnConflict = pOp->p5; |
| 69682 | | - rc = u.cq.pModule->xUpdate(u.cq.pVtab, u.cq.nArg, u.cq.apArg, &u.cq.rowid); |
| 69739 | + rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid); |
| 69683 | 69740 | db->vtabOnConflict = vtabOnConflict; |
| 69684 | | - importVtabErrMsg(p, u.cq.pVtab); |
| 69741 | + importVtabErrMsg(p, u.cr.pVtab); |
| 69685 | 69742 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 69686 | | - assert( u.cq.nArg>1 && u.cq.apArg[0] && (u.cq.apArg[0]->flags&MEM_Null) ); |
| 69687 | | - db->lastRowid = lastRowid = u.cq.rowid; |
| 69743 | + assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) ); |
| 69744 | + db->lastRowid = lastRowid = u.cr.rowid; |
| 69688 | 69745 | } |
| 69689 | 69746 | if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 69690 | 69747 | if( pOp->p5==OE_Ignore ){ |
| 69691 | 69748 | rc = SQLITE_OK; |
| 69692 | 69749 | }else{ |
| | @@ -69742,28 +69799,28 @@ |
| 69742 | 69799 | ** |
| 69743 | 69800 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 69744 | 69801 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 69745 | 69802 | */ |
| 69746 | 69803 | case OP_Trace: { |
| 69747 | | -#if 0 /* local variables moved into u.cr */ |
| 69804 | +#if 0 /* local variables moved into u.cs */ |
| 69748 | 69805 | char *zTrace; |
| 69749 | 69806 | char *z; |
| 69750 | | -#endif /* local variables moved into u.cr */ |
| 69807 | +#endif /* local variables moved into u.cs */ |
| 69751 | 69808 | |
| 69752 | 69809 | if( db->xTrace |
| 69753 | 69810 | && !p->doingRerun |
| 69754 | | - && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69811 | + && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69755 | 69812 | ){ |
| 69756 | | - u.cr.z = sqlite3VdbeExpandSql(p, u.cr.zTrace); |
| 69757 | | - db->xTrace(db->pTraceArg, u.cr.z); |
| 69758 | | - sqlite3DbFree(db, u.cr.z); |
| 69813 | + u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace); |
| 69814 | + db->xTrace(db->pTraceArg, u.cs.z); |
| 69815 | + sqlite3DbFree(db, u.cs.z); |
| 69759 | 69816 | } |
| 69760 | 69817 | #ifdef SQLITE_DEBUG |
| 69761 | 69818 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 69762 | | - && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69819 | + && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69763 | 69820 | ){ |
| 69764 | | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cr.zTrace); |
| 69821 | + sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace); |
| 69765 | 69822 | } |
| 69766 | 69823 | #endif /* SQLITE_DEBUG */ |
| 69767 | 69824 | break; |
| 69768 | 69825 | } |
| 69769 | 69826 | #endif |
| | @@ -74733,27 +74790,36 @@ |
| 74733 | 74790 | return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); |
| 74734 | 74791 | } |
| 74735 | 74792 | |
| 74736 | 74793 | /* |
| 74737 | 74794 | ** This function is used by the implementation of the IN (...) operator. |
| 74738 | | -** It's job is to find or create a b-tree structure that may be used |
| 74739 | | -** either to test for membership of the (...) set or to iterate through |
| 74740 | | -** its members, skipping duplicates. |
| 74795 | +** The pX parameter is the expression on the RHS of the IN operator, which |
| 74796 | +** might be either a list of expressions or a subquery. |
| 74741 | 74797 | ** |
| 74742 | | -** The index of the cursor opened on the b-tree (database table, database index |
| 74743 | | -** or ephermal table) is stored in pX->iTable before this function returns. |
| 74798 | +** The job of this routine is to find or create a b-tree object that can |
| 74799 | +** be used either to test for membership in the RHS set or to iterate through |
| 74800 | +** all members of the RHS set, skipping duplicates. |
| 74801 | +** |
| 74802 | +** A cursor is opened on the b-tree object that the RHS of the IN operator |
| 74803 | +** and pX->iTable is set to the index of that cursor. |
| 74804 | +** |
| 74744 | 74805 | ** The returned value of this function indicates the b-tree type, as follows: |
| 74745 | 74806 | ** |
| 74746 | 74807 | ** IN_INDEX_ROWID - The cursor was opened on a database table. |
| 74747 | 74808 | ** IN_INDEX_INDEX - The cursor was opened on a database index. |
| 74748 | 74809 | ** IN_INDEX_EPH - The cursor was opened on a specially created and |
| 74749 | 74810 | ** populated epheremal table. |
| 74750 | 74811 | ** |
| 74751 | | -** An existing b-tree may only be used if the SELECT is of the simple |
| 74752 | | -** form: |
| 74812 | +** An existing b-tree might be used if the RHS expression pX is a simple |
| 74813 | +** subquery such as: |
| 74753 | 74814 | ** |
| 74754 | 74815 | ** SELECT <column> FROM <table> |
| 74816 | +** |
| 74817 | +** If the RHS of the IN operator is a list or a more complex subquery, then |
| 74818 | +** an ephemeral table might need to be generated from the RHS and then |
| 74819 | +** pX->iTable made to point to the ephermeral table instead of an |
| 74820 | +** existing table. |
| 74755 | 74821 | ** |
| 74756 | 74822 | ** If the prNotFound parameter is 0, then the b-tree will be used to iterate |
| 74757 | 74823 | ** through the set members, skipping any duplicates. In this case an |
| 74758 | 74824 | ** epheremal table must be used unless the selected <column> is guaranteed |
| 74759 | 74825 | ** to be unique - either because it is an INTEGER PRIMARY KEY or it |
| | @@ -74846,12 +74912,11 @@ |
| 74846 | 74912 | |
| 74847 | 74913 | /* Check that the affinity that will be used to perform the |
| 74848 | 74914 | ** comparison is the same as the affinity of the column. If |
| 74849 | 74915 | ** it is not, it is not possible to use any index. |
| 74850 | 74916 | */ |
| 74851 | | - char aff = comparisonAffinity(pX); |
| 74852 | | - int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE); |
| 74917 | + int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity); |
| 74853 | 74918 | |
| 74854 | 74919 | for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ |
| 74855 | 74920 | if( (pIdx->aiColumn[0]==iCol) |
| 74856 | 74921 | && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq |
| 74857 | 74922 | && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) |
| | @@ -75371,11 +75436,11 @@ |
| 75371 | 75436 | |
| 75372 | 75437 | /* The SQLITE_ColumnCache flag disables the column cache. This is used |
| 75373 | 75438 | ** for testing only - to verify that SQLite always gets the same answer |
| 75374 | 75439 | ** with and without the column cache. |
| 75375 | 75440 | */ |
| 75376 | | - if( pParse->db->flags & SQLITE_ColumnCache ) return; |
| 75441 | + if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; |
| 75377 | 75442 | |
| 75378 | 75443 | /* First replace any existing entry. |
| 75379 | 75444 | ** |
| 75380 | 75445 | ** Actually, the way the column cache is currently used, we are guaranteed |
| 75381 | 75446 | ** that the object will never already be in cache. Verify this guarantee. |
| | @@ -75568,32 +75633,20 @@ |
| 75568 | 75633 | ** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. |
| 75569 | 75634 | */ |
| 75570 | 75635 | SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ |
| 75571 | 75636 | int i; |
| 75572 | 75637 | struct yColCache *p; |
| 75573 | | - if( NEVER(iFrom==iTo) ) return; |
| 75574 | | - sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); |
| 75638 | + assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); |
| 75639 | + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1); |
| 75575 | 75640 | for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){ |
| 75576 | 75641 | int x = p->iReg; |
| 75577 | 75642 | if( x>=iFrom && x<iFrom+nReg ){ |
| 75578 | 75643 | p->iReg += iTo-iFrom; |
| 75579 | 75644 | } |
| 75580 | 75645 | } |
| 75581 | 75646 | } |
| 75582 | 75647 | |
| 75583 | | -/* |
| 75584 | | -** Generate code to copy content from registers iFrom...iFrom+nReg-1 |
| 75585 | | -** over to iTo..iTo+nReg-1. |
| 75586 | | -*/ |
| 75587 | | -SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){ |
| 75588 | | - int i; |
| 75589 | | - if( NEVER(iFrom==iTo) ) return; |
| 75590 | | - for(i=0; i<nReg; i++){ |
| 75591 | | - sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i); |
| 75592 | | - } |
| 75593 | | -} |
| 75594 | | - |
| 75595 | 75648 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 75596 | 75649 | /* |
| 75597 | 75650 | ** Return true if any register in the range iFrom..iTo (inclusive) |
| 75598 | 75651 | ** is used as part of the column cache. |
| 75599 | 75652 | ** |
| | @@ -76699,11 +76752,11 @@ |
| 76699 | 76752 | ** precomputed into registers or if they are inserted in-line. |
| 76700 | 76753 | */ |
| 76701 | 76754 | SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ |
| 76702 | 76755 | Walker w; |
| 76703 | 76756 | if( pParse->cookieGoto ) return; |
| 76704 | | - if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return; |
| 76757 | + if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return; |
| 76705 | 76758 | w.xExprCallback = evalConstExpr; |
| 76706 | 76759 | w.xSelectCallback = 0; |
| 76707 | 76760 | w.pParse = pParse; |
| 76708 | 76761 | sqlite3WalkExpr(&w, pExpr); |
| 76709 | 76762 | } |
| | @@ -85180,11 +85233,13 @@ |
| 85180 | 85233 | sqlite3ColumnDefault(v, pTab, idx, -1); |
| 85181 | 85234 | } |
| 85182 | 85235 | } |
| 85183 | 85236 | if( doMakeRec ){ |
| 85184 | 85237 | const char *zAff; |
| 85185 | | - if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){ |
| 85238 | + if( pTab->pSelect |
| 85239 | + || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt) |
| 85240 | + ){ |
| 85186 | 85241 | zAff = 0; |
| 85187 | 85242 | }else{ |
| 85188 | 85243 | zAff = sqlite3IndexAffinityStr(v, pIdx); |
| 85189 | 85244 | } |
| 85190 | 85245 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); |
| | @@ -92422,11 +92477,11 @@ |
| 92422 | 92477 | sqlite3VdbeChangeP5(v, (u8)i); |
| 92423 | 92478 | addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); |
| 92424 | 92479 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, |
| 92425 | 92480 | sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), |
| 92426 | 92481 | P4_DYNAMIC); |
| 92427 | | - sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); |
| 92482 | + sqlite3VdbeAddOp2(v, OP_Move, 2, 4); |
| 92428 | 92483 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); |
| 92429 | 92484 | sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); |
| 92430 | 92485 | sqlite3VdbeJumpHere(v, addr); |
| 92431 | 92486 | |
| 92432 | 92487 | /* Make sure all the indices are constructed correctly. |
| | @@ -92725,10 +92780,26 @@ |
| 92725 | 92780 | */ |
| 92726 | 92781 | if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){ |
| 92727 | 92782 | sqlite3_db_release_memory(db); |
| 92728 | 92783 | }else |
| 92729 | 92784 | |
| 92785 | + /* |
| 92786 | + ** PRAGMA busy_timeout |
| 92787 | + ** PRAGMA busy_timeout = N |
| 92788 | + ** |
| 92789 | + ** Call sqlite3_busy_timeout(db, N). Return the current timeout value |
| 92790 | + ** if one is set. If no busy handler or a different busy handler is set |
| 92791 | + ** then 0 is returned. Setting the busy_timeout to 0 or negative |
| 92792 | + ** disables the timeout. |
| 92793 | + */ |
| 92794 | + if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){ |
| 92795 | + if( zRight ){ |
| 92796 | + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); |
| 92797 | + } |
| 92798 | + returnSingleInt(pParse, "timeout", db->busyTimeout); |
| 92799 | + }else |
| 92800 | + |
| 92730 | 92801 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) |
| 92731 | 92802 | /* |
| 92732 | 92803 | ** Report the current state of file logs for all databases |
| 92733 | 92804 | */ |
| 92734 | 92805 | if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ |
| | @@ -92955,11 +93026,13 @@ |
| 92955 | 93026 | ** indicate success or failure. |
| 92956 | 93027 | */ |
| 92957 | 93028 | static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ |
| 92958 | 93029 | int rc; |
| 92959 | 93030 | int i; |
| 93031 | +#ifndef SQLITE_OMIT_DEPRECATED |
| 92960 | 93032 | int size; |
| 93033 | +#endif |
| 92961 | 93034 | Table *pTab; |
| 92962 | 93035 | Db *pDb; |
| 92963 | 93036 | char const *azArg[4]; |
| 92964 | 93037 | int meta[5]; |
| 92965 | 93038 | InitData initData; |
| | @@ -94210,10 +94283,23 @@ |
| 94210 | 94283 | return 0; |
| 94211 | 94284 | } |
| 94212 | 94285 | } |
| 94213 | 94286 | #endif |
| 94214 | 94287 | |
| 94288 | +/* |
| 94289 | +** An instance of the following object is used to record information about |
| 94290 | +** how to process the DISTINCT keyword, to simplify passing that information |
| 94291 | +** into the selectInnerLoop() routine. |
| 94292 | +*/ |
| 94293 | +typedef struct DistinctCtx DistinctCtx; |
| 94294 | +struct DistinctCtx { |
| 94295 | + u8 isTnct; /* True if the DISTINCT keyword is present */ |
| 94296 | + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ |
| 94297 | + int tabTnct; /* Ephemeral table used for DISTINCT processing */ |
| 94298 | + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ |
| 94299 | +}; |
| 94300 | + |
| 94215 | 94301 | /* |
| 94216 | 94302 | ** This routine generates the code for the inside of the inner loop |
| 94217 | 94303 | ** of a SELECT. |
| 94218 | 94304 | ** |
| 94219 | 94305 | ** If srcTab and nColumn are both zero, then the pEList expressions |
| | @@ -94226,11 +94312,11 @@ |
| 94226 | 94312 | Select *p, /* The complete select statement being coded */ |
| 94227 | 94313 | ExprList *pEList, /* List of values being extracted */ |
| 94228 | 94314 | int srcTab, /* Pull data from this table */ |
| 94229 | 94315 | int nColumn, /* Number of columns in the source table */ |
| 94230 | 94316 | ExprList *pOrderBy, /* If not NULL, sort results using this key */ |
| 94231 | | - int distinct, /* If >=0, make sure results are distinct */ |
| 94317 | + DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ |
| 94232 | 94318 | SelectDest *pDest, /* How to dispose of the results */ |
| 94233 | 94319 | int iContinue, /* Jump here to continue with next row */ |
| 94234 | 94320 | int iBreak /* Jump here to break out of the inner loop */ |
| 94235 | 94321 | ){ |
| 94236 | 94322 | Vdbe *v = pParse->pVdbe; |
| | @@ -94242,11 +94328,11 @@ |
| 94242 | 94328 | int nResultCol; /* Number of result columns */ |
| 94243 | 94329 | |
| 94244 | 94330 | assert( v ); |
| 94245 | 94331 | if( NEVER(v==0) ) return; |
| 94246 | 94332 | assert( pEList!=0 ); |
| 94247 | | - hasDistinct = distinct>=0; |
| 94333 | + hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; |
| 94248 | 94334 | if( pOrderBy==0 && !hasDistinct ){ |
| 94249 | 94335 | codeOffset(v, p, iContinue); |
| 94250 | 94336 | } |
| 94251 | 94337 | |
| 94252 | 94338 | /* Pull the requested columns. |
| | @@ -94282,11 +94368,59 @@ |
| 94282 | 94368 | ** part of the result. |
| 94283 | 94369 | */ |
| 94284 | 94370 | if( hasDistinct ){ |
| 94285 | 94371 | assert( pEList!=0 ); |
| 94286 | 94372 | assert( pEList->nExpr==nColumn ); |
| 94287 | | - codeDistinct(pParse, distinct, iContinue, nColumn, regResult); |
| 94373 | + switch( pDistinct->eTnctType ){ |
| 94374 | + case WHERE_DISTINCT_ORDERED: { |
| 94375 | + VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 94376 | + int iJump; /* Jump destination */ |
| 94377 | + int regPrev; /* Previous row content */ |
| 94378 | + |
| 94379 | + /* Allocate space for the previous row */ |
| 94380 | + regPrev = pParse->nMem+1; |
| 94381 | + pParse->nMem += nColumn; |
| 94382 | + |
| 94383 | + /* Change the OP_OpenEphemeral coded earlier to an OP_Null |
| 94384 | + ** sets the MEM_Cleared bit on the first register of the |
| 94385 | + ** previous value. This will cause the OP_Ne below to always |
| 94386 | + ** fail on the first iteration of the loop even if the first |
| 94387 | + ** row is all NULLs. |
| 94388 | + */ |
| 94389 | + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); |
| 94390 | + pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); |
| 94391 | + pOp->opcode = OP_Null; |
| 94392 | + pOp->p1 = 1; |
| 94393 | + pOp->p2 = regPrev; |
| 94394 | + |
| 94395 | + iJump = sqlite3VdbeCurrentAddr(v) + nColumn; |
| 94396 | + for(i=0; i<nColumn; i++){ |
| 94397 | + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr); |
| 94398 | + if( i<nColumn-1 ){ |
| 94399 | + sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i); |
| 94400 | + }else{ |
| 94401 | + sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i); |
| 94402 | + } |
| 94403 | + sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); |
| 94404 | + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 94405 | + } |
| 94406 | + assert( sqlite3VdbeCurrentAddr(v)==iJump ); |
| 94407 | + sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1); |
| 94408 | + break; |
| 94409 | + } |
| 94410 | + |
| 94411 | + case WHERE_DISTINCT_UNIQUE: { |
| 94412 | + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); |
| 94413 | + break; |
| 94414 | + } |
| 94415 | + |
| 94416 | + default: { |
| 94417 | + assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); |
| 94418 | + codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult); |
| 94419 | + break; |
| 94420 | + } |
| 94421 | + } |
| 94288 | 94422 | if( pOrderBy==0 ){ |
| 94289 | 94423 | codeOffset(v, p, iContinue); |
| 94290 | 94424 | } |
| 94291 | 94425 | } |
| 94292 | 94426 | |
| | @@ -94340,20 +94474,21 @@ |
| 94340 | 94474 | ** then there should be a single item on the stack. Write this |
| 94341 | 94475 | ** item into the set table with bogus data. |
| 94342 | 94476 | */ |
| 94343 | 94477 | case SRT_Set: { |
| 94344 | 94478 | assert( nColumn==1 ); |
| 94345 | | - p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); |
| 94479 | + pDest->affSdst = |
| 94480 | + sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); |
| 94346 | 94481 | if( pOrderBy ){ |
| 94347 | 94482 | /* At first glance you would think we could optimize out the |
| 94348 | 94483 | ** ORDER BY in this case since the order of entries in the set |
| 94349 | 94484 | ** does not matter. But there might be a LIMIT clause, in which |
| 94350 | 94485 | ** case the order does matter */ |
| 94351 | 94486 | pushOntoSorter(pParse, pOrderBy, p, regResult); |
| 94352 | 94487 | }else{ |
| 94353 | 94488 | int r1 = sqlite3GetTempReg(pParse); |
| 94354 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); |
| 94489 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1); |
| 94355 | 94490 | sqlite3ExprCacheAffinityChange(pParse, regResult, 1); |
| 94356 | 94491 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); |
| 94357 | 94492 | sqlite3ReleaseTempReg(pParse, r1); |
| 94358 | 94493 | } |
| 94359 | 94494 | break; |
| | @@ -94616,11 +94751,12 @@ |
| 94616 | 94751 | break; |
| 94617 | 94752 | } |
| 94618 | 94753 | #ifndef SQLITE_OMIT_SUBQUERY |
| 94619 | 94754 | case SRT_Set: { |
| 94620 | 94755 | assert( nColumn==1 ); |
| 94621 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1); |
| 94756 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, |
| 94757 | + &pDest->affSdst, 1); |
| 94622 | 94758 | sqlite3ExprCacheAffinityChange(pParse, regRow, 1); |
| 94623 | 94759 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); |
| 94624 | 94760 | break; |
| 94625 | 94761 | } |
| 94626 | 94762 | case SRT_Mem: { |
| | @@ -95453,11 +95589,11 @@ |
| 95453 | 95589 | iCont = sqlite3VdbeMakeLabel(v); |
| 95454 | 95590 | computeLimitRegisters(pParse, p, iBreak); |
| 95455 | 95591 | sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); |
| 95456 | 95592 | iStart = sqlite3VdbeCurrentAddr(v); |
| 95457 | 95593 | selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, |
| 95458 | | - 0, -1, &dest, iCont, iBreak); |
| 95594 | + 0, 0, &dest, iCont, iBreak); |
| 95459 | 95595 | sqlite3VdbeResolveLabel(v, iCont); |
| 95460 | 95596 | sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); |
| 95461 | 95597 | sqlite3VdbeResolveLabel(v, iBreak); |
| 95462 | 95598 | sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); |
| 95463 | 95599 | } |
| | @@ -95531,11 +95667,11 @@ |
| 95531 | 95667 | r1 = sqlite3GetTempReg(pParse); |
| 95532 | 95668 | iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); |
| 95533 | 95669 | sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); |
| 95534 | 95670 | sqlite3ReleaseTempReg(pParse, r1); |
| 95535 | 95671 | selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, |
| 95536 | | - 0, -1, &dest, iCont, iBreak); |
| 95672 | + 0, 0, &dest, iCont, iBreak); |
| 95537 | 95673 | sqlite3VdbeResolveLabel(v, iCont); |
| 95538 | 95674 | sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); |
| 95539 | 95675 | sqlite3VdbeResolveLabel(v, iBreak); |
| 95540 | 95676 | sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); |
| 95541 | 95677 | sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); |
| | @@ -95651,11 +95787,11 @@ |
| 95651 | 95787 | j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); |
| 95652 | 95788 | j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, |
| 95653 | 95789 | (char*)pKeyInfo, p4type); |
| 95654 | 95790 | sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); |
| 95655 | 95791 | sqlite3VdbeJumpHere(v, j1); |
| 95656 | | - sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst); |
| 95792 | + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); |
| 95657 | 95793 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); |
| 95658 | 95794 | } |
| 95659 | 95795 | if( pParse->db->mallocFailed ) return 0; |
| 95660 | 95796 | |
| 95661 | 95797 | /* Suppress the first OFFSET entries if there is an OFFSET clause |
| | @@ -95686,14 +95822,14 @@ |
| 95686 | 95822 | ** item into the set table with bogus data. |
| 95687 | 95823 | */ |
| 95688 | 95824 | case SRT_Set: { |
| 95689 | 95825 | int r1; |
| 95690 | 95826 | assert( pIn->nSdst==1 ); |
| 95691 | | - p->affinity = |
| 95827 | + pDest->affSdst = |
| 95692 | 95828 | sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); |
| 95693 | 95829 | r1 = sqlite3GetTempReg(pParse); |
| 95694 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1); |
| 95830 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1); |
| 95695 | 95831 | sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); |
| 95696 | 95832 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); |
| 95697 | 95833 | sqlite3ReleaseTempReg(pParse, r1); |
| 95698 | 95834 | break; |
| 95699 | 95835 | } |
| | @@ -96431,11 +96567,11 @@ |
| 96431 | 96567 | |
| 96432 | 96568 | /* Check to see if flattening is permitted. Return 0 if not. |
| 96433 | 96569 | */ |
| 96434 | 96570 | assert( p!=0 ); |
| 96435 | 96571 | assert( p->pPrior==0 ); /* Unable to flatten compound queries */ |
| 96436 | | - if( db->flags & SQLITE_QueryFlattener ) return 0; |
| 96572 | + if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; |
| 96437 | 96573 | pSrc = p->pSrc; |
| 96438 | 96574 | assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); |
| 96439 | 96575 | pSubitem = &pSrc->a[iFrom]; |
| 96440 | 96576 | iParent = pSubitem->iCursor; |
| 96441 | 96577 | pSub = pSubitem->pSelect; |
| | @@ -97471,15 +97607,13 @@ |
| 97471 | 97607 | SrcList *pTabList; /* List of tables to select from */ |
| 97472 | 97608 | Expr *pWhere; /* The WHERE clause. May be NULL */ |
| 97473 | 97609 | ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ |
| 97474 | 97610 | ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ |
| 97475 | 97611 | Expr *pHaving; /* The HAVING clause. May be NULL */ |
| 97476 | | - int isDistinct; /* True if the DISTINCT keyword is present */ |
| 97477 | | - int distinct; /* Table to use for the distinct set */ |
| 97478 | 97612 | int rc = 1; /* Value to return from this function */ |
| 97479 | 97613 | int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ |
| 97480 | | - int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */ |
| 97614 | + DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ |
| 97481 | 97615 | AggInfo sAggInfo; /* Information used by aggregate queries */ |
| 97482 | 97616 | int iEnd; /* Address of the end of the query */ |
| 97483 | 97617 | sqlite3 *db; /* The database connection */ |
| 97484 | 97618 | |
| 97485 | 97619 | #ifndef SQLITE_OMIT_EXPLAIN |
| | @@ -97601,11 +97735,11 @@ |
| 97601 | 97735 | pEList = p->pEList; |
| 97602 | 97736 | #endif |
| 97603 | 97737 | pWhere = p->pWhere; |
| 97604 | 97738 | pGroupBy = p->pGroupBy; |
| 97605 | 97739 | pHaving = p->pHaving; |
| 97606 | | - isDistinct = (p->selFlags & SF_Distinct)!=0; |
| 97740 | + sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; |
| 97607 | 97741 | |
| 97608 | 97742 | #ifndef SQLITE_OMIT_COMPOUND_SELECT |
| 97609 | 97743 | /* If there is are a sequence of queries, do the earlier ones first. |
| 97610 | 97744 | */ |
| 97611 | 97745 | if( p->pPrior ){ |
| | @@ -97636,11 +97770,11 @@ |
| 97636 | 97770 | ** an optimization - the correct answer should result regardless. |
| 97637 | 97771 | ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER |
| 97638 | 97772 | ** to disable this optimization for testing purposes. |
| 97639 | 97773 | */ |
| 97640 | 97774 | if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 |
| 97641 | | - && (db->flags & SQLITE_GroupByOrder)==0 ){ |
| 97775 | + && OptimizationEnabled(db, SQLITE_GroupByOrder) ){ |
| 97642 | 97776 | pOrderBy = 0; |
| 97643 | 97777 | } |
| 97644 | 97778 | |
| 97645 | 97779 | /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and |
| 97646 | 97780 | ** if the select-list is the same as the ORDER BY list, then this query |
| | @@ -97662,10 +97796,14 @@ |
| 97662 | 97796 | ){ |
| 97663 | 97797 | p->selFlags &= ~SF_Distinct; |
| 97664 | 97798 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 97665 | 97799 | pGroupBy = p->pGroupBy; |
| 97666 | 97800 | pOrderBy = 0; |
| 97801 | + /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 97802 | + ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 97803 | + ** original setting of the SF_Distinct flag, not the current setting */ |
| 97804 | + assert( sDistinct.isTnct ); |
| 97667 | 97805 | } |
| 97668 | 97806 | |
| 97669 | 97807 | /* If there is an ORDER BY clause, then this sorting |
| 97670 | 97808 | ** index might end up being unused if the data can be |
| 97671 | 97809 | ** extracted in pre-sorted order. If that is the case, then the |
| | @@ -97702,28 +97840,31 @@ |
| 97702 | 97840 | } |
| 97703 | 97841 | |
| 97704 | 97842 | /* Open a virtual index to use for the distinct set. |
| 97705 | 97843 | */ |
| 97706 | 97844 | if( p->selFlags & SF_Distinct ){ |
| 97707 | | - KeyInfo *pKeyInfo; |
| 97708 | | - distinct = pParse->nTab++; |
| 97709 | | - pKeyInfo = keyInfoFromExprList(pParse, p->pEList); |
| 97710 | | - addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, |
| 97711 | | - (char*)pKeyInfo, P4_KEYINFO_HANDOFF); |
| 97845 | + sDistinct.tabTnct = pParse->nTab++; |
| 97846 | + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 97847 | + sDistinct.tabTnct, 0, 0, |
| 97848 | + (char*)keyInfoFromExprList(pParse, p->pEList), |
| 97849 | + P4_KEYINFO_HANDOFF); |
| 97712 | 97850 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 97851 | + sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; |
| 97713 | 97852 | }else{ |
| 97714 | | - distinct = addrDistinctIndex = -1; |
| 97853 | + sDistinct.eTnctType = WHERE_DISTINCT_NOOP; |
| 97715 | 97854 | } |
| 97716 | 97855 | |
| 97717 | | - /* Aggregate and non-aggregate queries are handled differently */ |
| 97718 | 97856 | if( !isAgg && pGroupBy==0 ){ |
| 97719 | | - ExprList *pDist = (isDistinct ? p->pEList : 0); |
| 97857 | + /* No aggregate functions and no GROUP BY clause */ |
| 97858 | + ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0); |
| 97720 | 97859 | |
| 97721 | 97860 | /* Begin the database scan. */ |
| 97722 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0); |
| 97861 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0); |
| 97723 | 97862 | if( pWInfo==0 ) goto select_end; |
| 97724 | 97863 | if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; |
| 97864 | + if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct; |
| 97865 | + if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0; |
| 97725 | 97866 | |
| 97726 | 97867 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| 97727 | 97868 | ** instruction ended up not being needed, then change the OP_OpenEphemeral |
| 97728 | 97869 | ** into an OP_Noop. |
| 97729 | 97870 | */ |
| | @@ -97730,63 +97871,20 @@ |
| 97730 | 97871 | if( addrSortIndex>=0 && pOrderBy==0 ){ |
| 97731 | 97872 | sqlite3VdbeChangeToNoop(v, addrSortIndex); |
| 97732 | 97873 | p->addrOpenEphm[2] = -1; |
| 97733 | 97874 | } |
| 97734 | 97875 | |
| 97735 | | - if( pWInfo->eDistinct ){ |
| 97736 | | - VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 97737 | | - |
| 97738 | | - assert( addrDistinctIndex>=0 ); |
| 97739 | | - pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); |
| 97740 | | - |
| 97741 | | - assert( isDistinct ); |
| 97742 | | - assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED |
| 97743 | | - || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE |
| 97744 | | - ); |
| 97745 | | - distinct = -1; |
| 97746 | | - if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){ |
| 97747 | | - int iJump; |
| 97748 | | - int iExpr; |
| 97749 | | - int iFlag = ++pParse->nMem; |
| 97750 | | - int iBase = pParse->nMem+1; |
| 97751 | | - int iBase2 = iBase + pEList->nExpr; |
| 97752 | | - pParse->nMem += (pEList->nExpr*2); |
| 97753 | | - |
| 97754 | | - /* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The |
| 97755 | | - ** OP_Integer initializes the "first row" flag. */ |
| 97756 | | - pOp->opcode = OP_Integer; |
| 97757 | | - pOp->p1 = 1; |
| 97758 | | - pOp->p2 = iFlag; |
| 97759 | | - |
| 97760 | | - sqlite3ExprCodeExprList(pParse, pEList, iBase, 1); |
| 97761 | | - iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1; |
| 97762 | | - sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1); |
| 97763 | | - for(iExpr=0; iExpr<pEList->nExpr; iExpr++){ |
| 97764 | | - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr); |
| 97765 | | - sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr); |
| 97766 | | - sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ); |
| 97767 | | - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 97768 | | - } |
| 97769 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue); |
| 97770 | | - |
| 97771 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag); |
| 97772 | | - assert( sqlite3VdbeCurrentAddr(v)==iJump ); |
| 97773 | | - sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr); |
| 97774 | | - }else{ |
| 97775 | | - pOp->opcode = OP_Noop; |
| 97776 | | - } |
| 97777 | | - } |
| 97778 | | - |
| 97779 | 97876 | /* Use the standard inner loop. */ |
| 97780 | | - selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest, |
| 97877 | + selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest, |
| 97781 | 97878 | pWInfo->iContinue, pWInfo->iBreak); |
| 97782 | 97879 | |
| 97783 | 97880 | /* End the database scan loop. |
| 97784 | 97881 | */ |
| 97785 | 97882 | sqlite3WhereEnd(pWInfo); |
| 97786 | 97883 | }else{ |
| 97787 | | - /* This is the processing for aggregate queries */ |
| 97884 | + /* This case when there exist aggregate functions or a GROUP BY clause |
| 97885 | + ** or both */ |
| 97788 | 97886 | NameContext sNC; /* Name context for processing aggregate information */ |
| 97789 | 97887 | int iAMem; /* First Mem address for storing current GROUP BY */ |
| 97790 | 97888 | int iBMem; /* First Mem address for previous GROUP BY */ |
| 97791 | 97889 | int iUseFlag; /* Mem address holding flag indicating that at least |
| 97792 | 97890 | ** one row of the input to the aggregator has been |
| | @@ -97890,18 +97988,17 @@ |
| 97890 | 97988 | ** This might involve two separate loops with an OP_Sort in between, or |
| 97891 | 97989 | ** it might be a single loop that uses an index to extract information |
| 97892 | 97990 | ** in the right order to begin with. |
| 97893 | 97991 | */ |
| 97894 | 97992 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 97895 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0); |
| 97993 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0); |
| 97896 | 97994 | if( pWInfo==0 ) goto select_end; |
| 97897 | | - if( pGroupBy==0 ){ |
| 97995 | + if( pWInfo->nOBSat==pGroupBy->nExpr ){ |
| 97898 | 97996 | /* The optimizer is able to deliver rows in group by order so |
| 97899 | 97997 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| 97900 | 97998 | ** cancelled later because we still need to use the pKeyInfo |
| 97901 | 97999 | */ |
| 97902 | | - pGroupBy = p->pGroupBy; |
| 97903 | 98000 | groupBySort = 0; |
| 97904 | 98001 | }else{ |
| 97905 | 98002 | /* Rows are coming out in undetermined order. We have to push |
| 97906 | 98003 | ** each row into a sorting index, terminate the first loop, |
| 97907 | 98004 | ** then loop over the sorting index in order to get the output |
| | @@ -97911,11 +98008,12 @@ |
| 97911 | 98008 | int regRecord; |
| 97912 | 98009 | int nCol; |
| 97913 | 98010 | int nGroupBy; |
| 97914 | 98011 | |
| 97915 | 98012 | explainTempTable(pParse, |
| 97916 | | - isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY"); |
| 98013 | + (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? |
| 98014 | + "DISTINCT" : "GROUP BY"); |
| 97917 | 98015 | |
| 97918 | 98016 | groupBySort = 1; |
| 97919 | 98017 | nGroupBy = pGroupBy->nExpr; |
| 97920 | 98018 | nCol = nGroupBy + 1; |
| 97921 | 98019 | j = nGroupBy+1; |
| | @@ -98043,11 +98141,11 @@ |
| 98043 | 98141 | VdbeComment((v, "Groupby result generator entry point")); |
| 98044 | 98142 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 98045 | 98143 | finalizeAggFunctions(pParse, &sAggInfo); |
| 98046 | 98144 | sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); |
| 98047 | 98145 | selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, |
| 98048 | | - distinct, pDest, |
| 98146 | + &sDistinct, pDest, |
| 98049 | 98147 | addrOutputRow+1, addrSetAbort); |
| 98050 | 98148 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); |
| 98051 | 98149 | VdbeComment((v, "end groupby result generator")); |
| 98052 | 98150 | |
| 98053 | 98151 | /* Generate a subroutine that will reset the group-by accumulator |
| | @@ -98146,10 +98244,11 @@ |
| 98146 | 98244 | */ |
| 98147 | 98245 | ExprList *pMinMax = 0; |
| 98148 | 98246 | u8 flag = minMaxQuery(p); |
| 98149 | 98247 | if( flag ){ |
| 98150 | 98248 | assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) ); |
| 98249 | + assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 ); |
| 98151 | 98250 | pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0); |
| 98152 | 98251 | pDel = pMinMax; |
| 98153 | 98252 | if( pMinMax && !db->mallocFailed ){ |
| 98154 | 98253 | pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; |
| 98155 | 98254 | pMinMax->a[0].pExpr->op = TK_COLUMN; |
| | @@ -98159,17 +98258,18 @@ |
| 98159 | 98258 | /* This case runs if the aggregate has no GROUP BY clause. The |
| 98160 | 98259 | ** processing is much simpler since there is only a single row |
| 98161 | 98260 | ** of output. |
| 98162 | 98261 | */ |
| 98163 | 98262 | resetAccumulator(pParse, &sAggInfo); |
| 98164 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0); |
| 98263 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0); |
| 98165 | 98264 | if( pWInfo==0 ){ |
| 98166 | 98265 | sqlite3ExprListDelete(db, pDel); |
| 98167 | 98266 | goto select_end; |
| 98168 | 98267 | } |
| 98169 | 98268 | updateAccumulator(pParse, &sAggInfo); |
| 98170 | | - if( !pMinMax && flag ){ |
| 98269 | + assert( pMinMax==0 || pMinMax->nExpr==1 ); |
| 98270 | + if( pWInfo->nOBSat>0 ){ |
| 98171 | 98271 | sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); |
| 98172 | 98272 | VdbeComment((v, "%s() by index", |
| 98173 | 98273 | (flag==WHERE_ORDERBY_MIN?"min":"max"))); |
| 98174 | 98274 | } |
| 98175 | 98275 | sqlite3WhereEnd(pWInfo); |
| | @@ -98176,19 +98276,19 @@ |
| 98176 | 98276 | finalizeAggFunctions(pParse, &sAggInfo); |
| 98177 | 98277 | } |
| 98178 | 98278 | |
| 98179 | 98279 | pOrderBy = 0; |
| 98180 | 98280 | sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); |
| 98181 | | - selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, |
| 98281 | + selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0, |
| 98182 | 98282 | pDest, addrEnd, addrEnd); |
| 98183 | 98283 | sqlite3ExprListDelete(db, pDel); |
| 98184 | 98284 | } |
| 98185 | 98285 | sqlite3VdbeResolveLabel(v, addrEnd); |
| 98186 | 98286 | |
| 98187 | 98287 | } /* endif aggregate query */ |
| 98188 | 98288 | |
| 98189 | | - if( distinct>=0 ){ |
| 98289 | + if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ |
| 98190 | 98290 | explainTempTable(pParse, "DISTINCT"); |
| 98191 | 98291 | } |
| 98192 | 98292 | |
| 98193 | 98293 | /* If there is an ORDER BY clause, then we need to sort the results |
| 98194 | 98294 | ** and send them to the callback one by one. |
| | @@ -101789,13 +101889,14 @@ |
| 101789 | 101889 | |
| 101790 | 101890 | /* |
| 101791 | 101891 | ** Trace output macros |
| 101792 | 101892 | */ |
| 101793 | 101893 | #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) |
| 101794 | | -SQLITE_PRIVATE int sqlite3WhereTrace = 0; |
| 101894 | +/***/ int sqlite3WhereTrace = 0; |
| 101795 | 101895 | #endif |
| 101796 | | -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 101896 | +#if defined(SQLITE_DEBUG) \ |
| 101897 | + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) |
| 101797 | 101898 | # define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X |
| 101798 | 101899 | #else |
| 101799 | 101900 | # define WHERETRACE(X) |
| 101800 | 101901 | #endif |
| 101801 | 101902 | |
| | @@ -102031,10 +102132,32 @@ |
| 102031 | 102132 | #define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */ |
| 102032 | 102133 | #define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */ |
| 102033 | 102134 | #define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */ |
| 102034 | 102135 | #define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */ |
| 102035 | 102136 | #define WHERE_COVER_SCAN 0x80000000 /* Full scan of a covering index */ |
| 102137 | + |
| 102138 | +/* |
| 102139 | +** This module contains many separate subroutines that work together to |
| 102140 | +** find the best indices to use for accessing a particular table in a query. |
| 102141 | +** An instance of the following structure holds context information about the |
| 102142 | +** index search so that it can be more easily passed between the various |
| 102143 | +** routines. |
| 102144 | +*/ |
| 102145 | +typedef struct WhereBestIdx WhereBestIdx; |
| 102146 | +struct WhereBestIdx { |
| 102147 | + Parse *pParse; /* Parser context */ |
| 102148 | + WhereClause *pWC; /* The WHERE clause */ |
| 102149 | + struct SrcList_item *pSrc; /* The FROM clause term to search */ |
| 102150 | + Bitmask notReady; /* Mask of cursors not available */ |
| 102151 | + Bitmask notValid; /* Cursors not available for any purpose */ |
| 102152 | + ExprList *pOrderBy; /* The ORDER BY clause */ |
| 102153 | + ExprList *pDistinct; /* The select-list if query is DISTINCT */ |
| 102154 | + sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */ |
| 102155 | + int i, n; /* Which loop is being coded; # of loops */ |
| 102156 | + WhereLevel *aLevel; /* Info about outer loops */ |
| 102157 | + WhereCost cost; /* Lowest cost query plan */ |
| 102158 | +}; |
| 102036 | 102159 | |
| 102037 | 102160 | /* |
| 102038 | 102161 | ** Initialize a preallocated WhereClause structure. |
| 102039 | 102162 | */ |
| 102040 | 102163 | static void whereClauseInit( |
| | @@ -103174,26 +103297,22 @@ |
| 103174 | 103297 | */ |
| 103175 | 103298 | pTerm->prereqRight |= extraRight; |
| 103176 | 103299 | } |
| 103177 | 103300 | |
| 103178 | 103301 | /* |
| 103179 | | -** Return TRUE if any of the expressions in pList->a[iFirst...] contain |
| 103180 | | -** a reference to any table other than the iBase table. |
| 103302 | +** Return TRUE if the given index is UNIQUE and all columns past the |
| 103303 | +** first nSkip columns are NOT NULL. |
| 103181 | 103304 | */ |
| 103182 | | -static int referencesOtherTables( |
| 103183 | | - ExprList *pList, /* Search expressions in ths list */ |
| 103184 | | - WhereMaskSet *pMaskSet, /* Mapping from tables to bitmaps */ |
| 103185 | | - int iFirst, /* Be searching with the iFirst-th expression */ |
| 103186 | | - int iBase /* Ignore references to this table */ |
| 103187 | | -){ |
| 103188 | | - Bitmask allowed = ~getMask(pMaskSet, iBase); |
| 103189 | | - while( iFirst<pList->nExpr ){ |
| 103190 | | - if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){ |
| 103191 | | - return 1; |
| 103192 | | - } |
| 103193 | | - } |
| 103194 | | - return 0; |
| 103305 | +static int indexIsUniqueNotNull(Index *pIdx, int nSkip){ |
| 103306 | + Table *pTab = pIdx->pTable; |
| 103307 | + int i; |
| 103308 | + if( pIdx->onError==OE_None ) return 0; |
| 103309 | + for(i=nSkip; i<pIdx->nColumn; i++){ |
| 103310 | + int j = pIdx->aiColumn[i]; |
| 103311 | + if( j>=0 && pTab->aCol[j].notNull==0 ) return 0; |
| 103312 | + } |
| 103313 | + return 1; |
| 103195 | 103314 | } |
| 103196 | 103315 | |
| 103197 | 103316 | /* |
| 103198 | 103317 | ** This function searches the expression list passed as the second argument |
| 103199 | 103318 | ** for an expression of type TK_COLUMN that refers to the same column and |
| | @@ -103355,47 +103474,63 @@ |
| 103355 | 103474 | return 0; |
| 103356 | 103475 | } |
| 103357 | 103476 | |
| 103358 | 103477 | /* |
| 103359 | 103478 | ** This routine decides if pIdx can be used to satisfy the ORDER BY |
| 103360 | | -** clause. If it can, it returns 1. If pIdx cannot satisfy the |
| 103361 | | -** ORDER BY clause, this routine returns 0. |
| 103479 | +** clause, either in whole or in part. The return value is the |
| 103480 | +** cumulative number of terms in the ORDER BY clause that are satisfied |
| 103481 | +** by the index pIdx and other indices in outer loops. |
| 103362 | 103482 | ** |
| 103363 | | -** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the |
| 103364 | | -** left-most table in the FROM clause of that same SELECT statement and |
| 103365 | | -** the table has a cursor number of "base". pIdx is an index on pTab. |
| 103483 | +** The table being queried has a cursor number of "base". pIdx is the |
| 103484 | +** index that is postulated for use to access the table. |
| 103366 | 103485 | ** |
| 103367 | 103486 | ** nEqCol is the number of columns of pIdx that are used as equality |
| 103368 | | -** constraints. Any of these columns may be missing from the ORDER BY |
| 103369 | | -** clause and the match can still be a success. |
| 103487 | +** constraints and where the other side of the == is an ordered column |
| 103488 | +** or constant. An "order column" in the previous sentence means a column |
| 103489 | +** in table from an outer loop whose values will always appear in the |
| 103490 | +** correct order due to othre index, or because the outer loop generates |
| 103491 | +** a unique result. Any of the first nEqCol columns of pIdx may be missing |
| 103492 | +** from the ORDER BY clause and the match can still be a success. |
| 103370 | 103493 | ** |
| 103371 | | -** All terms of the ORDER BY that match against the index must be either |
| 103372 | | -** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE |
| 103373 | | -** index do not need to satisfy this constraint.) The *pbRev value is |
| 103374 | | -** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if |
| 103375 | | -** the ORDER BY clause is all ASC. |
| 103494 | +** The *pbRev value is set to 0 order 1 depending on whether or not |
| 103495 | +** pIdx should be run in the forward order or in reverse order. |
| 103376 | 103496 | */ |
| 103377 | 103497 | static int isSortingIndex( |
| 103378 | | - Parse *pParse, /* Parsing context */ |
| 103379 | | - WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */ |
| 103380 | | - Index *pIdx, /* The index we are testing */ |
| 103381 | | - int base, /* Cursor number for the table to be sorted */ |
| 103382 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 103383 | | - int nEqCol, /* Number of index columns with == constraints */ |
| 103384 | | - int wsFlags, /* Index usages flags */ |
| 103385 | | - int *pbRev /* Set to 1 if ORDER BY is DESC */ |
| 103498 | + WhereBestIdx *p, /* Best index search context */ |
| 103499 | + Index *pIdx, /* The index we are testing */ |
| 103500 | + int base, /* Cursor number for the table to be sorted */ |
| 103501 | + int nEqCol, /* Number of index columns with ordered == constraints */ |
| 103502 | + int wsFlags, /* Index usages flags */ |
| 103503 | + int bOuterRev, /* True if outer loops scan in reverse order */ |
| 103504 | + int *pbRev /* Set to 1 for reverse-order scan of pIdx */ |
| 103386 | 103505 | ){ |
| 103387 | | - int i, j; /* Loop counters */ |
| 103388 | | - int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ |
| 103389 | | - int nTerm; /* Number of ORDER BY terms */ |
| 103390 | | - struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ |
| 103391 | | - sqlite3 *db = pParse->db; |
| 103392 | | - |
| 103393 | | - if( !pOrderBy ) return 0; |
| 103394 | | - if( wsFlags & WHERE_COLUMN_IN ) return 0; |
| 103395 | | - if( pIdx->bUnordered ) return 0; |
| 103396 | | - |
| 103506 | + int i; /* Number of pIdx terms used */ |
| 103507 | + int j; /* Number of ORDER BY terms satisfied */ |
| 103508 | + int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ |
| 103509 | + int nTerm; /* Number of ORDER BY terms */ |
| 103510 | + struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ |
| 103511 | + ExprList *pOrderBy; /* The ORDER BY clause */ |
| 103512 | + Parse *pParse = p->pParse; /* Parser context */ |
| 103513 | + sqlite3 *db = pParse->db; /* Database connection */ |
| 103514 | + int nPriorSat; /* ORDER BY terms satisfied by outer loops */ |
| 103515 | + int seenRowid = 0; /* True if an ORDER BY rowid term is seen */ |
| 103516 | + int nEqOneRow; /* Idx columns that ref unique values */ |
| 103517 | + |
| 103518 | + if( p->i==0 ){ |
| 103519 | + nPriorSat = 0; |
| 103520 | + nEqOneRow = nEqCol; |
| 103521 | + }else{ |
| 103522 | + if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; |
| 103523 | + nPriorSat = p->aLevel[p->i-1].plan.nOBSat; |
| 103524 | + sortOrder = bOuterRev; |
| 103525 | + nEqOneRow = 0; |
| 103526 | + } |
| 103527 | + if( p->i>0 && nEqCol==0 /*&& !allOuterLoopsUnique(p)*/ ) return nPriorSat; |
| 103528 | + pOrderBy = p->pOrderBy; |
| 103529 | + if( !pOrderBy ) return nPriorSat; |
| 103530 | + if( wsFlags & WHERE_COLUMN_IN ) return nPriorSat; |
| 103531 | + if( pIdx->bUnordered ) return nPriorSat; |
| 103397 | 103532 | nTerm = pOrderBy->nExpr; |
| 103398 | 103533 | assert( nTerm>0 ); |
| 103399 | 103534 | |
| 103400 | 103535 | /* Argument pIdx must either point to a 'real' named index structure, |
| 103401 | 103536 | ** or an index structure allocated on the stack by bestBtreeIndex() to |
| | @@ -103408,11 +103543,11 @@ |
| 103408 | 103543 | ** Note that indices have pIdx->nColumn regular columns plus |
| 103409 | 103544 | ** one additional column containing the rowid. The rowid column |
| 103410 | 103545 | ** of the index is also allowed to match against the ORDER BY |
| 103411 | 103546 | ** clause. |
| 103412 | 103547 | */ |
| 103413 | | - for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){ |
| 103548 | + for(i=0,j=nPriorSat,pTerm=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){ |
| 103414 | 103549 | Expr *pExpr; /* The expression of the ORDER BY pTerm */ |
| 103415 | 103550 | CollSeq *pColl; /* The collating sequence of pExpr */ |
| 103416 | 103551 | int termSortOrder; /* Sort order for this term */ |
| 103417 | 103552 | int iColumn; /* The i-th column of the index. -1 for rowid */ |
| 103418 | 103553 | int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ |
| | @@ -103452,68 +103587,53 @@ |
| 103452 | 103587 | break; |
| 103453 | 103588 | }else{ |
| 103454 | 103589 | /* If an index column fails to match and is not constrained by == |
| 103455 | 103590 | ** then the index cannot satisfy the ORDER BY constraint. |
| 103456 | 103591 | */ |
| 103457 | | - return 0; |
| 103592 | + return nPriorSat; |
| 103458 | 103593 | } |
| 103459 | 103594 | } |
| 103460 | 103595 | assert( pIdx->aSortOrder!=0 || iColumn==-1 ); |
| 103461 | 103596 | assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); |
| 103462 | 103597 | assert( iSortOrder==0 || iSortOrder==1 ); |
| 103463 | 103598 | termSortOrder = iSortOrder ^ pTerm->sortOrder; |
| 103464 | | - if( i>nEqCol ){ |
| 103599 | + if( i>nEqOneRow ){ |
| 103465 | 103600 | if( termSortOrder!=sortOrder ){ |
| 103466 | 103601 | /* Indices can only be used if all ORDER BY terms past the |
| 103467 | 103602 | ** equality constraints are all either DESC or ASC. */ |
| 103468 | | - return 0; |
| 103603 | + break; |
| 103469 | 103604 | } |
| 103470 | 103605 | }else{ |
| 103471 | 103606 | sortOrder = termSortOrder; |
| 103472 | 103607 | } |
| 103473 | 103608 | j++; |
| 103474 | 103609 | pTerm++; |
| 103475 | | - if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ |
| 103476 | | - /* If the indexed column is the primary key and everything matches |
| 103477 | | - ** so far and none of the ORDER BY terms to the right reference other |
| 103478 | | - ** tables in the join, then we are assured that the index can be used |
| 103479 | | - ** to sort because the primary key is unique and so none of the other |
| 103480 | | - ** columns will make any difference |
| 103481 | | - */ |
| 103482 | | - j = nTerm; |
| 103483 | | - } |
| 103484 | | - } |
| 103485 | | - |
| 103486 | | - *pbRev = sortOrder!=0; |
| 103487 | | - if( j>=nTerm ){ |
| 103488 | | - /* All terms of the ORDER BY clause are covered by this index so |
| 103489 | | - ** this index can be used for sorting. */ |
| 103490 | | - return 1; |
| 103491 | | - } |
| 103492 | | - if( pIdx->onError!=OE_None && i==pIdx->nColumn |
| 103493 | | - && (wsFlags & WHERE_COLUMN_NULL)==0 |
| 103494 | | - && !referencesOtherTables(pOrderBy, pMaskSet, j, base) |
| 103610 | + if( iColumn<0 ){ |
| 103611 | + seenRowid = 1; |
| 103612 | + break; |
| 103613 | + } |
| 103614 | + } |
| 103615 | + *pbRev = sortOrder; |
| 103616 | + |
| 103617 | + /* If there was an "ORDER BY rowid" term that matched, or it is only |
| 103618 | + ** possible for a single row from this table to match, then skip over |
| 103619 | + ** any additional ORDER BY terms dealing with this table. |
| 103620 | + */ |
| 103621 | + if( seenRowid || |
| 103622 | + ( (wsFlags & WHERE_COLUMN_NULL)==0 |
| 103623 | + && i>=pIdx->nColumn |
| 103624 | + && indexIsUniqueNotNull(pIdx, nEqCol) |
| 103625 | + ) |
| 103495 | 103626 | ){ |
| 103496 | | - Column *aCol = pIdx->pTable->aCol; |
| 103497 | | - |
| 103498 | | - /* All terms of this index match some prefix of the ORDER BY clause, |
| 103499 | | - ** the index is UNIQUE, and no terms on the tail of the ORDER BY |
| 103500 | | - ** refer to other tables in a join. So, assuming that the index entries |
| 103501 | | - ** visited contain no NULL values, then this index delivers rows in |
| 103502 | | - ** the required order. |
| 103503 | | - ** |
| 103504 | | - ** It is not possible for any of the first nEqCol index fields to be |
| 103505 | | - ** NULL (since the corresponding "=" operator in the WHERE clause would |
| 103506 | | - ** not be true). So if all remaining index columns have NOT NULL |
| 103507 | | - ** constaints attached to them, we can be confident that the visited |
| 103508 | | - ** index entries are free of NULLs. */ |
| 103509 | | - for(i=nEqCol; i<pIdx->nColumn; i++){ |
| 103510 | | - if( aCol[pIdx->aiColumn[i]].notNull==0 ) break; |
| 103511 | | - } |
| 103512 | | - return (i==pIdx->nColumn); |
| 103513 | | - } |
| 103514 | | - return 0; |
| 103627 | + /* Advance j over additional ORDER BY terms associated with base */ |
| 103628 | + WhereMaskSet *pMS = p->pWC->pMaskSet; |
| 103629 | + Bitmask m = ~getMask(pMS, base); |
| 103630 | + while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){ |
| 103631 | + j++; |
| 103632 | + } |
| 103633 | + } |
| 103634 | + return j; |
| 103515 | 103635 | } |
| 103516 | 103636 | |
| 103517 | 103637 | /* |
| 103518 | 103638 | ** Prepare a crude estimate of the logarithm of the input value. |
| 103519 | 103639 | ** The results need not be exact. This is only used for estimating |
| | @@ -103576,35 +103696,27 @@ |
| 103576 | 103696 | #endif |
| 103577 | 103697 | |
| 103578 | 103698 | /* |
| 103579 | 103699 | ** Required because bestIndex() is called by bestOrClauseIndex() |
| 103580 | 103700 | */ |
| 103581 | | -static void bestIndex( |
| 103582 | | - Parse*, WhereClause*, struct SrcList_item*, |
| 103583 | | - Bitmask, Bitmask, ExprList*, WhereCost*); |
| 103701 | +static void bestIndex(WhereBestIdx*); |
| 103584 | 103702 | |
| 103585 | 103703 | /* |
| 103586 | 103704 | ** This routine attempts to find an scanning strategy that can be used |
| 103587 | 103705 | ** to optimize an 'OR' expression that is part of a WHERE clause. |
| 103588 | 103706 | ** |
| 103589 | 103707 | ** The table associated with FROM clause term pSrc may be either a |
| 103590 | 103708 | ** regular B-Tree table or a virtual table. |
| 103591 | 103709 | */ |
| 103592 | | -static void bestOrClauseIndex( |
| 103593 | | - Parse *pParse, /* The parsing context */ |
| 103594 | | - WhereClause *pWC, /* The WHERE clause */ |
| 103595 | | - struct SrcList_item *pSrc, /* The FROM clause term to search */ |
| 103596 | | - Bitmask notReady, /* Mask of cursors not available for indexing */ |
| 103597 | | - Bitmask notValid, /* Cursors not available for any purpose */ |
| 103598 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 103599 | | - WhereCost *pCost /* Lowest cost query plan */ |
| 103600 | | -){ |
| 103710 | +static void bestOrClauseIndex(WhereBestIdx *p){ |
| 103601 | 103711 | #ifndef SQLITE_OMIT_OR_OPTIMIZATION |
| 103602 | | - const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ |
| 103712 | + WhereClause *pWC = p->pWC; /* The WHERE clause */ |
| 103713 | + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ |
| 103714 | + const int iCur = pSrc->iCursor; /* The cursor of the table */ |
| 103603 | 103715 | const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */ |
| 103604 | 103716 | WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */ |
| 103605 | | - WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| 103717 | + WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| 103606 | 103718 | |
| 103607 | 103719 | /* The OR-clause optimization is disallowed if the INDEXED BY or |
| 103608 | 103720 | ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */ |
| 103609 | 103721 | if( pSrc->notIndexed || pSrc->pIndex!=0 ){ |
| 103610 | 103722 | return; |
| | @@ -103614,66 +103726,71 @@ |
| 103614 | 103726 | } |
| 103615 | 103727 | |
| 103616 | 103728 | /* Search the WHERE clause terms for a usable WO_OR term. */ |
| 103617 | 103729 | for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ |
| 103618 | 103730 | if( pTerm->eOperator==WO_OR |
| 103619 | | - && ((pTerm->prereqAll & ~maskSrc) & notReady)==0 |
| 103731 | + && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0 |
| 103620 | 103732 | && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 |
| 103621 | 103733 | ){ |
| 103622 | 103734 | WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; |
| 103623 | 103735 | WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; |
| 103624 | 103736 | WhereTerm *pOrTerm; |
| 103625 | 103737 | int flags = WHERE_MULTI_OR; |
| 103626 | 103738 | double rTotal = 0; |
| 103627 | 103739 | double nRow = 0; |
| 103628 | 103740 | Bitmask used = 0; |
| 103741 | + WhereBestIdx sBOI; |
| 103629 | 103742 | |
| 103743 | + sBOI = *p; |
| 103744 | + sBOI.pOrderBy = 0; |
| 103745 | + sBOI.pDistinct = 0; |
| 103746 | + sBOI.ppIdxInfo = 0; |
| 103630 | 103747 | for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ |
| 103631 | | - WhereCost sTermCost; |
| 103632 | 103748 | WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", |
| 103633 | 103749 | (pOrTerm - pOrWC->a), (pTerm - pWC->a) |
| 103634 | 103750 | )); |
| 103635 | 103751 | if( pOrTerm->eOperator==WO_AND ){ |
| 103636 | | - WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc; |
| 103637 | | - bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost); |
| 103752 | + sBOI.pWC = &pOrTerm->u.pAndInfo->wc; |
| 103753 | + bestIndex(&sBOI); |
| 103638 | 103754 | }else if( pOrTerm->leftCursor==iCur ){ |
| 103639 | 103755 | WhereClause tempWC; |
| 103640 | 103756 | tempWC.pParse = pWC->pParse; |
| 103641 | 103757 | tempWC.pMaskSet = pWC->pMaskSet; |
| 103642 | 103758 | tempWC.pOuter = pWC; |
| 103643 | 103759 | tempWC.op = TK_AND; |
| 103644 | 103760 | tempWC.a = pOrTerm; |
| 103645 | 103761 | tempWC.wctrlFlags = 0; |
| 103646 | 103762 | tempWC.nTerm = 1; |
| 103647 | | - bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost); |
| 103763 | + sBOI.pWC = &tempWC; |
| 103764 | + bestIndex(&sBOI); |
| 103648 | 103765 | }else{ |
| 103649 | 103766 | continue; |
| 103650 | 103767 | } |
| 103651 | | - rTotal += sTermCost.rCost; |
| 103652 | | - nRow += sTermCost.plan.nRow; |
| 103653 | | - used |= sTermCost.used; |
| 103654 | | - if( rTotal>=pCost->rCost ) break; |
| 103768 | + rTotal += sBOI.cost.rCost; |
| 103769 | + nRow += sBOI.cost.plan.nRow; |
| 103770 | + used |= sBOI.cost.used; |
| 103771 | + if( rTotal>=p->cost.rCost ) break; |
| 103655 | 103772 | } |
| 103656 | 103773 | |
| 103657 | 103774 | /* If there is an ORDER BY clause, increase the scan cost to account |
| 103658 | 103775 | ** for the cost of the sort. */ |
| 103659 | | - if( pOrderBy!=0 ){ |
| 103776 | + if( p->pOrderBy!=0 ){ |
| 103660 | 103777 | WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n", |
| 103661 | 103778 | rTotal, rTotal+nRow*estLog(nRow))); |
| 103662 | 103779 | rTotal += nRow*estLog(nRow); |
| 103663 | 103780 | } |
| 103664 | 103781 | |
| 103665 | 103782 | /* If the cost of scanning using this OR term for optimization is |
| 103666 | 103783 | ** less than the current cost stored in pCost, replace the contents |
| 103667 | 103784 | ** of pCost. */ |
| 103668 | 103785 | WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow)); |
| 103669 | | - if( rTotal<pCost->rCost ){ |
| 103670 | | - pCost->rCost = rTotal; |
| 103671 | | - pCost->used = used; |
| 103672 | | - pCost->plan.nRow = nRow; |
| 103673 | | - pCost->plan.wsFlags = flags; |
| 103674 | | - pCost->plan.u.pTerm = pTerm; |
| 103786 | + if( rTotal<p->cost.rCost ){ |
| 103787 | + p->cost.rCost = rTotal; |
| 103788 | + p->cost.used = used; |
| 103789 | + p->cost.plan.nRow = nRow; |
| 103790 | + p->cost.plan.wsFlags = flags; |
| 103791 | + p->cost.plan.u.pTerm = pTerm; |
| 103675 | 103792 | } |
| 103676 | 103793 | } |
| 103677 | 103794 | } |
| 103678 | 103795 | #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ |
| 103679 | 103796 | } |
| | @@ -103706,19 +103823,16 @@ |
| 103706 | 103823 | ** possible to construct a transient index that would perform better |
| 103707 | 103824 | ** than a full table scan even when the cost of constructing the index |
| 103708 | 103825 | ** is taken into account, then alter the query plan to use the |
| 103709 | 103826 | ** transient index. |
| 103710 | 103827 | */ |
| 103711 | | -static void bestAutomaticIndex( |
| 103712 | | - Parse *pParse, /* The parsing context */ |
| 103713 | | - WhereClause *pWC, /* The WHERE clause */ |
| 103714 | | - struct SrcList_item *pSrc, /* The FROM clause term to search */ |
| 103715 | | - Bitmask notReady, /* Mask of cursors that are not available */ |
| 103716 | | - WhereCost *pCost /* Lowest cost query plan */ |
| 103717 | | -){ |
| 103718 | | - double nTableRow; /* Rows in the input table */ |
| 103719 | | - double logN; /* log(nTableRow) */ |
| 103828 | +static void bestAutomaticIndex(WhereBestIdx *p){ |
| 103829 | + Parse *pParse = p->pParse; /* The parsing context */ |
| 103830 | + WhereClause *pWC = p->pWC; /* The WHERE clause */ |
| 103831 | + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ |
| 103832 | + double nTableRow; /* Rows in the input table */ |
| 103833 | + double logN; /* log(nTableRow) */ |
| 103720 | 103834 | double costTempIdx; /* per-query cost of the transient index */ |
| 103721 | 103835 | WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| 103722 | 103836 | WhereTerm *pWCEnd; /* End of pWC->a[] */ |
| 103723 | 103837 | Table *pTable; /* Table tht might be indexed */ |
| 103724 | 103838 | |
| | @@ -103728,11 +103842,11 @@ |
| 103728 | 103842 | } |
| 103729 | 103843 | if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){ |
| 103730 | 103844 | /* Automatic indices are disabled at run-time */ |
| 103731 | 103845 | return; |
| 103732 | 103846 | } |
| 103733 | | - if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ |
| 103847 | + if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ |
| 103734 | 103848 | /* We already have some kind of index in use for this query. */ |
| 103735 | 103849 | return; |
| 103736 | 103850 | } |
| 103737 | 103851 | if( pSrc->notIndexed ){ |
| 103738 | 103852 | /* The NOT INDEXED clause appears in the SQL. */ |
| | @@ -103746,32 +103860,32 @@ |
| 103746 | 103860 | assert( pParse->nQueryLoop >= (double)1 ); |
| 103747 | 103861 | pTable = pSrc->pTab; |
| 103748 | 103862 | nTableRow = pTable->nRowEst; |
| 103749 | 103863 | logN = estLog(nTableRow); |
| 103750 | 103864 | costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1); |
| 103751 | | - if( costTempIdx>=pCost->rCost ){ |
| 103865 | + if( costTempIdx>=p->cost.rCost ){ |
| 103752 | 103866 | /* The cost of creating the transient table would be greater than |
| 103753 | 103867 | ** doing the full table scan */ |
| 103754 | 103868 | return; |
| 103755 | 103869 | } |
| 103756 | 103870 | |
| 103757 | 103871 | /* Search for any equality comparison term */ |
| 103758 | 103872 | pWCEnd = &pWC->a[pWC->nTerm]; |
| 103759 | 103873 | for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ |
| 103760 | | - if( termCanDriveIndex(pTerm, pSrc, notReady) ){ |
| 103874 | + if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){ |
| 103761 | 103875 | WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n", |
| 103762 | | - pCost->rCost, costTempIdx)); |
| 103763 | | - pCost->rCost = costTempIdx; |
| 103764 | | - pCost->plan.nRow = logN + 1; |
| 103765 | | - pCost->plan.wsFlags = WHERE_TEMP_INDEX; |
| 103766 | | - pCost->used = pTerm->prereqRight; |
| 103876 | + p->cost.rCost, costTempIdx)); |
| 103877 | + p->cost.rCost = costTempIdx; |
| 103878 | + p->cost.plan.nRow = logN + 1; |
| 103879 | + p->cost.plan.wsFlags = WHERE_TEMP_INDEX; |
| 103880 | + p->cost.used = pTerm->prereqRight; |
| 103767 | 103881 | break; |
| 103768 | 103882 | } |
| 103769 | 103883 | } |
| 103770 | 103884 | } |
| 103771 | 103885 | #else |
| 103772 | | -# define bestAutomaticIndex(A,B,C,D,E) /* no-op */ |
| 103886 | +# define bestAutomaticIndex(A) /* no-op */ |
| 103773 | 103887 | #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ |
| 103774 | 103888 | |
| 103775 | 103889 | |
| 103776 | 103890 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 103777 | 103891 | /* |
| | @@ -103928,16 +104042,15 @@ |
| 103928 | 104042 | /* |
| 103929 | 104043 | ** Allocate and populate an sqlite3_index_info structure. It is the |
| 103930 | 104044 | ** responsibility of the caller to eventually release the structure |
| 103931 | 104045 | ** by passing the pointer returned by this function to sqlite3_free(). |
| 103932 | 104046 | */ |
| 103933 | | -static sqlite3_index_info *allocateIndexInfo( |
| 103934 | | - Parse *pParse, |
| 103935 | | - WhereClause *pWC, |
| 103936 | | - struct SrcList_item *pSrc, |
| 103937 | | - ExprList *pOrderBy |
| 103938 | | -){ |
| 104047 | +static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){ |
| 104048 | + Parse *pParse = p->pParse; |
| 104049 | + WhereClause *pWC = p->pWC; |
| 104050 | + struct SrcList_item *pSrc = p->pSrc; |
| 104051 | + ExprList *pOrderBy = p->pOrderBy; |
| 103939 | 104052 | int i, j; |
| 103940 | 104053 | int nTerm; |
| 103941 | 104054 | struct sqlite3_index_constraint *pIdxCons; |
| 103942 | 104055 | struct sqlite3_index_orderby *pIdxOrderBy; |
| 103943 | 104056 | struct sqlite3_index_constraint_usage *pUsage; |
| | @@ -103963,16 +104076,17 @@ |
| 103963 | 104076 | ** virtual table then allocate space for the aOrderBy part of |
| 103964 | 104077 | ** the sqlite3_index_info structure. |
| 103965 | 104078 | */ |
| 103966 | 104079 | nOrderBy = 0; |
| 103967 | 104080 | if( pOrderBy ){ |
| 103968 | | - for(i=0; i<pOrderBy->nExpr; i++){ |
| 104081 | + int n = pOrderBy->nExpr; |
| 104082 | + for(i=0; i<n; i++){ |
| 103969 | 104083 | Expr *pExpr = pOrderBy->a[i].pExpr; |
| 103970 | 104084 | if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; |
| 103971 | 104085 | } |
| 103972 | | - if( i==pOrderBy->nExpr ){ |
| 103973 | | - nOrderBy = pOrderBy->nExpr; |
| 104086 | + if( i==n){ |
| 104087 | + nOrderBy = n; |
| 103974 | 104088 | } |
| 103975 | 104089 | } |
| 103976 | 104090 | |
| 103977 | 104091 | /* Allocate the sqlite3_index_info structure |
| 103978 | 104092 | */ |
| | @@ -104092,20 +104206,14 @@ |
| 104092 | 104206 | ** invocations. The sqlite3_index_info structure is also used when |
| 104093 | 104207 | ** code is generated to access the virtual table. The whereInfoDelete() |
| 104094 | 104208 | ** routine takes care of freeing the sqlite3_index_info structure after |
| 104095 | 104209 | ** everybody has finished with it. |
| 104096 | 104210 | */ |
| 104097 | | -static void bestVirtualIndex( |
| 104098 | | - Parse *pParse, /* The parsing context */ |
| 104099 | | - WhereClause *pWC, /* The WHERE clause */ |
| 104100 | | - struct SrcList_item *pSrc, /* The FROM clause term to search */ |
| 104101 | | - Bitmask notReady, /* Mask of cursors not available for index */ |
| 104102 | | - Bitmask notValid, /* Cursors not valid for any purpose */ |
| 104103 | | - ExprList *pOrderBy, /* The order by clause */ |
| 104104 | | - WhereCost *pCost, /* Lowest cost query plan */ |
| 104105 | | - sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ |
| 104106 | | -){ |
| 104211 | +static void bestVirtualIndex(WhereBestIdx *p){ |
| 104212 | + Parse *pParse = p->pParse; /* The parsing context */ |
| 104213 | + WhereClause *pWC = p->pWC; /* The WHERE clause */ |
| 104214 | + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ |
| 104107 | 104215 | Table *pTab = pSrc->pTab; |
| 104108 | 104216 | sqlite3_index_info *pIdxInfo; |
| 104109 | 104217 | struct sqlite3_index_constraint *pIdxCons; |
| 104110 | 104218 | struct sqlite3_index_constraint_usage *pUsage; |
| 104111 | 104219 | WhereTerm *pTerm; |
| | @@ -104115,19 +104223,19 @@ |
| 104115 | 104223 | |
| 104116 | 104224 | /* Make sure wsFlags is initialized to some sane value. Otherwise, if the |
| 104117 | 104225 | ** malloc in allocateIndexInfo() fails and this function returns leaving |
| 104118 | 104226 | ** wsFlags in an uninitialized state, the caller may behave unpredictably. |
| 104119 | 104227 | */ |
| 104120 | | - memset(pCost, 0, sizeof(*pCost)); |
| 104121 | | - pCost->plan.wsFlags = WHERE_VIRTUALTABLE; |
| 104228 | + memset(&p->cost, 0, sizeof(p->cost)); |
| 104229 | + p->cost.plan.wsFlags = WHERE_VIRTUALTABLE; |
| 104122 | 104230 | |
| 104123 | 104231 | /* If the sqlite3_index_info structure has not been previously |
| 104124 | 104232 | ** allocated and initialized, then allocate and initialize it now. |
| 104125 | 104233 | */ |
| 104126 | | - pIdxInfo = *ppIdxInfo; |
| 104234 | + pIdxInfo = *p->ppIdxInfo; |
| 104127 | 104235 | if( pIdxInfo==0 ){ |
| 104128 | | - *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy); |
| 104236 | + *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p); |
| 104129 | 104237 | } |
| 104130 | 104238 | if( pIdxInfo==0 ){ |
| 104131 | 104239 | return; |
| 104132 | 104240 | } |
| 104133 | 104241 | |
| | @@ -104168,11 +104276,11 @@ |
| 104168 | 104276 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 104169 | 104277 | pUsage = pIdxInfo->aConstraintUsage; |
| 104170 | 104278 | for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ |
| 104171 | 104279 | j = pIdxCons->iTermOffset; |
| 104172 | 104280 | pTerm = &pWC->a[j]; |
| 104173 | | - pIdxCons->usable = (pTerm->prereqRight¬Ready) ? 0 : 1; |
| 104281 | + pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1; |
| 104174 | 104282 | } |
| 104175 | 104283 | memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); |
| 104176 | 104284 | if( pIdxInfo->needToFreeIdxStr ){ |
| 104177 | 104285 | sqlite3_free(pIdxInfo->idxStr); |
| 104178 | 104286 | } |
| | @@ -104181,11 +104289,11 @@ |
| 104181 | 104289 | pIdxInfo->needToFreeIdxStr = 0; |
| 104182 | 104290 | pIdxInfo->orderByConsumed = 0; |
| 104183 | 104291 | /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */ |
| 104184 | 104292 | pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2); |
| 104185 | 104293 | nOrderBy = pIdxInfo->nOrderBy; |
| 104186 | | - if( !pOrderBy ){ |
| 104294 | + if( !p->pOrderBy ){ |
| 104187 | 104295 | pIdxInfo->nOrderBy = 0; |
| 104188 | 104296 | } |
| 104189 | 104297 | |
| 104190 | 104298 | if( vtabBestIndex(pParse, pTab, pIdxInfo) ){ |
| 104191 | 104299 | return; |
| | @@ -104192,20 +104300,20 @@ |
| 104192 | 104300 | } |
| 104193 | 104301 | |
| 104194 | 104302 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 104195 | 104303 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
| 104196 | 104304 | if( pUsage[i].argvIndex>0 ){ |
| 104197 | | - pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; |
| 104305 | + p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; |
| 104198 | 104306 | } |
| 104199 | 104307 | } |
| 104200 | 104308 | |
| 104201 | 104309 | /* If there is an ORDER BY clause, and the selected virtual table index |
| 104202 | 104310 | ** does not satisfy it, increase the cost of the scan accordingly. This |
| 104203 | 104311 | ** matches the processing for non-virtual tables in bestBtreeIndex(). |
| 104204 | 104312 | */ |
| 104205 | 104313 | rCost = pIdxInfo->estimatedCost; |
| 104206 | | - if( pOrderBy && pIdxInfo->orderByConsumed==0 ){ |
| 104314 | + if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){ |
| 104207 | 104315 | rCost += estLog(rCost)*rCost; |
| 104208 | 104316 | } |
| 104209 | 104317 | |
| 104210 | 104318 | /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the |
| 104211 | 104319 | ** inital value of lowestCost in this loop. If it is, then the |
| | @@ -104213,25 +104321,25 @@ |
| 104213 | 104321 | ** |
| 104214 | 104322 | ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT |
| 104215 | 104323 | ** is defined. |
| 104216 | 104324 | */ |
| 104217 | 104325 | if( (SQLITE_BIG_DBL/((double)2))<rCost ){ |
| 104218 | | - pCost->rCost = (SQLITE_BIG_DBL/((double)2)); |
| 104326 | + p->cost.rCost = (SQLITE_BIG_DBL/((double)2)); |
| 104219 | 104327 | }else{ |
| 104220 | | - pCost->rCost = rCost; |
| 104328 | + p->cost.rCost = rCost; |
| 104221 | 104329 | } |
| 104222 | | - pCost->plan.u.pVtabIdx = pIdxInfo; |
| 104330 | + p->cost.plan.u.pVtabIdx = pIdxInfo; |
| 104223 | 104331 | if( pIdxInfo->orderByConsumed ){ |
| 104224 | | - pCost->plan.wsFlags |= WHERE_ORDERBY; |
| 104332 | + p->cost.plan.wsFlags |= WHERE_ORDERBY; |
| 104225 | 104333 | } |
| 104226 | | - pCost->plan.nEq = 0; |
| 104334 | + p->cost.plan.nEq = 0; |
| 104227 | 104335 | pIdxInfo->nOrderBy = nOrderBy; |
| 104228 | 104336 | |
| 104229 | 104337 | /* Try to find a more efficient access pattern by using multiple indexes |
| 104230 | 104338 | ** to optimize an OR expression within the WHERE clause. |
| 104231 | 104339 | */ |
| 104232 | | - bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); |
| 104340 | + bestOrClauseIndex(p); |
| 104233 | 104341 | } |
| 104234 | 104342 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 104235 | 104343 | |
| 104236 | 104344 | #ifdef SQLITE_ENABLE_STAT3 |
| 104237 | 104345 | /* |
| | @@ -104626,15 +104734,88 @@ |
| 104626 | 104734 | } |
| 104627 | 104735 | return rc; |
| 104628 | 104736 | } |
| 104629 | 104737 | #endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 104630 | 104738 | |
| 104739 | +/* |
| 104740 | +** Check to see if column iCol of the table with cursor iTab will appear |
| 104741 | +** in sorted order according to the current query plan. Return true if |
| 104742 | +** it will and false if not. |
| 104743 | +** |
| 104744 | +** If *pbRev is initially 2 (meaning "unknown") then set *pbRev to the |
| 104745 | +** sort order of iTab.iCol. If *pbRev is 0 or 1 but does not match |
| 104746 | +** the sort order of iTab.iCol, then consider the column to be unordered. |
| 104747 | +*/ |
| 104748 | +static int isOrderedColumn(WhereBestIdx *p, int iTab, int iCol, int *pbRev){ |
| 104749 | + int i, j; |
| 104750 | + WhereLevel *pLevel = &p->aLevel[p->i-1]; |
| 104751 | + Index *pIdx; |
| 104752 | + u8 sortOrder; |
| 104753 | + for(i=p->i-1; i>=0; i--, pLevel--){ |
| 104754 | + if( pLevel->iTabCur!=iTab ) continue; |
| 104755 | + if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ |
| 104756 | + pIdx = pLevel->plan.u.pIdx; |
| 104757 | + if( iCol<0 ){ |
| 104758 | + sortOrder = 0; |
| 104759 | + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); |
| 104760 | + }else{ |
| 104761 | + for(j=0; j<pIdx->nColumn; j++){ |
| 104762 | + if( iCol==pIdx->aiColumn[j] ) break; |
| 104763 | + } |
| 104764 | + if( j>=pIdx->nColumn ) return 0; |
| 104765 | + sortOrder = pIdx->aSortOrder[j]; |
| 104766 | + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); |
| 104767 | + } |
| 104768 | + }else{ |
| 104769 | + if( iCol!=(-1) ) return 0; |
| 104770 | + sortOrder = 0; |
| 104771 | + testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ); |
| 104772 | + } |
| 104773 | + if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){ |
| 104774 | + assert( sortOrder==0 || sortOrder==1 ); |
| 104775 | + testcase( sortOrder==1 ); |
| 104776 | + sortOrder = 1 - sortOrder; |
| 104777 | + } |
| 104778 | + if( *pbRev==2 ){ |
| 104779 | + *pbRev = sortOrder; |
| 104780 | + return 1; |
| 104781 | + } |
| 104782 | + return (*pbRev==sortOrder); |
| 104783 | + } |
| 104784 | + return 0; |
| 104785 | +} |
| 104786 | + |
| 104787 | +/* |
| 104788 | +** pTerm is an == constraint. Check to see if the other side of |
| 104789 | +** the == is a constant or a value that is guaranteed to be ordered |
| 104790 | +** by outer loops. Return 1 if pTerm is ordered, and 0 if not. |
| 104791 | +*/ |
| 104792 | +static int isOrderedTerm(WhereBestIdx *p, WhereTerm *pTerm, int *pbRev){ |
| 104793 | + Expr *pExpr = pTerm->pExpr; |
| 104794 | + assert( pExpr->op==TK_EQ ); |
| 104795 | + assert( pExpr->pLeft!=0 && pExpr->pLeft->op==TK_COLUMN ); |
| 104796 | + assert( pExpr->pRight!=0 ); |
| 104797 | + if( p->i==0 ){ |
| 104798 | + return 1; /* All == are ordered in the outer loop */ |
| 104799 | + } |
| 104800 | + if( pTerm->prereqRight==0 ){ |
| 104801 | + return 1; /* RHS of the == is a constant */ |
| 104802 | + } |
| 104803 | + if( pExpr->pRight->op==TK_COLUMN |
| 104804 | + && isOrderedColumn(p, pExpr->pRight->iTable, pExpr->pRight->iColumn, pbRev) |
| 104805 | + ){ |
| 104806 | + return 1; |
| 104807 | + } |
| 104808 | + |
| 104809 | + /* If we cannot prove that the constraint is ordered, assume it is not */ |
| 104810 | + return 0; |
| 104811 | +} |
| 104812 | + |
| 104631 | 104813 | |
| 104632 | 104814 | /* |
| 104633 | 104815 | ** Find the best query plan for accessing a particular table. Write the |
| 104634 | | -** best query plan and its cost into the WhereCost object supplied as the |
| 104635 | | -** last parameter. |
| 104816 | +** best query plan and its cost into the p->cost. |
| 104636 | 104817 | ** |
| 104637 | 104818 | ** The lowest cost plan wins. The cost is an estimate of the amount of |
| 104638 | 104819 | ** CPU and disk I/O needed to process the requested result. |
| 104639 | 104820 | ** Factors that influence cost include: |
| 104640 | 104821 | ** |
| | @@ -104655,33 +104836,27 @@ |
| 104655 | 104836 | ** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table |
| 104656 | 104837 | ** in the SELECT statement, then no indexes are considered. However, the |
| 104657 | 104838 | ** selected plan may still take advantage of the built-in rowid primary key |
| 104658 | 104839 | ** index. |
| 104659 | 104840 | */ |
| 104660 | | -static void bestBtreeIndex( |
| 104661 | | - Parse *pParse, /* The parsing context */ |
| 104662 | | - WhereClause *pWC, /* The WHERE clause */ |
| 104663 | | - struct SrcList_item *pSrc, /* The FROM clause term to search */ |
| 104664 | | - Bitmask notReady, /* Mask of cursors not available for indexing */ |
| 104665 | | - Bitmask notValid, /* Cursors not available for any purpose */ |
| 104666 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 104667 | | - ExprList *pDistinct, /* The select-list if query is DISTINCT */ |
| 104668 | | - WhereCost *pCost /* Lowest cost query plan */ |
| 104669 | | -){ |
| 104841 | +static void bestBtreeIndex(WhereBestIdx *p){ |
| 104842 | + Parse *pParse = p->pParse; /* The parsing context */ |
| 104843 | + WhereClause *pWC = p->pWC; /* The WHERE clause */ |
| 104844 | + struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */ |
| 104670 | 104845 | int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ |
| 104671 | 104846 | Index *pProbe; /* An index we are evaluating */ |
| 104672 | 104847 | Index *pIdx; /* Copy of pProbe, or zero for IPK index */ |
| 104673 | 104848 | int eqTermMask; /* Current mask of valid equality operators */ |
| 104674 | 104849 | int idxEqTermMask; /* Index mask of valid equality operators */ |
| 104675 | 104850 | Index sPk; /* A fake index object for the primary key */ |
| 104676 | 104851 | tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ |
| 104677 | 104852 | int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ |
| 104678 | | - int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */ |
| 104853 | + int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */ |
| 104679 | 104854 | |
| 104680 | 104855 | /* Initialize the cost to a worst-case value */ |
| 104681 | | - memset(pCost, 0, sizeof(*pCost)); |
| 104682 | | - pCost->rCost = SQLITE_BIG_DBL; |
| 104856 | + memset(&p->cost, 0, sizeof(p->cost)); |
| 104857 | + p->cost.rCost = SQLITE_BIG_DBL; |
| 104683 | 104858 | |
| 104684 | 104859 | /* If the pSrc table is the right table of a LEFT JOIN then we may not |
| 104685 | 104860 | ** use an index to satisfy IS NULL constraints on that table. This is |
| 104686 | 104861 | ** because columns might end up being NULL if the table does not match - |
| 104687 | 104862 | ** a circumstance which the index cannot help us discover. Ticket #2177. |
| | @@ -104730,11 +104905,11 @@ |
| 104730 | 104905 | for(; pProbe; pIdx=pProbe=pProbe->pNext){ |
| 104731 | 104906 | const tRowcnt * const aiRowEst = pProbe->aiRowEst; |
| 104732 | 104907 | double cost; /* Cost of using pProbe */ |
| 104733 | 104908 | double nRow; /* Estimated number of rows in result set */ |
| 104734 | 104909 | double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */ |
| 104735 | | - int rev; /* True to scan in reverse order */ |
| 104910 | + int bRev = 2; /* 0=forward scan. 1=reverse. 2=undecided */ |
| 104736 | 104911 | int wsFlags = 0; |
| 104737 | 104912 | Bitmask used = 0; |
| 104738 | 104913 | |
| 104739 | 104914 | /* The following variables are populated based on the properties of |
| 104740 | 104915 | ** index being evaluated. They are then used to determine the expected |
| | @@ -104763,10 +104938,14 @@ |
| 104763 | 104938 | ** |
| 104764 | 104939 | ** If there exists a WHERE term of the form "x IN (SELECT ...)", then |
| 104765 | 104940 | ** the sub-select is assumed to return 25 rows for the purposes of |
| 104766 | 104941 | ** determining nInMul. |
| 104767 | 104942 | ** |
| 104943 | + ** nOrdered: |
| 104944 | + ** The number of equality terms that are constrainted by outer loop |
| 104945 | + ** variables that are well-ordered. |
| 104946 | + ** |
| 104768 | 104947 | ** bInEst: |
| 104769 | 104948 | ** Set to true if there was at least one "x IN (SELECT ...)" term used |
| 104770 | 104949 | ** in determining the value of nInMul. Note that the RHS of the |
| 104771 | 104950 | ** IN operator must be a SELECT, not a value list, for this variable |
| 104772 | 104951 | ** to be true. |
| | @@ -104781,10 +104960,14 @@ |
| 104781 | 104960 | ** bSort: |
| 104782 | 104961 | ** Boolean. True if there is an ORDER BY clause that will require an |
| 104783 | 104962 | ** external sort (i.e. scanning the index being evaluated will not |
| 104784 | 104963 | ** correctly order records). |
| 104785 | 104964 | ** |
| 104965 | + ** bDistinct: |
| 104966 | + ** Boolean. True if there is a DISTINCT clause that will require an |
| 104967 | + ** external btree. |
| 104968 | + ** |
| 104786 | 104969 | ** bLookup: |
| 104787 | 104970 | ** Boolean. True if a table lookup is required for each index entry |
| 104788 | 104971 | ** visited. In other words, true if this is not a covering index. |
| 104789 | 104972 | ** This is always false for the rowid primary key index of a table. |
| 104790 | 104973 | ** For other indexes, it is true unless all the columns of the table |
| | @@ -104797,26 +104980,33 @@ |
| 104797 | 104980 | ** |
| 104798 | 104981 | ** SELECT a, b FROM tbl WHERE a = 1; |
| 104799 | 104982 | ** SELECT a, b, c FROM tbl WHERE a = 1; |
| 104800 | 104983 | */ |
| 104801 | 104984 | int nEq; /* Number of == or IN terms matching index */ |
| 104985 | + int nOrdered; /* Number of ordered terms matching index */ |
| 104802 | 104986 | int bInEst = 0; /* True if "x IN (SELECT...)" seen */ |
| 104803 | 104987 | int nInMul = 1; /* Number of distinct equalities to lookup */ |
| 104804 | 104988 | double rangeDiv = (double)1; /* Estimated reduction in search space */ |
| 104805 | 104989 | int nBound = 0; /* Number of range constraints seen */ |
| 104806 | | - int bSort = !!pOrderBy; /* True if external sort required */ |
| 104807 | | - int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */ |
| 104990 | + int bSort; /* True if external sort required */ |
| 104991 | + int bDist; /* True if index cannot help with DISTINCT */ |
| 104808 | 104992 | int bLookup = 0; /* True if not a covering index */ |
| 104993 | + int nOBSat = 0; /* Number of ORDER BY terms satisfied */ |
| 104994 | + int nOrderBy; /* Number of ORDER BY terms */ |
| 104809 | 104995 | WhereTerm *pTerm; /* A single term of the WHERE clause */ |
| 104810 | 104996 | #ifdef SQLITE_ENABLE_STAT3 |
| 104811 | 104997 | WhereTerm *pFirstTerm = 0; /* First term matching the index */ |
| 104812 | 104998 | #endif |
| 104999 | + |
| 105000 | + nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0; |
| 105001 | + bSort = nOrderBy>0 && (p->i==0 || p->aLevel[p->i-1].plan.nOBSat<nOrderBy); |
| 105002 | + bDist = p->i==0 && p->pDistinct!=0; |
| 104813 | 105003 | |
| 104814 | 105004 | /* Determine the values of nEq and nInMul */ |
| 104815 | | - for(nEq=0; nEq<pProbe->nColumn; nEq++){ |
| 105005 | + for(nEq=nOrdered=0; nEq<pProbe->nColumn; nEq++){ |
| 104816 | 105006 | int j = pProbe->aiColumn[nEq]; |
| 104817 | | - pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); |
| 105007 | + pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx); |
| 104818 | 105008 | if( pTerm==0 ) break; |
| 104819 | 105009 | wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); |
| 104820 | 105010 | testcase( pTerm->pWC!=pWC ); |
| 104821 | 105011 | if( pTerm->eOperator & WO_IN ){ |
| 104822 | 105012 | Expr *pExpr = pTerm->pExpr; |
| | @@ -104829,10 +105019,13 @@ |
| 104829 | 105019 | /* "x IN (value, value, ...)" */ |
| 104830 | 105020 | nInMul *= pExpr->x.pList->nExpr; |
| 104831 | 105021 | } |
| 104832 | 105022 | }else if( pTerm->eOperator & WO_ISNULL ){ |
| 104833 | 105023 | wsFlags |= WHERE_COLUMN_NULL; |
| 105024 | + if( nEq==nOrdered ) nOrdered++; |
| 105025 | + }else if( bSort && nEq==nOrdered && isOrderedTerm(p, pTerm, &bRev) ){ |
| 105026 | + nOrdered++; |
| 104834 | 105027 | } |
| 104835 | 105028 | #ifdef SQLITE_ENABLE_STAT3 |
| 104836 | 105029 | if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; |
| 104837 | 105030 | #endif |
| 104838 | 105031 | used |= pTerm->prereqRight; |
| | @@ -104853,13 +105046,14 @@ |
| 104853 | 105046 | if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ |
| 104854 | 105047 | wsFlags |= WHERE_UNIQUE; |
| 104855 | 105048 | } |
| 104856 | 105049 | }else if( pProbe->bUnordered==0 ){ |
| 104857 | 105050 | int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]); |
| 104858 | | - if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ |
| 104859 | | - WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); |
| 104860 | | - WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); |
| 105051 | + if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ |
| 105052 | + WhereTerm *pTop, *pBtm; |
| 105053 | + pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx); |
| 105054 | + pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx); |
| 104861 | 105055 | whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv); |
| 104862 | 105056 | if( pTop ){ |
| 104863 | 105057 | nBound = 1; |
| 104864 | 105058 | wsFlags |= WHERE_TOP_LIMIT; |
| 104865 | 105059 | used |= pTop->prereqRight; |
| | @@ -104877,22 +105071,29 @@ |
| 104877 | 105071 | |
| 104878 | 105072 | /* If there is an ORDER BY clause and the index being considered will |
| 104879 | 105073 | ** naturally scan rows in the required order, set the appropriate flags |
| 104880 | 105074 | ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index |
| 104881 | 105075 | ** will scan rows in a different order, set the bSort variable. */ |
| 104882 | | - if( isSortingIndex( |
| 104883 | | - pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev) |
| 104884 | | - ){ |
| 104885 | | - bSort = 0; |
| 104886 | | - wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; |
| 104887 | | - wsFlags |= (rev ? WHERE_REVERSE : 0); |
| 105076 | + assert( bRev>=0 && bRev<=2 ); |
| 105077 | + if( bSort ){ |
| 105078 | + testcase( bRev==0 ); |
| 105079 | + testcase( bRev==1 ); |
| 105080 | + testcase( bRev==2 ); |
| 105081 | + nOBSat = isSortingIndex(p, pProbe, iCur, nOrdered, |
| 105082 | + wsFlags, bRev&1, &bRev); |
| 105083 | + if( nOrderBy==nOBSat ){ |
| 105084 | + bSort = 0; |
| 105085 | + wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; |
| 105086 | + } |
| 105087 | + if( bRev & 1 ) wsFlags |= WHERE_REVERSE; |
| 104888 | 105088 | } |
| 104889 | 105089 | |
| 104890 | 105090 | /* If there is a DISTINCT qualifier and this index will scan rows in |
| 104891 | 105091 | ** order of the DISTINCT expressions, clear bDist and set the appropriate |
| 104892 | 105092 | ** flags in wsFlags. */ |
| 104893 | | - if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq) |
| 105093 | + if( bDist |
| 105094 | + && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, nEq) |
| 104894 | 105095 | && (wsFlags & WHERE_COLUMN_IN)==0 |
| 104895 | 105096 | ){ |
| 104896 | 105097 | bDist = 0; |
| 104897 | 105098 | wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT; |
| 104898 | 105099 | } |
| | @@ -104965,16 +105166,14 @@ |
| 104965 | 105166 | ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do |
| 104966 | 105167 | ** not give us data on the relative sizes of table and index records. |
| 104967 | 105168 | ** So this computation assumes table records are about twice as big |
| 104968 | 105169 | ** as index records |
| 104969 | 105170 | */ |
| 104970 | | - if( wsFlags==WHERE_IDX_ONLY |
| 105171 | + if( (wsFlags&~WHERE_REVERSE)==WHERE_IDX_ONLY |
| 104971 | 105172 | && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 |
| 104972 | 105173 | && sqlite3GlobalConfig.bUseCis |
| 104973 | | -#ifndef SQLITE_OMIT_BUILTIN_TEST |
| 104974 | | - && (pParse->db->flags & SQLITE_CoverIdxScan)==0 |
| 104975 | | -#endif |
| 105174 | + && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan) |
| 104976 | 105175 | ){ |
| 104977 | 105176 | /* This index is not useful for indexing, but it is a covering index. |
| 104978 | 105177 | ** A full-scan of the index might be a little faster than a full-scan |
| 104979 | 105178 | ** of the table, so give this case a cost slightly less than a table |
| 104980 | 105179 | ** scan. */ |
| | @@ -105024,11 +105223,11 @@ |
| 105024 | 105223 | ** adds C*N*log10(N) to the cost, where N is the number of rows to be |
| 105025 | 105224 | ** sorted and C is a factor between 1.95 and 4.3. We will split the |
| 105026 | 105225 | ** difference and select C of 3.0. |
| 105027 | 105226 | */ |
| 105028 | 105227 | if( bSort ){ |
| 105029 | | - cost += nRow*estLog(nRow)*3; |
| 105228 | + cost += nRow*estLog(nRow*(nOrderBy - nOBSat)/nOrderBy)*3; |
| 105030 | 105229 | } |
| 105031 | 105230 | if( bDist ){ |
| 105032 | 105231 | cost += nRow*estLog(nRow)*3; |
| 105033 | 105232 | } |
| 105034 | 105233 | |
| | @@ -105048,20 +105247,20 @@ |
| 105048 | 105247 | ** tables that are not in outer loops. If notReady is used here instead |
| 105049 | 105248 | ** of notValid, then a optimal index that depends on inner joins loops |
| 105050 | 105249 | ** might be selected even when there exists an optimal index that has |
| 105051 | 105250 | ** no such dependency. |
| 105052 | 105251 | */ |
| 105053 | | - if( nRow>2 && cost<=pCost->rCost ){ |
| 105252 | + if( nRow>2 && cost<=p->cost.rCost ){ |
| 105054 | 105253 | int k; /* Loop counter */ |
| 105055 | 105254 | int nSkipEq = nEq; /* Number of == constraints to skip */ |
| 105056 | 105255 | int nSkipRange = nBound; /* Number of < constraints to skip */ |
| 105057 | 105256 | Bitmask thisTab; /* Bitmap for pSrc */ |
| 105058 | 105257 | |
| 105059 | 105258 | thisTab = getMask(pWC->pMaskSet, iCur); |
| 105060 | 105259 | for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){ |
| 105061 | 105260 | if( pTerm->wtFlags & TERM_VIRTUAL ) continue; |
| 105062 | | - if( (pTerm->prereqAll & notValid)!=thisTab ) continue; |
| 105261 | + if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue; |
| 105063 | 105262 | if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){ |
| 105064 | 105263 | if( nSkipEq ){ |
| 105065 | 105264 | /* Ignore the first nEq equality matches since the index |
| 105066 | 105265 | ** has already accounted for these */ |
| 105067 | 105266 | nSkipEq--; |
| | @@ -105092,29 +105291,32 @@ |
| 105092 | 105291 | if( nRow<2 ) nRow = 2; |
| 105093 | 105292 | } |
| 105094 | 105293 | |
| 105095 | 105294 | |
| 105096 | 105295 | WHERETRACE(( |
| 105097 | | - "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" |
| 105098 | | - " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", |
| 105296 | + "%s(%s):\n" |
| 105297 | + " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n" |
| 105298 | + " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n" |
| 105299 | + " used=0x%llx nOrdered=%d nOBSat=%d\n", |
| 105099 | 105300 | pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), |
| 105100 | 105301 | nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, |
| 105101 | | - notReady, log10N, nRow, cost, used |
| 105302 | + p->notReady, log10N, nRow, cost, used, nOrdered, nOBSat |
| 105102 | 105303 | )); |
| 105103 | 105304 | |
| 105104 | 105305 | /* If this index is the best we have seen so far, then record this |
| 105105 | 105306 | ** index and its cost in the pCost structure. |
| 105106 | 105307 | */ |
| 105107 | 105308 | if( (!pIdx || wsFlags) |
| 105108 | | - && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow)) |
| 105309 | + && (cost<p->cost.rCost || (cost<=p->cost.rCost && nRow<p->cost.plan.nRow)) |
| 105109 | 105310 | ){ |
| 105110 | | - pCost->rCost = cost; |
| 105111 | | - pCost->used = used; |
| 105112 | | - pCost->plan.nRow = nRow; |
| 105113 | | - pCost->plan.wsFlags = (wsFlags&wsFlagMask); |
| 105114 | | - pCost->plan.nEq = nEq; |
| 105115 | | - pCost->plan.u.pIdx = pIdx; |
| 105311 | + p->cost.rCost = cost; |
| 105312 | + p->cost.used = used; |
| 105313 | + p->cost.plan.nRow = nRow; |
| 105314 | + p->cost.plan.wsFlags = (wsFlags&wsFlagMask); |
| 105315 | + p->cost.plan.nEq = nEq; |
| 105316 | + p->cost.plan.nOBSat = nOBSat; |
| 105317 | + p->cost.plan.u.pIdx = pIdx; |
| 105116 | 105318 | } |
| 105117 | 105319 | |
| 105118 | 105320 | /* If there was an INDEXED BY clause, then only that one index is |
| 105119 | 105321 | ** considered. */ |
| 105120 | 105322 | if( pSrc->pIndex ) break; |
| | @@ -105127,58 +105329,57 @@ |
| 105127 | 105329 | /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag |
| 105128 | 105330 | ** is set, then reverse the order that the index will be scanned |
| 105129 | 105331 | ** in. This is used for application testing, to help find cases |
| 105130 | 105332 | ** where application behaviour depends on the (undefined) order that |
| 105131 | 105333 | ** SQLite outputs rows in in the absence of an ORDER BY clause. */ |
| 105132 | | - if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ |
| 105133 | | - pCost->plan.wsFlags |= WHERE_REVERSE; |
| 105334 | + if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ |
| 105335 | + p->cost.plan.wsFlags |= WHERE_REVERSE; |
| 105134 | 105336 | } |
| 105135 | 105337 | |
| 105136 | | - assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 ); |
| 105137 | | - assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 ); |
| 105338 | + assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERBY)==0 ); |
| 105339 | + assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 ); |
| 105138 | 105340 | assert( pSrc->pIndex==0 |
| 105139 | | - || pCost->plan.u.pIdx==0 |
| 105140 | | - || pCost->plan.u.pIdx==pSrc->pIndex |
| 105341 | + || p->cost.plan.u.pIdx==0 |
| 105342 | + || p->cost.plan.u.pIdx==pSrc->pIndex |
| 105141 | 105343 | ); |
| 105142 | 105344 | |
| 105143 | 105345 | WHERETRACE(("best index is: %s\n", |
| 105144 | | - ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : |
| 105145 | | - pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") |
| 105346 | + ((p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : |
| 105347 | + p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk") |
| 105146 | 105348 | )); |
| 105147 | 105349 | |
| 105148 | | - bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); |
| 105149 | | - bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost); |
| 105150 | | - pCost->plan.wsFlags |= eqTermMask; |
| 105350 | + bestOrClauseIndex(p); |
| 105351 | + bestAutomaticIndex(p); |
| 105352 | + p->cost.plan.wsFlags |= eqTermMask; |
| 105151 | 105353 | } |
| 105152 | 105354 | |
| 105153 | 105355 | /* |
| 105154 | 105356 | ** Find the query plan for accessing table pSrc->pTab. Write the |
| 105155 | 105357 | ** best query plan and its cost into the WhereCost object supplied |
| 105156 | 105358 | ** as the last parameter. This function may calculate the cost of |
| 105157 | 105359 | ** both real and virtual table scans. |
| 105360 | +** |
| 105361 | +** This function does not take ORDER BY or DISTINCT into account. Nor |
| 105362 | +** does it remember the virtual table query plan. All it does is compute |
| 105363 | +** the cost while determining if an OR optimization is applicable. The |
| 105364 | +** details will be reconsidered later if the optimization is found to be |
| 105365 | +** applicable. |
| 105158 | 105366 | */ |
| 105159 | | -static void bestIndex( |
| 105160 | | - Parse *pParse, /* The parsing context */ |
| 105161 | | - WhereClause *pWC, /* The WHERE clause */ |
| 105162 | | - struct SrcList_item *pSrc, /* The FROM clause term to search */ |
| 105163 | | - Bitmask notReady, /* Mask of cursors not available for indexing */ |
| 105164 | | - Bitmask notValid, /* Cursors not available for any purpose */ |
| 105165 | | - ExprList *pOrderBy, /* The ORDER BY clause */ |
| 105166 | | - WhereCost *pCost /* Lowest cost query plan */ |
| 105167 | | -){ |
| 105367 | +static void bestIndex(WhereBestIdx *p){ |
| 105168 | 105368 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 105169 | | - if( IsVirtual(pSrc->pTab) ){ |
| 105170 | | - sqlite3_index_info *p = 0; |
| 105171 | | - bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p); |
| 105172 | | - if( p->needToFreeIdxStr ){ |
| 105173 | | - sqlite3_free(p->idxStr); |
| 105369 | + if( IsVirtual(p->pSrc->pTab) ){ |
| 105370 | + sqlite3_index_info *pIdxInfo = 0; |
| 105371 | + p->ppIdxInfo = &pIdxInfo; |
| 105372 | + bestVirtualIndex(p); |
| 105373 | + if( pIdxInfo->needToFreeIdxStr ){ |
| 105374 | + sqlite3_free(pIdxInfo->idxStr); |
| 105174 | 105375 | } |
| 105175 | | - sqlite3DbFree(pParse->db, p); |
| 105376 | + sqlite3DbFree(p->pParse->db, pIdxInfo); |
| 105176 | 105377 | }else |
| 105177 | 105378 | #endif |
| 105178 | 105379 | { |
| 105179 | | - bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost); |
| 105380 | + bestBtreeIndex(p); |
| 105180 | 105381 | } |
| 105181 | 105382 | } |
| 105182 | 105383 | |
| 105183 | 105384 | /* |
| 105184 | 105385 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| | @@ -106432,46 +106633,50 @@ |
| 106432 | 106633 | ** fi |
| 106433 | 106634 | ** end |
| 106434 | 106635 | ** |
| 106435 | 106636 | ** ORDER BY CLAUSE PROCESSING |
| 106436 | 106637 | ** |
| 106437 | | -** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement, |
| 106638 | +** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement, |
| 106438 | 106639 | ** if there is one. If there is no ORDER BY clause or if this routine |
| 106439 | | -** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL. |
| 106640 | +** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. |
| 106440 | 106641 | ** |
| 106441 | 106642 | ** If an index can be used so that the natural output order of the table |
| 106442 | 106643 | ** scan is correct for the ORDER BY clause, then that index is used and |
| 106443 | | -** *ppOrderBy is set to NULL. This is an optimization that prevents an |
| 106444 | | -** unnecessary sort of the result set if an index appropriate for the |
| 106445 | | -** ORDER BY clause already exists. |
| 106644 | +** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr. This |
| 106645 | +** is an optimization that prevents an unnecessary sort of the result set |
| 106646 | +** if an index appropriate for the ORDER BY clause already exists. |
| 106446 | 106647 | ** |
| 106447 | 106648 | ** If the where clause loops cannot be arranged to provide the correct |
| 106448 | | -** output order, then the *ppOrderBy is unchanged. |
| 106649 | +** output order, then WhereInfo.nOBSat is 0. |
| 106449 | 106650 | */ |
| 106450 | 106651 | SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( |
| 106451 | 106652 | Parse *pParse, /* The parser context */ |
| 106452 | 106653 | SrcList *pTabList, /* A list of all tables to be scanned */ |
| 106453 | 106654 | Expr *pWhere, /* The WHERE clause */ |
| 106454 | | - ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ |
| 106655 | + ExprList *pOrderBy, /* An ORDER BY clause, or NULL */ |
| 106455 | 106656 | ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */ |
| 106456 | 106657 | u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ |
| 106457 | 106658 | int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */ |
| 106458 | 106659 | ){ |
| 106459 | | - int i; /* Loop counter */ |
| 106460 | 106660 | int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ |
| 106461 | 106661 | int nTabList; /* Number of elements in pTabList */ |
| 106462 | 106662 | WhereInfo *pWInfo; /* Will become the return value of this function */ |
| 106463 | 106663 | Vdbe *v = pParse->pVdbe; /* The virtual database engine */ |
| 106464 | 106664 | Bitmask notReady; /* Cursors that are not yet positioned */ |
| 106665 | + WhereBestIdx sWBI; /* Best index search context */ |
| 106465 | 106666 | WhereMaskSet *pMaskSet; /* The expression mask set */ |
| 106466 | | - WhereClause *pWC; /* Decomposition of the WHERE clause */ |
| 106467 | | - struct SrcList_item *pTabItem; /* A single entry from pTabList */ |
| 106468 | | - WhereLevel *pLevel; /* A single level in the pWInfo list */ |
| 106469 | | - int iFrom; /* First unused FROM clause element */ |
| 106667 | + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ |
| 106668 | + int iFrom; /* First unused FROM clause element */ |
| 106470 | 106669 | int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */ |
| 106670 | + int ii; /* Loop counter */ |
| 106471 | 106671 | sqlite3 *db; /* Database connection */ |
| 106472 | 106672 | |
| 106673 | + |
| 106674 | + /* Variable initialization */ |
| 106675 | + memset(&sWBI, 0, sizeof(sWBI)); |
| 106676 | + sWBI.pParse = pParse; |
| 106677 | + |
| 106473 | 106678 | /* The number of tables in the FROM clause is limited by the number of |
| 106474 | 106679 | ** bits in a Bitmask |
| 106475 | 106680 | */ |
| 106476 | 106681 | testcase( pTabList->nSrc==BMS ); |
| 106477 | 106682 | if( pTabList->nSrc>BMS ){ |
| | @@ -106507,26 +106712,27 @@ |
| 106507 | 106712 | } |
| 106508 | 106713 | pWInfo->nLevel = nTabList; |
| 106509 | 106714 | pWInfo->pParse = pParse; |
| 106510 | 106715 | pWInfo->pTabList = pTabList; |
| 106511 | 106716 | pWInfo->iBreak = sqlite3VdbeMakeLabel(v); |
| 106512 | | - pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; |
| 106717 | + pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; |
| 106513 | 106718 | pWInfo->wctrlFlags = wctrlFlags; |
| 106514 | 106719 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 106515 | | - pMaskSet = (WhereMaskSet*)&pWC[1]; |
| 106720 | + pMaskSet = (WhereMaskSet*)&sWBI.pWC[1]; |
| 106721 | + sWBI.aLevel = pWInfo->a; |
| 106516 | 106722 | |
| 106517 | 106723 | /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via |
| 106518 | 106724 | ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ |
| 106519 | | - if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0; |
| 106725 | + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0; |
| 106520 | 106726 | |
| 106521 | 106727 | /* Split the WHERE clause into separate subexpressions where each |
| 106522 | 106728 | ** subexpression is separated by an AND operator. |
| 106523 | 106729 | */ |
| 106524 | 106730 | initMaskSet(pMaskSet); |
| 106525 | | - whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags); |
| 106731 | + whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags); |
| 106526 | 106732 | sqlite3ExprCodeConstants(pParse, pWhere); |
| 106527 | | - whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ |
| 106733 | + whereSplit(sWBI.pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ |
| 106528 | 106734 | |
| 106529 | 106735 | /* Special case: a WHERE clause that is constant. Evaluate the |
| 106530 | 106736 | ** expression and either jump over all of the code or fall thru. |
| 106531 | 106737 | */ |
| 106532 | 106738 | if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){ |
| | @@ -106553,24 +106759,24 @@ |
| 106553 | 106759 | ** Note that bitmasks are created for all pTabList->nSrc tables in |
| 106554 | 106760 | ** pTabList, not just the first nTabList tables. nTabList is normally |
| 106555 | 106761 | ** equal to pTabList->nSrc but might be shortened to 1 if the |
| 106556 | 106762 | ** WHERE_ONETABLE_ONLY flag is set. |
| 106557 | 106763 | */ |
| 106558 | | - assert( pWC->vmask==0 && pMaskSet->n==0 ); |
| 106559 | | - for(i=0; i<pTabList->nSrc; i++){ |
| 106560 | | - createMask(pMaskSet, pTabList->a[i].iCursor); |
| 106764 | + assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 ); |
| 106765 | + for(ii=0; ii<pTabList->nSrc; ii++){ |
| 106766 | + createMask(pMaskSet, pTabList->a[ii].iCursor); |
| 106561 | 106767 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 106562 | | - if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ |
| 106563 | | - pWC->vmask |= ((Bitmask)1 << i); |
| 106768 | + if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){ |
| 106769 | + sWBI.pWC->vmask |= ((Bitmask)1 << ii); |
| 106564 | 106770 | } |
| 106565 | 106771 | #endif |
| 106566 | 106772 | } |
| 106567 | 106773 | #ifndef NDEBUG |
| 106568 | 106774 | { |
| 106569 | 106775 | Bitmask toTheLeft = 0; |
| 106570 | | - for(i=0; i<pTabList->nSrc; i++){ |
| 106571 | | - Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor); |
| 106776 | + for(ii=0; ii<pTabList->nSrc; ii++){ |
| 106777 | + Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor); |
| 106572 | 106778 | assert( (m-1)==toTheLeft ); |
| 106573 | 106779 | toTheLeft |= m; |
| 106574 | 106780 | } |
| 106575 | 106781 | } |
| 106576 | 106782 | #endif |
| | @@ -106578,20 +106784,20 @@ |
| 106578 | 106784 | /* Analyze all of the subexpressions. Note that exprAnalyze() might |
| 106579 | 106785 | ** add new virtual terms onto the end of the WHERE clause. We do not |
| 106580 | 106786 | ** want to analyze these virtual terms, so start analyzing at the end |
| 106581 | 106787 | ** and work forward so that the added virtual terms are never processed. |
| 106582 | 106788 | */ |
| 106583 | | - exprAnalyzeAll(pTabList, pWC); |
| 106789 | + exprAnalyzeAll(pTabList, sWBI.pWC); |
| 106584 | 106790 | if( db->mallocFailed ){ |
| 106585 | 106791 | goto whereBeginError; |
| 106586 | 106792 | } |
| 106587 | 106793 | |
| 106588 | 106794 | /* Check if the DISTINCT qualifier, if there is one, is redundant. |
| 106589 | 106795 | ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to |
| 106590 | 106796 | ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT. |
| 106591 | 106797 | */ |
| 106592 | | - if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){ |
| 106798 | + if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){ |
| 106593 | 106799 | pDistinct = 0; |
| 106594 | 106800 | pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; |
| 106595 | 106801 | } |
| 106596 | 106802 | |
| 106597 | 106803 | /* Chose the best index to use for each table in the FROM clause. |
| | @@ -106607,14 +106813,17 @@ |
| 106607 | 106813 | ** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term |
| 106608 | 106814 | ** |
| 106609 | 106815 | ** This loop also figures out the nesting order of tables in the FROM |
| 106610 | 106816 | ** clause. |
| 106611 | 106817 | */ |
| 106612 | | - notReady = ~(Bitmask)0; |
| 106818 | + sWBI.notValid = ~(Bitmask)0; |
| 106819 | + sWBI.pOrderBy = pOrderBy; |
| 106820 | + sWBI.n = nTabList; |
| 106821 | + sWBI.pDistinct = pDistinct; |
| 106613 | 106822 | andFlags = ~0; |
| 106614 | 106823 | WHERETRACE(("*** Optimizer Start ***\n")); |
| 106615 | | - for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ |
| 106824 | + for(sWBI.i=iFrom=0, pLevel=pWInfo->a; sWBI.i<nTabList; sWBI.i++, pLevel++){ |
| 106616 | 106825 | WhereCost bestPlan; /* Most efficient plan seen so far */ |
| 106617 | 106826 | Index *pIdx; /* Index for FROM table at pTabItem */ |
| 106618 | 106827 | int j; /* For looping over FROM tables */ |
| 106619 | 106828 | int bestJ = -1; /* The value of j */ |
| 106620 | 106829 | Bitmask m; /* Bitmask value for j or bestJ */ |
| | @@ -106622,11 +106831,11 @@ |
| 106622 | 106831 | int nUnconstrained; /* Number tables without INDEXED BY */ |
| 106623 | 106832 | Bitmask notIndexed; /* Mask of tables that cannot use an index */ |
| 106624 | 106833 | |
| 106625 | 106834 | memset(&bestPlan, 0, sizeof(bestPlan)); |
| 106626 | 106835 | bestPlan.rCost = SQLITE_BIG_DBL; |
| 106627 | | - WHERETRACE(("*** Begin search for loop %d ***\n", i)); |
| 106836 | + WHERETRACE(("*** Begin search for loop %d ***\n", sWBI.i)); |
| 106628 | 106837 | |
| 106629 | 106838 | /* Loop through the remaining entries in the FROM clause to find the |
| 106630 | 106839 | ** next nested loop. The loop tests all FROM clause entries |
| 106631 | 106840 | ** either once or twice. |
| 106632 | 106841 | ** |
| | @@ -106638,12 +106847,12 @@ |
| 106638 | 106847 | ** were used as the innermost nested loop. In other words, a table |
| 106639 | 106848 | ** is chosen such that the cost of running that table cannot be reduced |
| 106640 | 106849 | ** by waiting for other tables to run first. This "optimal" test works |
| 106641 | 106850 | ** by first assuming that the FROM clause is on the inner loop and finding |
| 106642 | 106851 | ** its query plan, then checking to see if that query plan uses any |
| 106643 | | - ** other FROM clause terms that are notReady. If no notReady terms are |
| 106644 | | - ** used then the "optimal" query plan works. |
| 106852 | + ** other FROM clause terms that are sWBI.notValid. If no notValid terms |
| 106853 | + ** are used then the "optimal" query plan works. |
| 106645 | 106854 | ** |
| 106646 | 106855 | ** Note that the WhereCost.nRow parameter for an optimal scan might |
| 106647 | 106856 | ** not be as small as it would be if the table really were the innermost |
| 106648 | 106857 | ** join. The nRow value can be reduced by WHERE clause constraints |
| 106649 | 106858 | ** that do not use indices. But this nRow reduction only happens if the |
| | @@ -106670,59 +106879,52 @@ |
| 106670 | 106879 | ** costlier approach. |
| 106671 | 106880 | */ |
| 106672 | 106881 | nUnconstrained = 0; |
| 106673 | 106882 | notIndexed = 0; |
| 106674 | 106883 | for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){ |
| 106675 | | - Bitmask mask; /* Mask of tables not yet ready */ |
| 106676 | | - for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){ |
| 106884 | + for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){ |
| 106677 | 106885 | int doNotReorder; /* True if this table should not be reordered */ |
| 106678 | | - WhereCost sCost; /* Cost information from best[Virtual]Index() */ |
| 106679 | | - ExprList *pOrderBy; /* ORDER BY clause for index to optimize */ |
| 106680 | | - ExprList *pDist; /* DISTINCT clause for index to optimize */ |
| 106681 | 106886 | |
| 106682 | | - doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; |
| 106887 | + doNotReorder = (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0; |
| 106683 | 106888 | if( j!=iFrom && doNotReorder ) break; |
| 106684 | | - m = getMask(pMaskSet, pTabItem->iCursor); |
| 106685 | | - if( (m & notReady)==0 ){ |
| 106889 | + m = getMask(pMaskSet, sWBI.pSrc->iCursor); |
| 106890 | + if( (m & sWBI.notValid)==0 ){ |
| 106686 | 106891 | if( j==iFrom ) iFrom++; |
| 106687 | 106892 | continue; |
| 106688 | 106893 | } |
| 106689 | | - mask = (isOptimal ? m : notReady); |
| 106690 | | - pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); |
| 106691 | | - pDist = (i==0 ? pDistinct : 0); |
| 106692 | | - if( pTabItem->pIndex==0 ) nUnconstrained++; |
| 106894 | + sWBI.notReady = (isOptimal ? m : sWBI.notValid); |
| 106895 | + if( sWBI.pSrc->pIndex==0 ) nUnconstrained++; |
| 106693 | 106896 | |
| 106694 | 106897 | WHERETRACE(("=== trying table %d with isOptimal=%d ===\n", |
| 106695 | 106898 | j, isOptimal)); |
| 106696 | | - assert( pTabItem->pTab ); |
| 106899 | + assert( sWBI.pSrc->pTab ); |
| 106697 | 106900 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 106698 | | - if( IsVirtual(pTabItem->pTab) ){ |
| 106699 | | - sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; |
| 106700 | | - bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, |
| 106701 | | - &sCost, pp); |
| 106901 | + if( IsVirtual(sWBI.pSrc->pTab) ){ |
| 106902 | + sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo; |
| 106903 | + bestVirtualIndex(&sWBI); |
| 106702 | 106904 | }else |
| 106703 | 106905 | #endif |
| 106704 | 106906 | { |
| 106705 | | - bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, |
| 106706 | | - pDist, &sCost); |
| 106907 | + bestBtreeIndex(&sWBI); |
| 106707 | 106908 | } |
| 106708 | | - assert( isOptimal || (sCost.used¬Ready)==0 ); |
| 106909 | + assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 ); |
| 106709 | 106910 | |
| 106710 | 106911 | /* If an INDEXED BY clause is present, then the plan must use that |
| 106711 | 106912 | ** index if it uses any index at all */ |
| 106712 | | - assert( pTabItem->pIndex==0 |
| 106713 | | - || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 |
| 106714 | | - || sCost.plan.u.pIdx==pTabItem->pIndex ); |
| 106913 | + assert( sWBI.pSrc->pIndex==0 |
| 106914 | + || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 |
| 106915 | + || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex ); |
| 106715 | 106916 | |
| 106716 | | - if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ |
| 106917 | + if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ |
| 106717 | 106918 | notIndexed |= m; |
| 106718 | 106919 | } |
| 106719 | 106920 | |
| 106720 | 106921 | /* Conditions under which this table becomes the best so far: |
| 106721 | 106922 | ** |
| 106722 | 106923 | ** (1) The table must not depend on other tables that have not |
| 106723 | | - ** yet run. |
| 106924 | + ** yet run. (In other words, it must not depend on tables |
| 106925 | + ** in inner loops.) |
| 106724 | 106926 | ** |
| 106725 | 106927 | ** (2) A full-table-scan plan cannot supercede indexed plan unless |
| 106726 | 106928 | ** the full-table-scan is an "optimal" plan as defined above. |
| 106727 | 106929 | ** |
| 106728 | 106930 | ** (3) All tables have an INDEXED BY clause or this table lacks an |
| | @@ -106735,37 +106937,38 @@ |
| 106735 | 106937 | ** An indexable full-table-scan from reaching rule (3). |
| 106736 | 106938 | ** |
| 106737 | 106939 | ** (4) The plan cost must be lower than prior plans or else the |
| 106738 | 106940 | ** cost must be the same and the number of rows must be lower. |
| 106739 | 106941 | */ |
| 106740 | | - if( (sCost.used¬Ready)==0 /* (1) */ |
| 106741 | | - && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ |
| 106942 | + if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */ |
| 106943 | + && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ |
| 106742 | 106944 | || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 |
| 106743 | | - || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) |
| 106744 | | - && (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */ |
| 106745 | | - || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 106746 | | - && (bestJ<0 || sCost.rCost<bestPlan.rCost /* (4) */ |
| 106747 | | - || (sCost.rCost<=bestPlan.rCost |
| 106748 | | - && sCost.plan.nRow<bestPlan.plan.nRow)) |
| 106945 | + || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) |
| 106946 | + && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */ |
| 106947 | + || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) |
| 106948 | + && (bestJ<0 || sWBI.cost.rCost<bestPlan.rCost /* (4) */ |
| 106949 | + || (sWBI.cost.rCost<=bestPlan.rCost |
| 106950 | + && sWBI.cost.plan.nRow<bestPlan.plan.nRow)) |
| 106749 | 106951 | ){ |
| 106750 | 106952 | WHERETRACE(("=== table %d is best so far" |
| 106751 | | - " with cost=%g and nRow=%g\n", |
| 106752 | | - j, sCost.rCost, sCost.plan.nRow)); |
| 106753 | | - bestPlan = sCost; |
| 106953 | + " with cost=%.1f, nRow=%.1f, nOBSat=%d\n", |
| 106954 | + j, sWBI.cost.rCost, sWBI.cost.plan.nRow, |
| 106955 | + sWBI.cost.plan.nOBSat)); |
| 106956 | + bestPlan = sWBI.cost; |
| 106754 | 106957 | bestJ = j; |
| 106755 | 106958 | } |
| 106756 | 106959 | if( doNotReorder ) break; |
| 106757 | 106960 | } |
| 106758 | 106961 | } |
| 106759 | 106962 | assert( bestJ>=0 ); |
| 106760 | | - assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); |
| 106761 | | - WHERETRACE(("*** Optimizer selects table %d for loop %d" |
| 106762 | | - " with cost=%g and nRow=%g\n", |
| 106763 | | - bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); |
| 106764 | | - /* The ALWAYS() that follows was added to hush up clang scan-build */ |
| 106765 | | - if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){ |
| 106766 | | - *ppOrderBy = 0; |
| 106963 | + assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); |
| 106964 | + WHERETRACE(("*** Optimizer selects table %d for loop %d with:\n" |
| 106965 | + " cost=%.1f, nRow=%.1f, nOBSat=%d wsFlags=0x%08x\n", |
| 106966 | + bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow, |
| 106967 | + bestPlan.plan.nOBSat, bestPlan.plan.wsFlags)); |
| 106968 | + if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ |
| 106969 | + pWInfo->nOBSat = pOrderBy->nExpr; |
| 106767 | 106970 | } |
| 106768 | 106971 | if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){ |
| 106769 | 106972 | assert( pWInfo->eDistinct==0 ); |
| 106770 | 106973 | pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 106771 | 106974 | } |
| | @@ -106782,11 +106985,11 @@ |
| 106782 | 106985 | pLevel->iIdxCur = pParse->nTab++; |
| 106783 | 106986 | } |
| 106784 | 106987 | }else{ |
| 106785 | 106988 | pLevel->iIdxCur = -1; |
| 106786 | 106989 | } |
| 106787 | | - notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); |
| 106990 | + sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); |
| 106788 | 106991 | pLevel->iFrom = (u8)bestJ; |
| 106789 | 106992 | if( bestPlan.plan.nRow>=(double)1 ){ |
| 106790 | 106993 | pParse->nQueryLoop *= bestPlan.plan.nRow; |
| 106791 | 106994 | } |
| 106792 | 106995 | |
| | @@ -106814,12 +107017,12 @@ |
| 106814 | 107017 | } |
| 106815 | 107018 | |
| 106816 | 107019 | /* If the total query only selects a single row, then the ORDER BY |
| 106817 | 107020 | ** clause is irrelevant. |
| 106818 | 107021 | */ |
| 106819 | | - if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){ |
| 106820 | | - *ppOrderBy = 0; |
| 107022 | + if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){ |
| 107023 | + pWInfo->nOBSat = pOrderBy->nExpr; |
| 106821 | 107024 | } |
| 106822 | 107025 | |
| 106823 | 107026 | /* If the caller is an UPDATE or DELETE statement that is requesting |
| 106824 | 107027 | ** to use a one-pass algorithm, determine if this is appropriate. |
| 106825 | 107028 | ** The one-pass algorithm only works if the WHERE clause constraints |
| | @@ -106835,13 +107038,14 @@ |
| 106835 | 107038 | ** searching those tables. |
| 106836 | 107039 | */ |
| 106837 | 107040 | sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ |
| 106838 | 107041 | notReady = ~(Bitmask)0; |
| 106839 | 107042 | pWInfo->nRowOut = (double)1; |
| 106840 | | - for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ |
| 107043 | + for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ |
| 106841 | 107044 | Table *pTab; /* Table to open */ |
| 106842 | 107045 | int iDb; /* Index of database containing table/index */ |
| 107046 | + struct SrcList_item *pTabItem; |
| 106843 | 107047 | |
| 106844 | 107048 | pTabItem = &pTabList->a[pLevel->iFrom]; |
| 106845 | 107049 | pTab = pTabItem->pTab; |
| 106846 | 107050 | pLevel->iTabCur = pTabItem->iCursor; |
| 106847 | 107051 | pWInfo->nRowOut *= pLevel->plan.nRow; |
| | @@ -106873,11 +107077,11 @@ |
| 106873 | 107077 | }else{ |
| 106874 | 107078 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 106875 | 107079 | } |
| 106876 | 107080 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 106877 | 107081 | if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){ |
| 106878 | | - constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel); |
| 107082 | + constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel); |
| 106879 | 107083 | }else |
| 106880 | 107084 | #endif |
| 106881 | 107085 | if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ |
| 106882 | 107086 | Index *pIx = pLevel->plan.u.pIdx; |
| 106883 | 107087 | KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); |
| | @@ -106887,24 +107091,24 @@ |
| 106887 | 107091 | sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb, |
| 106888 | 107092 | (char*)pKey, P4_KEYINFO_HANDOFF); |
| 106889 | 107093 | VdbeComment((v, "%s", pIx->zName)); |
| 106890 | 107094 | } |
| 106891 | 107095 | sqlite3CodeVerifySchema(pParse, iDb); |
| 106892 | | - notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor); |
| 107096 | + notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor); |
| 106893 | 107097 | } |
| 106894 | 107098 | pWInfo->iTop = sqlite3VdbeCurrentAddr(v); |
| 106895 | 107099 | if( db->mallocFailed ) goto whereBeginError; |
| 106896 | 107100 | |
| 106897 | 107101 | /* Generate the code to do the search. Each iteration of the for |
| 106898 | 107102 | ** loop below generates code for a single nested loop of the VM |
| 106899 | 107103 | ** program. |
| 106900 | 107104 | */ |
| 106901 | 107105 | notReady = ~(Bitmask)0; |
| 106902 | | - for(i=0; i<nTabList; i++){ |
| 106903 | | - pLevel = &pWInfo->a[i]; |
| 106904 | | - explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); |
| 106905 | | - notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); |
| 107106 | + for(ii=0; ii<nTabList; ii++){ |
| 107107 | + pLevel = &pWInfo->a[ii]; |
| 107108 | + explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags); |
| 107109 | + notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady); |
| 106906 | 107110 | pWInfo->iContinue = pLevel->addrCont; |
| 106907 | 107111 | } |
| 106908 | 107112 | |
| 106909 | 107113 | #ifdef SQLITE_TEST /* For testing and debugging use only */ |
| 106910 | 107114 | /* Record in the query plan information about the current table |
| | @@ -106911,15 +107115,17 @@ |
| 106911 | 107115 | ** and the index used to access it (if any). If the table itself |
| 106912 | 107116 | ** is not used, its name is just '{}'. If no index is used |
| 106913 | 107117 | ** the index is listed as "{}". If the primary key is used the |
| 106914 | 107118 | ** index name is '*'. |
| 106915 | 107119 | */ |
| 106916 | | - for(i=0; i<nTabList; i++){ |
| 107120 | + for(ii=0; ii<nTabList; ii++){ |
| 106917 | 107121 | char *z; |
| 106918 | 107122 | int n; |
| 106919 | 107123 | int w; |
| 106920 | | - pLevel = &pWInfo->a[i]; |
| 107124 | + struct SrcList_item *pTabItem; |
| 107125 | + |
| 107126 | + pLevel = &pWInfo->a[ii]; |
| 106921 | 107127 | w = pLevel->plan.wsFlags; |
| 106922 | 107128 | pTabItem = &pTabList->a[pLevel->iFrom]; |
| 106923 | 107129 | z = pTabItem->zAlias; |
| 106924 | 107130 | if( z==0 ) z = pTabItem->pTab->zName; |
| 106925 | 107131 | n = sqlite3Strlen30(z); |
| | @@ -112874,10 +113080,11 @@ |
| 112874 | 113080 | ){ |
| 112875 | 113081 | sqlite3_mutex_enter(db->mutex); |
| 112876 | 113082 | db->busyHandler.xFunc = xBusy; |
| 112877 | 113083 | db->busyHandler.pArg = pArg; |
| 112878 | 113084 | db->busyHandler.nBusy = 0; |
| 113085 | + db->busyTimeout = 0; |
| 112879 | 113086 | sqlite3_mutex_leave(db->mutex); |
| 112880 | 113087 | return SQLITE_OK; |
| 112881 | 113088 | } |
| 112882 | 113089 | |
| 112883 | 113090 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| | @@ -112911,12 +113118,12 @@ |
| 112911 | 113118 | ** This routine installs a default busy handler that waits for the |
| 112912 | 113119 | ** specified number of milliseconds before returning 0. |
| 112913 | 113120 | */ |
| 112914 | 113121 | SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ |
| 112915 | 113122 | if( ms>0 ){ |
| 112916 | | - db->busyTimeout = ms; |
| 112917 | 113123 | sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); |
| 113124 | + db->busyTimeout = ms; |
| 112918 | 113125 | }else{ |
| 112919 | 113126 | sqlite3_busy_handler(db, 0, 0); |
| 112920 | 113127 | } |
| 112921 | 113128 | return SQLITE_OK; |
| 112922 | 113129 | } |
| | @@ -114771,12 +114978,11 @@ |
| 114771 | 114978 | ** with various optimizations disabled to verify that the same answer |
| 114772 | 114979 | ** is obtained in every case. |
| 114773 | 114980 | */ |
| 114774 | 114981 | case SQLITE_TESTCTRL_OPTIMIZATIONS: { |
| 114775 | 114982 | sqlite3 *db = va_arg(ap, sqlite3*); |
| 114776 | | - int x = va_arg(ap,int); |
| 114777 | | - db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask); |
| 114983 | + db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); |
| 114778 | 114984 | break; |
| 114779 | 114985 | } |
| 114780 | 114986 | |
| 114781 | 114987 | #ifdef SQLITE_N_KEYWORD |
| 114782 | 114988 | /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) |
| 114783 | 114989 | |