Fossil SCM
Update the built-in SQLite to the latest 3.7.8-alpha version that contains the improved merge-sort logic.
Commit
0cf5416002ca0112088b92d7f7d1d326cae89971
Parent
0b93b0f958b0d70…
2 files changed
+1633
-1350
+1
-1
+1633
-1350
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -656,11 +656,11 @@ | ||
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | 659 | #define SQLITE_VERSION "3.7.8" |
| 660 | 660 | #define SQLITE_VERSION_NUMBER 3007008 |
| 661 | -#define SQLITE_SOURCE_ID "2011-08-29 11:56:14 639cc85a911454bffdcccb33f2976c683953ae64" | |
| 661 | +#define SQLITE_SOURCE_ID "2011-09-04 01:27:00 6b657ae75035eb10b0ad640998d3c9eadfdffa6e" | |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| @@ -7632,18 +7632,10 @@ | ||
| 7632 | 7632 | */ |
| 7633 | 7633 | #ifndef SQLITE_TEMP_STORE |
| 7634 | 7634 | # define SQLITE_TEMP_STORE 1 |
| 7635 | 7635 | #endif |
| 7636 | 7636 | |
| 7637 | -/* | |
| 7638 | -** If all temporary storage is in-memory, then omit the external merge-sort | |
| 7639 | -** logic since it is superfluous. | |
| 7640 | -*/ | |
| 7641 | -#if SQLITE_TEMP_STORE==3 && !defined(SQLITE_OMIT_MERGE_SORT) | |
| 7642 | -# define SQLITE_OMIT_MERGE_SORT | |
| 7643 | -#endif | |
| 7644 | - | |
| 7645 | 7637 | /* |
| 7646 | 7638 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 7647 | 7639 | ** ourselves. |
| 7648 | 7640 | */ |
| 7649 | 7641 | #ifndef offsetof |
| @@ -7982,11 +7974,10 @@ | ||
| 7982 | 7974 | #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ |
| 7983 | 7975 | #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ |
| 7984 | 7976 | #define BTREE_MEMORY 4 /* This is an in-memory DB */ |
| 7985 | 7977 | #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ |
| 7986 | 7978 | #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ |
| 7987 | -#define BTREE_SORTER 32 /* Used as accumulator in external merge sort */ | |
| 7988 | 7979 | |
| 7989 | 7980 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 7990 | 7981 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 7991 | 7982 | SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); |
| 7992 | 7983 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| @@ -8399,13 +8390,13 @@ | ||
| 8399 | 8390 | #define OP_ReadCookie 35 |
| 8400 | 8391 | #define OP_SetCookie 36 |
| 8401 | 8392 | #define OP_VerifyCookie 37 |
| 8402 | 8393 | #define OP_OpenRead 38 |
| 8403 | 8394 | #define OP_OpenWrite 39 |
| 8404 | -#define OP_OpenSorter 40 | |
| 8405 | -#define OP_OpenAutoindex 41 | |
| 8406 | -#define OP_OpenEphemeral 42 | |
| 8395 | +#define OP_OpenAutoindex 40 | |
| 8396 | +#define OP_OpenEphemeral 41 | |
| 8397 | +#define OP_SorterOpen 42 | |
| 8407 | 8398 | #define OP_OpenPseudo 43 |
| 8408 | 8399 | #define OP_Close 44 |
| 8409 | 8400 | #define OP_SeekLt 45 |
| 8410 | 8401 | #define OP_SeekLe 46 |
| 8411 | 8402 | #define OP_SeekGe 47 |
| @@ -8419,70 +8410,72 @@ | ||
| 8419 | 8410 | #define OP_NewRowid 55 |
| 8420 | 8411 | #define OP_Insert 56 |
| 8421 | 8412 | #define OP_InsertInt 57 |
| 8422 | 8413 | #define OP_Delete 58 |
| 8423 | 8414 | #define OP_ResetCount 59 |
| 8424 | -#define OP_RowKey 60 | |
| 8425 | -#define OP_RowData 61 | |
| 8426 | -#define OP_Rowid 62 | |
| 8427 | -#define OP_NullRow 63 | |
| 8428 | -#define OP_Last 64 | |
| 8429 | -#define OP_Sort 65 | |
| 8430 | -#define OP_Rewind 66 | |
| 8431 | -#define OP_Prev 67 | |
| 8432 | -#define OP_Next 70 | |
| 8433 | -#define OP_IdxInsert 71 | |
| 8434 | -#define OP_IdxDelete 72 | |
| 8435 | -#define OP_IdxRowid 81 | |
| 8436 | -#define OP_IdxLT 92 | |
| 8437 | -#define OP_IdxGE 95 | |
| 8438 | -#define OP_Destroy 96 | |
| 8439 | -#define OP_Clear 97 | |
| 8440 | -#define OP_CreateIndex 98 | |
| 8441 | -#define OP_CreateTable 99 | |
| 8442 | -#define OP_ParseSchema 100 | |
| 8443 | -#define OP_LoadAnalysis 101 | |
| 8444 | -#define OP_DropTable 102 | |
| 8445 | -#define OP_DropIndex 103 | |
| 8446 | -#define OP_DropTrigger 104 | |
| 8447 | -#define OP_IntegrityCk 105 | |
| 8448 | -#define OP_RowSetAdd 106 | |
| 8449 | -#define OP_RowSetRead 107 | |
| 8450 | -#define OP_RowSetTest 108 | |
| 8451 | -#define OP_Program 109 | |
| 8452 | -#define OP_Param 110 | |
| 8453 | -#define OP_FkCounter 111 | |
| 8454 | -#define OP_FkIfZero 112 | |
| 8455 | -#define OP_MemMax 113 | |
| 8456 | -#define OP_IfPos 114 | |
| 8457 | -#define OP_IfNeg 115 | |
| 8458 | -#define OP_IfZero 116 | |
| 8459 | -#define OP_AggStep 117 | |
| 8460 | -#define OP_AggFinal 118 | |
| 8461 | -#define OP_Checkpoint 119 | |
| 8462 | -#define OP_JournalMode 120 | |
| 8463 | -#define OP_Vacuum 121 | |
| 8464 | -#define OP_IncrVacuum 122 | |
| 8465 | -#define OP_Expire 123 | |
| 8466 | -#define OP_TableLock 124 | |
| 8467 | -#define OP_VBegin 125 | |
| 8468 | -#define OP_VCreate 126 | |
| 8469 | -#define OP_VDestroy 127 | |
| 8470 | -#define OP_VOpen 128 | |
| 8471 | -#define OP_VFilter 129 | |
| 8472 | -#define OP_VColumn 131 | |
| 8473 | -#define OP_VNext 132 | |
| 8474 | -#define OP_VRename 133 | |
| 8475 | -#define OP_VUpdate 134 | |
| 8476 | -#define OP_Pagecount 135 | |
| 8477 | -#define OP_MaxPgcnt 136 | |
| 8478 | -#define OP_Trace 137 | |
| 8479 | -#define OP_Noop 138 | |
| 8480 | -#define OP_Explain 139 | |
| 8481 | - | |
| 8482 | -/* The following opcode values are never used */ | |
| 8483 | -#define OP_NotUsed_140 140 | |
| 8415 | +#define OP_SorterCompare 60 | |
| 8416 | +#define OP_SorterData 61 | |
| 8417 | +#define OP_RowKey 62 | |
| 8418 | +#define OP_RowData 63 | |
| 8419 | +#define OP_Rowid 64 | |
| 8420 | +#define OP_NullRow 65 | |
| 8421 | +#define OP_Last 66 | |
| 8422 | +#define OP_SorterSort 67 | |
| 8423 | +#define OP_Sort 70 | |
| 8424 | +#define OP_Rewind 71 | |
| 8425 | +#define OP_SorterNext 72 | |
| 8426 | +#define OP_Prev 81 | |
| 8427 | +#define OP_Next 92 | |
| 8428 | +#define OP_SorterInsert 95 | |
| 8429 | +#define OP_IdxInsert 96 | |
| 8430 | +#define OP_IdxDelete 97 | |
| 8431 | +#define OP_IdxRowid 98 | |
| 8432 | +#define OP_IdxLT 99 | |
| 8433 | +#define OP_IdxGE 100 | |
| 8434 | +#define OP_Destroy 101 | |
| 8435 | +#define OP_Clear 102 | |
| 8436 | +#define OP_CreateIndex 103 | |
| 8437 | +#define OP_CreateTable 104 | |
| 8438 | +#define OP_ParseSchema 105 | |
| 8439 | +#define OP_LoadAnalysis 106 | |
| 8440 | +#define OP_DropTable 107 | |
| 8441 | +#define OP_DropIndex 108 | |
| 8442 | +#define OP_DropTrigger 109 | |
| 8443 | +#define OP_IntegrityCk 110 | |
| 8444 | +#define OP_RowSetAdd 111 | |
| 8445 | +#define OP_RowSetRead 112 | |
| 8446 | +#define OP_RowSetTest 113 | |
| 8447 | +#define OP_Program 114 | |
| 8448 | +#define OP_Param 115 | |
| 8449 | +#define OP_FkCounter 116 | |
| 8450 | +#define OP_FkIfZero 117 | |
| 8451 | +#define OP_MemMax 118 | |
| 8452 | +#define OP_IfPos 119 | |
| 8453 | +#define OP_IfNeg 120 | |
| 8454 | +#define OP_IfZero 121 | |
| 8455 | +#define OP_AggStep 122 | |
| 8456 | +#define OP_AggFinal 123 | |
| 8457 | +#define OP_Checkpoint 124 | |
| 8458 | +#define OP_JournalMode 125 | |
| 8459 | +#define OP_Vacuum 126 | |
| 8460 | +#define OP_IncrVacuum 127 | |
| 8461 | +#define OP_Expire 128 | |
| 8462 | +#define OP_TableLock 129 | |
| 8463 | +#define OP_VBegin 131 | |
| 8464 | +#define OP_VCreate 132 | |
| 8465 | +#define OP_VDestroy 133 | |
| 8466 | +#define OP_VOpen 134 | |
| 8467 | +#define OP_VFilter 135 | |
| 8468 | +#define OP_VColumn 136 | |
| 8469 | +#define OP_VNext 137 | |
| 8470 | +#define OP_VRename 138 | |
| 8471 | +#define OP_VUpdate 139 | |
| 8472 | +#define OP_Pagecount 140 | |
| 8473 | +#define OP_MaxPgcnt 146 | |
| 8474 | +#define OP_Trace 147 | |
| 8475 | +#define OP_Noop 148 | |
| 8476 | +#define OP_Explain 149 | |
| 8484 | 8477 | |
| 8485 | 8478 | |
| 8486 | 8479 | /* Properties such as "out2" or "jump" that are specified in |
| 8487 | 8480 | ** comments following the "case" for each opcode in the vdbe.c |
| 8488 | 8481 | ** are encoded into bitvectors as follows: |
| @@ -8500,22 +8493,22 @@ | ||
| 8500 | 8493 | /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ |
| 8501 | 8494 | /* 24 */ 0x00, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\ |
| 8502 | 8495 | /* 32 */ 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00,\ |
| 8503 | 8496 | /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,\ |
| 8504 | 8497 | /* 48 */ 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02,\ |
| 8505 | -/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\ | |
| 8506 | -/* 64 */ 0x01, 0x01, 0x01, 0x01, 0x4c, 0x4c, 0x01, 0x08,\ | |
| 8507 | -/* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ | |
| 8508 | -/* 80 */ 0x15, 0x02, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ | |
| 8509 | -/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ | |
| 8510 | -/* 96 */ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\ | |
| 8511 | -/* 104 */ 0x00, 0x00, 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00,\ | |
| 8512 | -/* 112 */ 0x01, 0x08, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ | |
| 8513 | -/* 120 */ 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\ | |
| 8514 | -/* 128 */ 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02,\ | |
| 8515 | -/* 136 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\ | |
| 8516 | -/* 144 */ 0x04, 0x04,} | |
| 8498 | +/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ | |
| 8499 | +/* 64 */ 0x02, 0x00, 0x01, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ | |
| 8500 | +/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ | |
| 8501 | +/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ | |
| 8502 | +/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x08,\ | |
| 8503 | +/* 96 */ 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02,\ | |
| 8504 | +/* 104 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,\ | |
| 8505 | +/* 112 */ 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05,\ | |
| 8506 | +/* 120 */ 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ | |
| 8507 | +/* 128 */ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,\ | |
| 8508 | +/* 136 */ 0x00, 0x01, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04,\ | |
| 8509 | +/* 144 */ 0x04, 0x04, 0x02, 0x00, 0x00, 0x00,} | |
| 8517 | 8510 | |
| 8518 | 8511 | /************** End of opcodes.h *********************************************/ |
| 8519 | 8512 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 8520 | 8513 | |
| 8521 | 8514 | /* |
| @@ -8749,13 +8742,10 @@ | ||
| 8749 | 8742 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); |
| 8750 | 8743 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); |
| 8751 | 8744 | SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); |
| 8752 | 8745 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); |
| 8753 | 8746 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); |
| 8754 | -#ifndef SQLITE_OMIT_MERGE_SORT | |
| 8755 | -SQLITE_PRIVATE int sqlite3PagerUnderStress(Pager*); | |
| 8756 | -#endif | |
| 8757 | 8747 | |
| 8758 | 8748 | /* Functions used to truncate the database file. */ |
| 8759 | 8749 | SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); |
| 8760 | 8750 | |
| 8761 | 8751 | #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) |
| @@ -10186,10 +10176,11 @@ | ||
| 10186 | 10176 | u8 directMode; /* Direct rendering mode means take data directly |
| 10187 | 10177 | ** from source tables rather than from accumulators */ |
| 10188 | 10178 | u8 useSortingIdx; /* In direct mode, reference the sorting index rather |
| 10189 | 10179 | ** than the source table */ |
| 10190 | 10180 | int sortingIdx; /* Cursor number of the sorting index */ |
| 10181 | + int sortingIdxPTab; /* Cursor number of pseudo-table */ | |
| 10191 | 10182 | ExprList *pGroupBy; /* The group by clause */ |
| 10192 | 10183 | int nSortingColumn; /* Number of columns in the sorting index */ |
| 10193 | 10184 | struct AggInfo_col { /* For each column used in source tables */ |
| 10194 | 10185 | Table *pTab; /* Source table */ |
| 10195 | 10186 | int iTable; /* Cursor number of the source table */ |
| @@ -10718,10 +10709,11 @@ | ||
| 10718 | 10709 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 10719 | 10710 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 10720 | 10711 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 10721 | 10712 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 10722 | 10713 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 10714 | +#define SF_UseSorter 0x0040 /* Sort using a sorter */ | |
| 10723 | 10715 | |
| 10724 | 10716 | |
| 10725 | 10717 | /* |
| 10726 | 10718 | ** The results of a select can be distributed in several ways. The |
| 10727 | 10719 | ** "SRT" prefix means "SELECT Result Type". |
| @@ -12267,10 +12259,13 @@ | ||
| 12267 | 12259 | "INT64_TYPE", |
| 12268 | 12260 | #endif |
| 12269 | 12261 | #ifdef SQLITE_LOCK_TRACE |
| 12270 | 12262 | "LOCK_TRACE", |
| 12271 | 12263 | #endif |
| 12264 | +#ifdef SQLITE_MAX_SCHEMA_RETRY | |
| 12265 | + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), | |
| 12266 | +#endif | |
| 12272 | 12267 | #ifdef SQLITE_MEMDEBUG |
| 12273 | 12268 | "MEMDEBUG", |
| 12274 | 12269 | #endif |
| 12275 | 12270 | #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 12276 | 12271 | "MIXED_ENDIAN_64BIT_FLOAT", |
| @@ -12601,16 +12596,17 @@ | ||
| 12601 | 12596 | Bool nullRow; /* True if pointing to a row with no data */ |
| 12602 | 12597 | Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 12603 | 12598 | Bool isTable; /* True if a table requiring integer keys */ |
| 12604 | 12599 | Bool isIndex; /* True if an index containing keys only - no data */ |
| 12605 | 12600 | Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ |
| 12601 | + Bool isSorter; /* True if a new-style sorter */ | |
| 12606 | 12602 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 12607 | 12603 | const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ |
| 12608 | 12604 | i64 seqCount; /* Sequence counter */ |
| 12609 | 12605 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 12610 | 12606 | i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ |
| 12611 | - VdbeSorter *pSorter; /* Sorter object for OP_OpenSorter cursors */ | |
| 12607 | + VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ | |
| 12612 | 12608 | |
| 12613 | 12609 | /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or |
| 12614 | 12610 | ** OP_IsUnique opcode on this cursor. */ |
| 12615 | 12611 | int seekResult; |
| 12616 | 12612 | |
| @@ -12944,17 +12940,19 @@ | ||
| 12944 | 12940 | # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK |
| 12945 | 12941 | # define sqlite3VdbeSorterClose(Y,Z) |
| 12946 | 12942 | # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK |
| 12947 | 12943 | # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK |
| 12948 | 12944 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 12945 | +# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK | |
| 12949 | 12946 | #else |
| 12950 | 12947 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 12951 | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, int); | |
| 12952 | 12948 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 12953 | 12949 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); |
| 12954 | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); | |
| 12955 | 12950 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); |
| 12951 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); | |
| 12952 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); | |
| 12953 | +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); | |
| 12956 | 12954 | #endif |
| 12957 | 12955 | |
| 12958 | 12956 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 12959 | 12957 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 12960 | 12958 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22114,13 +22112,13 @@ | ||
| 22114 | 22112 | /* 35 */ "ReadCookie", |
| 22115 | 22113 | /* 36 */ "SetCookie", |
| 22116 | 22114 | /* 37 */ "VerifyCookie", |
| 22117 | 22115 | /* 38 */ "OpenRead", |
| 22118 | 22116 | /* 39 */ "OpenWrite", |
| 22119 | - /* 40 */ "OpenSorter", | |
| 22120 | - /* 41 */ "OpenAutoindex", | |
| 22121 | - /* 42 */ "OpenEphemeral", | |
| 22117 | + /* 40 */ "OpenAutoindex", | |
| 22118 | + /* 41 */ "OpenEphemeral", | |
| 22119 | + /* 42 */ "SorterOpen", | |
| 22122 | 22120 | /* 43 */ "OpenPseudo", |
| 22123 | 22121 | /* 44 */ "Close", |
| 22124 | 22122 | /* 45 */ "SeekLt", |
| 22125 | 22123 | /* 46 */ "SeekLe", |
| 22126 | 22124 | /* 47 */ "SeekGe", |
| @@ -22134,32 +22132,32 @@ | ||
| 22134 | 22132 | /* 55 */ "NewRowid", |
| 22135 | 22133 | /* 56 */ "Insert", |
| 22136 | 22134 | /* 57 */ "InsertInt", |
| 22137 | 22135 | /* 58 */ "Delete", |
| 22138 | 22136 | /* 59 */ "ResetCount", |
| 22139 | - /* 60 */ "RowKey", | |
| 22140 | - /* 61 */ "RowData", | |
| 22141 | - /* 62 */ "Rowid", | |
| 22142 | - /* 63 */ "NullRow", | |
| 22143 | - /* 64 */ "Last", | |
| 22144 | - /* 65 */ "Sort", | |
| 22145 | - /* 66 */ "Rewind", | |
| 22146 | - /* 67 */ "Prev", | |
| 22137 | + /* 60 */ "SorterCompare", | |
| 22138 | + /* 61 */ "SorterData", | |
| 22139 | + /* 62 */ "RowKey", | |
| 22140 | + /* 63 */ "RowData", | |
| 22141 | + /* 64 */ "Rowid", | |
| 22142 | + /* 65 */ "NullRow", | |
| 22143 | + /* 66 */ "Last", | |
| 22144 | + /* 67 */ "SorterSort", | |
| 22147 | 22145 | /* 68 */ "Or", |
| 22148 | 22146 | /* 69 */ "And", |
| 22149 | - /* 70 */ "Next", | |
| 22150 | - /* 71 */ "IdxInsert", | |
| 22151 | - /* 72 */ "IdxDelete", | |
| 22147 | + /* 70 */ "Sort", | |
| 22148 | + /* 71 */ "Rewind", | |
| 22149 | + /* 72 */ "SorterNext", | |
| 22152 | 22150 | /* 73 */ "IsNull", |
| 22153 | 22151 | /* 74 */ "NotNull", |
| 22154 | 22152 | /* 75 */ "Ne", |
| 22155 | 22153 | /* 76 */ "Eq", |
| 22156 | 22154 | /* 77 */ "Gt", |
| 22157 | 22155 | /* 78 */ "Le", |
| 22158 | 22156 | /* 79 */ "Lt", |
| 22159 | 22157 | /* 80 */ "Ge", |
| 22160 | - /* 81 */ "IdxRowid", | |
| 22158 | + /* 81 */ "Prev", | |
| 22161 | 22159 | /* 82 */ "BitAnd", |
| 22162 | 22160 | /* 83 */ "BitOr", |
| 22163 | 22161 | /* 84 */ "ShiftLeft", |
| 22164 | 22162 | /* 85 */ "ShiftRight", |
| 22165 | 22163 | /* 86 */ "Add", |
| @@ -22166,64 +22164,68 @@ | ||
| 22166 | 22164 | /* 87 */ "Subtract", |
| 22167 | 22165 | /* 88 */ "Multiply", |
| 22168 | 22166 | /* 89 */ "Divide", |
| 22169 | 22167 | /* 90 */ "Remainder", |
| 22170 | 22168 | /* 91 */ "Concat", |
| 22171 | - /* 92 */ "IdxLT", | |
| 22169 | + /* 92 */ "Next", | |
| 22172 | 22170 | /* 93 */ "BitNot", |
| 22173 | 22171 | /* 94 */ "String8", |
| 22174 | - /* 95 */ "IdxGE", | |
| 22175 | - /* 96 */ "Destroy", | |
| 22176 | - /* 97 */ "Clear", | |
| 22177 | - /* 98 */ "CreateIndex", | |
| 22178 | - /* 99 */ "CreateTable", | |
| 22179 | - /* 100 */ "ParseSchema", | |
| 22180 | - /* 101 */ "LoadAnalysis", | |
| 22181 | - /* 102 */ "DropTable", | |
| 22182 | - /* 103 */ "DropIndex", | |
| 22183 | - /* 104 */ "DropTrigger", | |
| 22184 | - /* 105 */ "IntegrityCk", | |
| 22185 | - /* 106 */ "RowSetAdd", | |
| 22186 | - /* 107 */ "RowSetRead", | |
| 22187 | - /* 108 */ "RowSetTest", | |
| 22188 | - /* 109 */ "Program", | |
| 22189 | - /* 110 */ "Param", | |
| 22190 | - /* 111 */ "FkCounter", | |
| 22191 | - /* 112 */ "FkIfZero", | |
| 22192 | - /* 113 */ "MemMax", | |
| 22193 | - /* 114 */ "IfPos", | |
| 22194 | - /* 115 */ "IfNeg", | |
| 22195 | - /* 116 */ "IfZero", | |
| 22196 | - /* 117 */ "AggStep", | |
| 22197 | - /* 118 */ "AggFinal", | |
| 22198 | - /* 119 */ "Checkpoint", | |
| 22199 | - /* 120 */ "JournalMode", | |
| 22200 | - /* 121 */ "Vacuum", | |
| 22201 | - /* 122 */ "IncrVacuum", | |
| 22202 | - /* 123 */ "Expire", | |
| 22203 | - /* 124 */ "TableLock", | |
| 22204 | - /* 125 */ "VBegin", | |
| 22205 | - /* 126 */ "VCreate", | |
| 22206 | - /* 127 */ "VDestroy", | |
| 22207 | - /* 128 */ "VOpen", | |
| 22208 | - /* 129 */ "VFilter", | |
| 22172 | + /* 95 */ "SorterInsert", | |
| 22173 | + /* 96 */ "IdxInsert", | |
| 22174 | + /* 97 */ "IdxDelete", | |
| 22175 | + /* 98 */ "IdxRowid", | |
| 22176 | + /* 99 */ "IdxLT", | |
| 22177 | + /* 100 */ "IdxGE", | |
| 22178 | + /* 101 */ "Destroy", | |
| 22179 | + /* 102 */ "Clear", | |
| 22180 | + /* 103 */ "CreateIndex", | |
| 22181 | + /* 104 */ "CreateTable", | |
| 22182 | + /* 105 */ "ParseSchema", | |
| 22183 | + /* 106 */ "LoadAnalysis", | |
| 22184 | + /* 107 */ "DropTable", | |
| 22185 | + /* 108 */ "DropIndex", | |
| 22186 | + /* 109 */ "DropTrigger", | |
| 22187 | + /* 110 */ "IntegrityCk", | |
| 22188 | + /* 111 */ "RowSetAdd", | |
| 22189 | + /* 112 */ "RowSetRead", | |
| 22190 | + /* 113 */ "RowSetTest", | |
| 22191 | + /* 114 */ "Program", | |
| 22192 | + /* 115 */ "Param", | |
| 22193 | + /* 116 */ "FkCounter", | |
| 22194 | + /* 117 */ "FkIfZero", | |
| 22195 | + /* 118 */ "MemMax", | |
| 22196 | + /* 119 */ "IfPos", | |
| 22197 | + /* 120 */ "IfNeg", | |
| 22198 | + /* 121 */ "IfZero", | |
| 22199 | + /* 122 */ "AggStep", | |
| 22200 | + /* 123 */ "AggFinal", | |
| 22201 | + /* 124 */ "Checkpoint", | |
| 22202 | + /* 125 */ "JournalMode", | |
| 22203 | + /* 126 */ "Vacuum", | |
| 22204 | + /* 127 */ "IncrVacuum", | |
| 22205 | + /* 128 */ "Expire", | |
| 22206 | + /* 129 */ "TableLock", | |
| 22209 | 22207 | /* 130 */ "Real", |
| 22210 | - /* 131 */ "VColumn", | |
| 22211 | - /* 132 */ "VNext", | |
| 22212 | - /* 133 */ "VRename", | |
| 22213 | - /* 134 */ "VUpdate", | |
| 22214 | - /* 135 */ "Pagecount", | |
| 22215 | - /* 136 */ "MaxPgcnt", | |
| 22216 | - /* 137 */ "Trace", | |
| 22217 | - /* 138 */ "Noop", | |
| 22218 | - /* 139 */ "Explain", | |
| 22219 | - /* 140 */ "NotUsed_140", | |
| 22208 | + /* 131 */ "VBegin", | |
| 22209 | + /* 132 */ "VCreate", | |
| 22210 | + /* 133 */ "VDestroy", | |
| 22211 | + /* 134 */ "VOpen", | |
| 22212 | + /* 135 */ "VFilter", | |
| 22213 | + /* 136 */ "VColumn", | |
| 22214 | + /* 137 */ "VNext", | |
| 22215 | + /* 138 */ "VRename", | |
| 22216 | + /* 139 */ "VUpdate", | |
| 22217 | + /* 140 */ "Pagecount", | |
| 22220 | 22218 | /* 141 */ "ToText", |
| 22221 | 22219 | /* 142 */ "ToBlob", |
| 22222 | 22220 | /* 143 */ "ToNumeric", |
| 22223 | 22221 | /* 144 */ "ToInt", |
| 22224 | 22222 | /* 145 */ "ToReal", |
| 22223 | + /* 146 */ "MaxPgcnt", | |
| 22224 | + /* 147 */ "Trace", | |
| 22225 | + /* 148 */ "Noop", | |
| 22226 | + /* 149 */ "Explain", | |
| 22225 | 22227 | }; |
| 22226 | 22228 | return azName[i]; |
| 22227 | 22229 | } |
| 22228 | 22230 | #endif |
| 22229 | 22231 | |
| @@ -22314,11 +22316,11 @@ | ||
| 22314 | 22316 | */ |
| 22315 | 22317 | #ifdef MEMORY_DEBUG |
| 22316 | 22318 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 22317 | 22319 | #endif |
| 22318 | 22320 | |
| 22319 | -#ifdef SQLITE_DEBUG | |
| 22321 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | |
| 22320 | 22322 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 22321 | 22323 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 22322 | 22324 | # endif |
| 22323 | 22325 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 22324 | 22326 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -24656,11 +24658,11 @@ | ||
| 24656 | 24658 | */ |
| 24657 | 24659 | #ifdef MEMORY_DEBUG |
| 24658 | 24660 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 24659 | 24661 | #endif |
| 24660 | 24662 | |
| 24661 | -#ifdef SQLITE_DEBUG | |
| 24663 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | |
| 24662 | 24664 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 24663 | 24665 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 24664 | 24666 | # endif |
| 24665 | 24667 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 24666 | 24668 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -27716,15 +27718,15 @@ | ||
| 27716 | 27718 | SQLITE_API int sqlite3_fullsync_count = 0; |
| 27717 | 27719 | #endif |
| 27718 | 27720 | |
| 27719 | 27721 | /* |
| 27720 | 27722 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 27721 | -** Others do no. To be safe, we will stick with the (slower) fsync(). | |
| 27722 | -** If you know that your system does support fdatasync() correctly, | |
| 27723 | +** Others do no. To be safe, we will stick with the (slightly slower) | |
| 27724 | +** fsync(). If you know that your system does support fdatasync() correctly, | |
| 27723 | 27725 | ** then simply compile with -Dfdatasync=fdatasync |
| 27724 | 27726 | */ |
| 27725 | -#if !defined(fdatasync) && !defined(__linux__) | |
| 27727 | +#if !defined(fdatasync) | |
| 27726 | 27728 | # define fdatasync fsync |
| 27727 | 27729 | #endif |
| 27728 | 27730 | |
| 27729 | 27731 | /* |
| 27730 | 27732 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28015,11 +28017,11 @@ | ||
| 28015 | 28017 | ** file-control operation. Enlarge the database to nBytes in size |
| 28016 | 28018 | ** (rounded up to the next chunk-size). If the database is already |
| 28017 | 28019 | ** nBytes or larger, this routine is a no-op. |
| 28018 | 28020 | */ |
| 28019 | 28021 | static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
| 28020 | - if( pFile->szChunk ){ | |
| 28022 | + if( pFile->szChunk>0 ){ | |
| 28021 | 28023 | i64 nSize; /* Required file size */ |
| 28022 | 28024 | struct stat buf; /* Used to hold return values of fstat() */ |
| 28023 | 28025 | |
| 28024 | 28026 | if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 28025 | 28027 | |
| @@ -28210,15 +28212,13 @@ | ||
| 28210 | 28212 | */ |
| 28211 | 28213 | struct unixShm { |
| 28212 | 28214 | unixShmNode *pShmNode; /* The underlying unixShmNode object */ |
| 28213 | 28215 | unixShm *pNext; /* Next unixShm with the same unixShmNode */ |
| 28214 | 28216 | u8 hasMutex; /* True if holding the unixShmNode mutex */ |
| 28217 | + u8 id; /* Id of this connection within its unixShmNode */ | |
| 28215 | 28218 | u16 sharedMask; /* Mask of shared locks held */ |
| 28216 | 28219 | u16 exclMask; /* Mask of exclusive locks held */ |
| 28217 | -#ifdef SQLITE_DEBUG | |
| 28218 | - u8 id; /* Id of this connection within its unixShmNode */ | |
| 28219 | -#endif | |
| 28220 | 28220 | }; |
| 28221 | 28221 | |
| 28222 | 28222 | /* |
| 28223 | 28223 | ** Constants used for locking |
| 28224 | 28224 | */ |
| @@ -31435,11 +31435,11 @@ | ||
| 31435 | 31435 | */ |
| 31436 | 31436 | #ifdef MEMORY_DEBUG |
| 31437 | 31437 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 31438 | 31438 | #endif |
| 31439 | 31439 | |
| 31440 | -#ifdef SQLITE_DEBUG | |
| 31440 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) | |
| 31441 | 31441 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 31442 | 31442 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 31443 | 31443 | # endif |
| 31444 | 31444 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 31445 | 31445 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -32768,11 +32768,11 @@ | ||
| 32768 | 32768 | /* If the user has configured a chunk-size for this file, truncate the |
| 32769 | 32769 | ** file so that it consists of an integer number of chunks (i.e. the |
| 32770 | 32770 | ** actual file size after the operation may be larger than the requested |
| 32771 | 32771 | ** size). |
| 32772 | 32772 | */ |
| 32773 | - if( pFile->szChunk ){ | |
| 32773 | + if( pFile->szChunk>0 ){ | |
| 32774 | 32774 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 32775 | 32775 | } |
| 32776 | 32776 | |
| 32777 | 32777 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 32778 | 32778 | if( seekWinFile(pFile, nByte) ){ |
| @@ -33155,22 +33155,24 @@ | ||
| 33155 | 33155 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33156 | 33156 | pFile->szChunk = *(int *)pArg; |
| 33157 | 33157 | return SQLITE_OK; |
| 33158 | 33158 | } |
| 33159 | 33159 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33160 | - winFile *pFile = (winFile*)id; | |
| 33161 | - sqlite3_int64 oldSz; | |
| 33162 | - int rc = winFileSize(id, &oldSz); | |
| 33163 | - if( rc==SQLITE_OK ){ | |
| 33164 | - sqlite3_int64 newSz = *(sqlite3_int64*)pArg; | |
| 33165 | - if( newSz>oldSz ){ | |
| 33166 | - SimulateIOErrorBenign(1); | |
| 33167 | - rc = winTruncate(id, newSz); | |
| 33168 | - SimulateIOErrorBenign(0); | |
| 33169 | - } | |
| 33170 | - } | |
| 33171 | - return rc; | |
| 33160 | + if( pFile->szChunk>0 ){ | |
| 33161 | + sqlite3_int64 oldSz; | |
| 33162 | + int rc = winFileSize(id, &oldSz); | |
| 33163 | + if( rc==SQLITE_OK ){ | |
| 33164 | + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; | |
| 33165 | + if( newSz>oldSz ){ | |
| 33166 | + SimulateIOErrorBenign(1); | |
| 33167 | + rc = winTruncate(id, newSz); | |
| 33168 | + SimulateIOErrorBenign(0); | |
| 33169 | + } | |
| 33170 | + } | |
| 33171 | + return rc; | |
| 33172 | + } | |
| 33173 | + return SQLITE_OK; | |
| 33172 | 33174 | } |
| 33173 | 33175 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33174 | 33176 | int bPersist = *(int*)pArg; |
| 33175 | 33177 | if( bPersist<0 ){ |
| 33176 | 33178 | *(int*)pArg = pFile->bPersistWal; |
| @@ -38137,11 +38139,10 @@ | ||
| 38137 | 38139 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 38138 | 38140 | u8 tempFile; /* zFilename is a temporary file */ |
| 38139 | 38141 | u8 readOnly; /* True for a read-only database */ |
| 38140 | 38142 | u8 memDb; /* True to inhibit all file I/O */ |
| 38141 | 38143 | u8 hasSeenStress; /* pagerStress() called one or more times */ |
| 38142 | - u8 isSorter; /* True for a PAGER_SORTER */ | |
| 38143 | 38144 | |
| 38144 | 38145 | /************************************************************************** |
| 38145 | 38146 | ** The following block contains those class members that change during |
| 38146 | 38147 | ** routine opertion. Class members not in this block are either fixed |
| 38147 | 38148 | ** when the pager is first created or else only change when there is a |
| @@ -38361,19 +38362,10 @@ | ||
| 38361 | 38362 | ); |
| 38362 | 38363 | assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); |
| 38363 | 38364 | assert( pagerUseWal(p)==0 ); |
| 38364 | 38365 | } |
| 38365 | 38366 | |
| 38366 | - /* A sorter is a temp file that never spills to disk and always has | |
| 38367 | - ** the doNotSpill flag set | |
| 38368 | - */ | |
| 38369 | - if( p->isSorter ){ | |
| 38370 | - assert( p->tempFile ); | |
| 38371 | - assert( p->doNotSpill ); | |
| 38372 | - assert( p->fd->pMethods==0 ); | |
| 38373 | - } | |
| 38374 | - | |
| 38375 | 38367 | /* If changeCountDone is set, a RESERVED lock or greater must be held |
| 38376 | 38368 | ** on the file. |
| 38377 | 38369 | */ |
| 38378 | 38370 | assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); |
| 38379 | 38371 | assert( p->eLock!=PENDING_LOCK ); |
| @@ -42073,16 +42065,10 @@ | ||
| 42073 | 42065 | } |
| 42074 | 42066 | /* pPager->xBusyHandler = 0; */ |
| 42075 | 42067 | /* pPager->pBusyHandlerArg = 0; */ |
| 42076 | 42068 | pPager->xReiniter = xReinit; |
| 42077 | 42069 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ |
| 42078 | -#ifndef SQLITE_OMIT_MERGE_SORT | |
| 42079 | - if( flags & PAGER_SORTER ){ | |
| 42080 | - pPager->doNotSpill = 1; | |
| 42081 | - pPager->isSorter = 1; | |
| 42082 | - } | |
| 42083 | -#endif | |
| 42084 | 42070 | |
| 42085 | 42071 | *ppPager = pPager; |
| 42086 | 42072 | return SQLITE_OK; |
| 42087 | 42073 | } |
| 42088 | 42074 | |
| @@ -43623,21 +43609,10 @@ | ||
| 43623 | 43609 | */ |
| 43624 | 43610 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ |
| 43625 | 43611 | return MEMDB; |
| 43626 | 43612 | } |
| 43627 | 43613 | |
| 43628 | -#ifndef SQLITE_OMIT_MERGE_SORT | |
| 43629 | -/* | |
| 43630 | -** Return true if the pager has seen a pagerStress callback. | |
| 43631 | -*/ | |
| 43632 | -SQLITE_PRIVATE int sqlite3PagerUnderStress(Pager *pPager){ | |
| 43633 | - assert( pPager->isSorter ); | |
| 43634 | - assert( pPager->doNotSpill ); | |
| 43635 | - return pPager->hasSeenStress; | |
| 43636 | -} | |
| 43637 | -#endif | |
| 43638 | - | |
| 43639 | 43614 | /* |
| 43640 | 43615 | ** Check that there are at least nSavepoint savepoints open. If there are |
| 43641 | 43616 | ** currently less than nSavepoints open, then open one or more savepoints |
| 43642 | 43617 | ** to make up the difference. If the number of savepoints is already |
| 43643 | 43618 | ** equal to nSavepoint, then this function is a no-op. |
| @@ -50002,26 +49977,15 @@ | ||
| 50002 | 49977 | assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); |
| 50003 | 49978 | |
| 50004 | 49979 | /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ |
| 50005 | 49980 | assert( (flags & BTREE_SINGLE)==0 || isTempDb ); |
| 50006 | 49981 | |
| 50007 | - /* The BTREE_SORTER flag is only used if SQLITE_OMIT_MERGE_SORT is undef */ | |
| 50008 | -#ifdef SQLITE_OMIT_MERGE_SORT | |
| 50009 | - assert( (flags & BTREE_SORTER)==0 ); | |
| 50010 | -#endif | |
| 50011 | - | |
| 50012 | - /* BTREE_SORTER is always on a BTREE_SINGLE, BTREE_OMIT_JOURNAL */ | |
| 50013 | - assert( (flags & BTREE_SORTER)==0 || | |
| 50014 | - (flags & (BTREE_SINGLE|BTREE_OMIT_JOURNAL)) | |
| 50015 | - ==(BTREE_SINGLE|BTREE_OMIT_JOURNAL) ); | |
| 50016 | - | |
| 50017 | 49982 | if( db->flags & SQLITE_NoReadlock ){ |
| 50018 | 49983 | flags |= BTREE_NO_READLOCK; |
| 50019 | 49984 | } |
| 50020 | 49985 | if( isMemdb ){ |
| 50021 | 49986 | flags |= BTREE_MEMORY; |
| 50022 | - flags &= ~BTREE_SORTER; | |
| 50023 | 49987 | } |
| 50024 | 49988 | if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ |
| 50025 | 49989 | vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; |
| 50026 | 49990 | } |
| 50027 | 49991 | p = sqlite3MallocZero(sizeof(Btree)); |
| @@ -51022,15 +50986,16 @@ | ||
| 51022 | 50986 | for(i=0; i<nCell; i++){ |
| 51023 | 50987 | u8 *pCell = findCell(pPage, i); |
| 51024 | 50988 | if( eType==PTRMAP_OVERFLOW1 ){ |
| 51025 | 50989 | CellInfo info; |
| 51026 | 50990 | btreeParseCellPtr(pPage, pCell, &info); |
| 51027 | - if( info.iOverflow ){ | |
| 51028 | - if( iFrom==get4byte(&pCell[info.iOverflow]) ){ | |
| 51029 | - put4byte(&pCell[info.iOverflow], iTo); | |
| 51030 | - break; | |
| 51031 | - } | |
| 50991 | + if( info.iOverflow | |
| 50992 | + && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage | |
| 50993 | + && iFrom==get4byte(&pCell[info.iOverflow]) | |
| 50994 | + ){ | |
| 50995 | + put4byte(&pCell[info.iOverflow], iTo); | |
| 50996 | + break; | |
| 51032 | 50997 | } |
| 51033 | 50998 | }else{ |
| 51034 | 50999 | if( get4byte(pCell)==iFrom ){ |
| 51035 | 51000 | put4byte(pCell, iTo); |
| 51036 | 51001 | break; |
| @@ -53458,10 +53423,13 @@ | ||
| 53458 | 53423 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 53459 | 53424 | btreeParseCellPtr(pPage, pCell, &info); |
| 53460 | 53425 | if( info.iOverflow==0 ){ |
| 53461 | 53426 | return SQLITE_OK; /* No overflow pages. Return without doing anything */ |
| 53462 | 53427 | } |
| 53428 | + if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ | |
| 53429 | + return SQLITE_CORRUPT; /* Cell extends past end of page */ | |
| 53430 | + } | |
| 53463 | 53431 | ovflPgno = get4byte(&pCell[info.iOverflow]); |
| 53464 | 53432 | assert( pBt->usableSize > 4 ); |
| 53465 | 53433 | ovflPageSize = pBt->usableSize - 4; |
| 53466 | 53434 | nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; |
| 53467 | 53435 | assert( ovflPgno==0 || nOvfl>0 ); |
| @@ -55560,20 +55528,13 @@ | ||
| 55560 | 55528 | releasePage(pPage); |
| 55561 | 55529 | } |
| 55562 | 55530 | return rc; |
| 55563 | 55531 | } |
| 55564 | 55532 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ |
| 55565 | - BtShared *pBt = p->pBt; | |
| 55566 | 55533 | int rc; |
| 55567 | 55534 | sqlite3BtreeEnter(p); |
| 55568 | - if( (pBt->openFlags&BTREE_SINGLE) ){ | |
| 55569 | - pBt->nPage = 0; | |
| 55570 | - sqlite3PagerTruncateImage(pBt->pPager, 1); | |
| 55571 | - rc = newDatabase(pBt); | |
| 55572 | - }else{ | |
| 55573 | - rc = btreeDropTable(p, iTable, piMoved); | |
| 55574 | - } | |
| 55535 | + rc = btreeDropTable(p, iTable, piMoved); | |
| 55575 | 55536 | sqlite3BtreeLeave(p); |
| 55576 | 55537 | return rc; |
| 55577 | 55538 | } |
| 55578 | 55539 | |
| 55579 | 55540 | |
| @@ -58758,11 +58719,11 @@ | ||
| 58758 | 58719 | assert( p->nOp - i >= 3 ); |
| 58759 | 58720 | assert( pOp[-1].opcode==OP_Integer ); |
| 58760 | 58721 | n = pOp[-1].p1; |
| 58761 | 58722 | if( n>nMaxArgs ) nMaxArgs = n; |
| 58762 | 58723 | #endif |
| 58763 | - }else if( opcode==OP_Next ){ | |
| 58724 | + }else if( opcode==OP_Next || opcode==OP_SorterNext ){ | |
| 58764 | 58725 | pOp->p4.xAdvance = sqlite3BtreeNext; |
| 58765 | 58726 | pOp->p4type = P4_ADVANCE; |
| 58766 | 58727 | }else if( opcode==OP_Prev ){ |
| 58767 | 58728 | pOp->p4.xAdvance = sqlite3BtreePrevious; |
| 58768 | 58729 | pOp->p4type = P4_ADVANCE; |
| @@ -63871,55 +63832,58 @@ | ||
| 63871 | 63832 | Db *pDb; |
| 63872 | 63833 | } aw; |
| 63873 | 63834 | struct OP_OpenEphemeral_stack_vars { |
| 63874 | 63835 | VdbeCursor *pCx; |
| 63875 | 63836 | } ax; |
| 63876 | - struct OP_OpenPseudo_stack_vars { | |
| 63837 | + struct OP_SorterOpen_stack_vars { | |
| 63877 | 63838 | VdbeCursor *pCx; |
| 63878 | 63839 | } ay; |
| 63840 | + struct OP_OpenPseudo_stack_vars { | |
| 63841 | + VdbeCursor *pCx; | |
| 63842 | + } az; | |
| 63879 | 63843 | struct OP_SeekGt_stack_vars { |
| 63880 | 63844 | int res; |
| 63881 | 63845 | int oc; |
| 63882 | 63846 | VdbeCursor *pC; |
| 63883 | 63847 | UnpackedRecord r; |
| 63884 | 63848 | int nField; |
| 63885 | 63849 | i64 iKey; /* The rowid we are to seek to */ |
| 63886 | - } az; | |
| 63850 | + } ba; | |
| 63887 | 63851 | struct OP_Seek_stack_vars { |
| 63888 | 63852 | VdbeCursor *pC; |
| 63889 | - } ba; | |
| 63853 | + } bb; | |
| 63890 | 63854 | struct OP_Found_stack_vars { |
| 63891 | 63855 | int alreadyExists; |
| 63892 | 63856 | VdbeCursor *pC; |
| 63893 | 63857 | int res; |
| 63894 | 63858 | UnpackedRecord *pIdxKey; |
| 63895 | 63859 | UnpackedRecord r; |
| 63896 | 63860 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 63897 | - } bb; | |
| 63861 | + } bc; | |
| 63898 | 63862 | struct OP_IsUnique_stack_vars { |
| 63899 | 63863 | u16 ii; |
| 63900 | 63864 | VdbeCursor *pCx; |
| 63901 | 63865 | BtCursor *pCrsr; |
| 63902 | 63866 | u16 nField; |
| 63903 | 63867 | Mem *aMx; |
| 63904 | 63868 | UnpackedRecord r; /* B-Tree index search key */ |
| 63905 | 63869 | i64 R; /* Rowid stored in register P3 */ |
| 63906 | - } bc; | |
| 63870 | + } bd; | |
| 63907 | 63871 | struct OP_NotExists_stack_vars { |
| 63908 | 63872 | VdbeCursor *pC; |
| 63909 | 63873 | BtCursor *pCrsr; |
| 63910 | 63874 | int res; |
| 63911 | 63875 | u64 iKey; |
| 63912 | - } bd; | |
| 63876 | + } be; | |
| 63913 | 63877 | struct OP_NewRowid_stack_vars { |
| 63914 | 63878 | i64 v; /* The new rowid */ |
| 63915 | 63879 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 63916 | 63880 | int res; /* Result of an sqlite3BtreeLast() */ |
| 63917 | 63881 | int cnt; /* Counter to limit the number of searches */ |
| 63918 | 63882 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 63919 | 63883 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 63920 | - } be; | |
| 63884 | + } bf; | |
| 63921 | 63885 | struct OP_InsertInt_stack_vars { |
| 63922 | 63886 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 63923 | 63887 | Mem *pKey; /* MEM cell holding key for the record */ |
| 63924 | 63888 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 63925 | 63889 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| @@ -63926,154 +63890,161 @@ | ||
| 63926 | 63890 | int nZero; /* Number of zero-bytes to append */ |
| 63927 | 63891 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 63928 | 63892 | const char *zDb; /* database name - used by the update hook */ |
| 63929 | 63893 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 63930 | 63894 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 63931 | - } bf; | |
| 63895 | + } bg; | |
| 63932 | 63896 | struct OP_Delete_stack_vars { |
| 63933 | 63897 | i64 iKey; |
| 63934 | 63898 | VdbeCursor *pC; |
| 63935 | - } bg; | |
| 63899 | + } bh; | |
| 63900 | + struct OP_SorterCompare_stack_vars { | |
| 63901 | + VdbeCursor *pC; | |
| 63902 | + int res; | |
| 63903 | + } bi; | |
| 63904 | + struct OP_SorterData_stack_vars { | |
| 63905 | + VdbeCursor *pC; | |
| 63906 | + } bj; | |
| 63936 | 63907 | struct OP_RowData_stack_vars { |
| 63937 | 63908 | VdbeCursor *pC; |
| 63938 | 63909 | BtCursor *pCrsr; |
| 63939 | 63910 | u32 n; |
| 63940 | 63911 | i64 n64; |
| 63941 | - } bh; | |
| 63912 | + } bk; | |
| 63942 | 63913 | struct OP_Rowid_stack_vars { |
| 63943 | 63914 | VdbeCursor *pC; |
| 63944 | 63915 | i64 v; |
| 63945 | 63916 | sqlite3_vtab *pVtab; |
| 63946 | 63917 | const sqlite3_module *pModule; |
| 63947 | - } bi; | |
| 63918 | + } bl; | |
| 63948 | 63919 | struct OP_NullRow_stack_vars { |
| 63949 | 63920 | VdbeCursor *pC; |
| 63950 | - } bj; | |
| 63921 | + } bm; | |
| 63951 | 63922 | struct OP_Last_stack_vars { |
| 63952 | 63923 | VdbeCursor *pC; |
| 63953 | 63924 | BtCursor *pCrsr; |
| 63954 | 63925 | int res; |
| 63955 | - } bk; | |
| 63926 | + } bn; | |
| 63956 | 63927 | struct OP_Rewind_stack_vars { |
| 63957 | 63928 | VdbeCursor *pC; |
| 63958 | 63929 | BtCursor *pCrsr; |
| 63959 | 63930 | int res; |
| 63960 | - } bl; | |
| 63931 | + } bo; | |
| 63961 | 63932 | struct OP_Next_stack_vars { |
| 63962 | 63933 | VdbeCursor *pC; |
| 63963 | 63934 | int res; |
| 63964 | - } bm; | |
| 63935 | + } bp; | |
| 63965 | 63936 | struct OP_IdxInsert_stack_vars { |
| 63966 | 63937 | VdbeCursor *pC; |
| 63967 | 63938 | BtCursor *pCrsr; |
| 63968 | 63939 | int nKey; |
| 63969 | 63940 | const char *zKey; |
| 63970 | - } bn; | |
| 63941 | + } bq; | |
| 63971 | 63942 | struct OP_IdxDelete_stack_vars { |
| 63972 | 63943 | VdbeCursor *pC; |
| 63973 | 63944 | BtCursor *pCrsr; |
| 63974 | 63945 | int res; |
| 63975 | 63946 | UnpackedRecord r; |
| 63976 | - } bo; | |
| 63947 | + } br; | |
| 63977 | 63948 | struct OP_IdxRowid_stack_vars { |
| 63978 | 63949 | BtCursor *pCrsr; |
| 63979 | 63950 | VdbeCursor *pC; |
| 63980 | 63951 | i64 rowid; |
| 63981 | - } bp; | |
| 63952 | + } bs; | |
| 63982 | 63953 | struct OP_IdxGE_stack_vars { |
| 63983 | 63954 | VdbeCursor *pC; |
| 63984 | 63955 | int res; |
| 63985 | 63956 | UnpackedRecord r; |
| 63986 | - } bq; | |
| 63957 | + } bt; | |
| 63987 | 63958 | struct OP_Destroy_stack_vars { |
| 63988 | 63959 | int iMoved; |
| 63989 | 63960 | int iCnt; |
| 63990 | 63961 | Vdbe *pVdbe; |
| 63991 | 63962 | int iDb; |
| 63992 | - } br; | |
| 63963 | + } bu; | |
| 63993 | 63964 | struct OP_Clear_stack_vars { |
| 63994 | 63965 | int nChange; |
| 63995 | - } bs; | |
| 63966 | + } bv; | |
| 63996 | 63967 | struct OP_CreateTable_stack_vars { |
| 63997 | 63968 | int pgno; |
| 63998 | 63969 | int flags; |
| 63999 | 63970 | Db *pDb; |
| 64000 | - } bt; | |
| 63971 | + } bw; | |
| 64001 | 63972 | struct OP_ParseSchema_stack_vars { |
| 64002 | 63973 | int iDb; |
| 64003 | 63974 | const char *zMaster; |
| 64004 | 63975 | char *zSql; |
| 64005 | 63976 | InitData initData; |
| 64006 | - } bu; | |
| 63977 | + } bx; | |
| 64007 | 63978 | struct OP_IntegrityCk_stack_vars { |
| 64008 | 63979 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 64009 | 63980 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 64010 | 63981 | int j; /* Loop counter */ |
| 64011 | 63982 | int nErr; /* Number of errors reported */ |
| 64012 | 63983 | char *z; /* Text of the error report */ |
| 64013 | 63984 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 64014 | - } bv; | |
| 63985 | + } by; | |
| 64015 | 63986 | struct OP_RowSetRead_stack_vars { |
| 64016 | 63987 | i64 val; |
| 64017 | - } bw; | |
| 63988 | + } bz; | |
| 64018 | 63989 | struct OP_RowSetTest_stack_vars { |
| 64019 | 63990 | int iSet; |
| 64020 | 63991 | int exists; |
| 64021 | - } bx; | |
| 63992 | + } ca; | |
| 64022 | 63993 | struct OP_Program_stack_vars { |
| 64023 | 63994 | int nMem; /* Number of memory registers for sub-program */ |
| 64024 | 63995 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 64025 | 63996 | Mem *pRt; /* Register to allocate runtime space */ |
| 64026 | 63997 | Mem *pMem; /* Used to iterate through memory cells */ |
| 64027 | 63998 | Mem *pEnd; /* Last memory cell in new array */ |
| 64028 | 63999 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 64029 | 64000 | SubProgram *pProgram; /* Sub-program to execute */ |
| 64030 | 64001 | void *t; /* Token identifying trigger */ |
| 64031 | - } by; | |
| 64002 | + } cb; | |
| 64032 | 64003 | struct OP_Param_stack_vars { |
| 64033 | 64004 | VdbeFrame *pFrame; |
| 64034 | 64005 | Mem *pIn; |
| 64035 | - } bz; | |
| 64006 | + } cc; | |
| 64036 | 64007 | struct OP_MemMax_stack_vars { |
| 64037 | 64008 | Mem *pIn1; |
| 64038 | 64009 | VdbeFrame *pFrame; |
| 64039 | - } ca; | |
| 64010 | + } cd; | |
| 64040 | 64011 | struct OP_AggStep_stack_vars { |
| 64041 | 64012 | int n; |
| 64042 | 64013 | int i; |
| 64043 | 64014 | Mem *pMem; |
| 64044 | 64015 | Mem *pRec; |
| 64045 | 64016 | sqlite3_context ctx; |
| 64046 | 64017 | sqlite3_value **apVal; |
| 64047 | - } cb; | |
| 64018 | + } ce; | |
| 64048 | 64019 | struct OP_AggFinal_stack_vars { |
| 64049 | 64020 | Mem *pMem; |
| 64050 | - } cc; | |
| 64021 | + } cf; | |
| 64051 | 64022 | struct OP_Checkpoint_stack_vars { |
| 64052 | 64023 | int i; /* Loop counter */ |
| 64053 | 64024 | int aRes[3]; /* Results */ |
| 64054 | 64025 | Mem *pMem; /* Write results here */ |
| 64055 | - } cd; | |
| 64026 | + } cg; | |
| 64056 | 64027 | struct OP_JournalMode_stack_vars { |
| 64057 | 64028 | Btree *pBt; /* Btree to change journal mode of */ |
| 64058 | 64029 | Pager *pPager; /* Pager associated with pBt */ |
| 64059 | 64030 | int eNew; /* New journal mode */ |
| 64060 | 64031 | int eOld; /* The old journal mode */ |
| 64061 | 64032 | const char *zFilename; /* Name of database file for pPager */ |
| 64062 | - } ce; | |
| 64033 | + } ch; | |
| 64063 | 64034 | struct OP_IncrVacuum_stack_vars { |
| 64064 | 64035 | Btree *pBt; |
| 64065 | - } cf; | |
| 64036 | + } ci; | |
| 64066 | 64037 | struct OP_VBegin_stack_vars { |
| 64067 | 64038 | VTable *pVTab; |
| 64068 | - } cg; | |
| 64039 | + } cj; | |
| 64069 | 64040 | struct OP_VOpen_stack_vars { |
| 64070 | 64041 | VdbeCursor *pCur; |
| 64071 | 64042 | sqlite3_vtab_cursor *pVtabCursor; |
| 64072 | 64043 | sqlite3_vtab *pVtab; |
| 64073 | 64044 | sqlite3_module *pModule; |
| 64074 | - } ch; | |
| 64045 | + } ck; | |
| 64075 | 64046 | struct OP_VFilter_stack_vars { |
| 64076 | 64047 | int nArg; |
| 64077 | 64048 | int iQuery; |
| 64078 | 64049 | const sqlite3_module *pModule; |
| 64079 | 64050 | Mem *pQuery; |
| @@ -64082,40 +64053,40 @@ | ||
| 64082 | 64053 | sqlite3_vtab *pVtab; |
| 64083 | 64054 | VdbeCursor *pCur; |
| 64084 | 64055 | int res; |
| 64085 | 64056 | int i; |
| 64086 | 64057 | Mem **apArg; |
| 64087 | - } ci; | |
| 64058 | + } cl; | |
| 64088 | 64059 | struct OP_VColumn_stack_vars { |
| 64089 | 64060 | sqlite3_vtab *pVtab; |
| 64090 | 64061 | const sqlite3_module *pModule; |
| 64091 | 64062 | Mem *pDest; |
| 64092 | 64063 | sqlite3_context sContext; |
| 64093 | - } cj; | |
| 64064 | + } cm; | |
| 64094 | 64065 | struct OP_VNext_stack_vars { |
| 64095 | 64066 | sqlite3_vtab *pVtab; |
| 64096 | 64067 | const sqlite3_module *pModule; |
| 64097 | 64068 | int res; |
| 64098 | 64069 | VdbeCursor *pCur; |
| 64099 | - } ck; | |
| 64070 | + } cn; | |
| 64100 | 64071 | struct OP_VRename_stack_vars { |
| 64101 | 64072 | sqlite3_vtab *pVtab; |
| 64102 | 64073 | Mem *pName; |
| 64103 | - } cl; | |
| 64074 | + } co; | |
| 64104 | 64075 | struct OP_VUpdate_stack_vars { |
| 64105 | 64076 | sqlite3_vtab *pVtab; |
| 64106 | 64077 | sqlite3_module *pModule; |
| 64107 | 64078 | int nArg; |
| 64108 | 64079 | int i; |
| 64109 | 64080 | sqlite_int64 rowid; |
| 64110 | 64081 | Mem **apArg; |
| 64111 | 64082 | Mem *pX; |
| 64112 | - } cm; | |
| 64083 | + } cp; | |
| 64113 | 64084 | struct OP_Trace_stack_vars { |
| 64114 | 64085 | char *zTrace; |
| 64115 | 64086 | char *z; |
| 64116 | - } cn; | |
| 64087 | + } cq; | |
| 64117 | 64088 | } u; |
| 64118 | 64089 | /* End automatically generated code |
| 64119 | 64090 | ********************************************************************/ |
| 64120 | 64091 | |
| 64121 | 64092 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| @@ -66746,17 +66717,10 @@ | ||
| 66746 | 66717 | ** This opcode works the same as OP_OpenEphemeral. It has a |
| 66747 | 66718 | ** different name to distinguish its use. Tables created using |
| 66748 | 66719 | ** by this opcode will be used for automatically created transient |
| 66749 | 66720 | ** indices in joins. |
| 66750 | 66721 | */ |
| 66751 | -/* Opcode: OpenSorter P1 P2 * P4 * | |
| 66752 | -** | |
| 66753 | -** This opcode works like OP_OpenEphemeral except that it opens | |
| 66754 | -** a transient index that is specifically designed to sort large | |
| 66755 | -** tables using an external merge-sort algorithm. | |
| 66756 | -*/ | |
| 66757 | -case OP_OpenSorter: | |
| 66758 | 66722 | case OP_OpenAutoindex: |
| 66759 | 66723 | case OP_OpenEphemeral: { |
| 66760 | 66724 | #if 0 /* local variables moved into u.ax */ |
| 66761 | 66725 | VdbeCursor *pCx; |
| 66762 | 66726 | #endif /* local variables moved into u.ax */ |
| @@ -66766,11 +66730,10 @@ | ||
| 66766 | 66730 | SQLITE_OPEN_EXCLUSIVE | |
| 66767 | 66731 | SQLITE_OPEN_DELETEONCLOSE | |
| 66768 | 66732 | SQLITE_OPEN_TRANSIENT_DB; |
| 66769 | 66733 | |
| 66770 | 66734 | assert( pOp->p1>=0 ); |
| 66771 | - assert( (pOp->opcode==OP_OpenSorter)==((pOp->p5 & BTREE_SORTER)!=0) ); | |
| 66772 | 66735 | u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66773 | 66736 | if( u.ax.pCx==0 ) goto no_mem; |
| 66774 | 66737 | u.ax.pCx->nullRow = 1; |
| 66775 | 66738 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, |
| 66776 | 66739 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| @@ -66800,14 +66763,33 @@ | ||
| 66800 | 66763 | u.ax.pCx->isTable = 1; |
| 66801 | 66764 | } |
| 66802 | 66765 | } |
| 66803 | 66766 | u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66804 | 66767 | u.ax.pCx->isIndex = !u.ax.pCx->isTable; |
| 66768 | + break; | |
| 66769 | +} | |
| 66770 | + | |
| 66771 | +/* Opcode: OpenSorter P1 P2 * P4 * | |
| 66772 | +** | |
| 66773 | +** This opcode works like OP_OpenEphemeral except that it opens | |
| 66774 | +** a transient index that is specifically designed to sort large | |
| 66775 | +** tables using an external merge-sort algorithm. | |
| 66776 | +*/ | |
| 66777 | +case OP_SorterOpen: { | |
| 66778 | +#if 0 /* local variables moved into u.ay */ | |
| 66779 | + VdbeCursor *pCx; | |
| 66780 | +#endif /* local variables moved into u.ay */ | |
| 66805 | 66781 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 66806 | - if( rc==SQLITE_OK && pOp->opcode==OP_OpenSorter ){ | |
| 66807 | - rc = sqlite3VdbeSorterInit(db, u.ax.pCx); | |
| 66808 | - } | |
| 66782 | + u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); | |
| 66783 | + if( u.ay.pCx==0 ) goto no_mem; | |
| 66784 | + u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; | |
| 66785 | + u.ay.pCx->pKeyInfo->enc = ENC(p->db); | |
| 66786 | + u.ay.pCx->isSorter = 1; | |
| 66787 | + rc = sqlite3VdbeSorterInit(db, u.ay.pCx); | |
| 66788 | +#else | |
| 66789 | + pOp->opcode = OP_OpenEphemeral; | |
| 66790 | + pc--; | |
| 66809 | 66791 | #endif |
| 66810 | 66792 | break; |
| 66811 | 66793 | } |
| 66812 | 66794 | |
| 66813 | 66795 | /* Opcode: OpenPseudo P1 P2 P3 * * |
| @@ -66824,21 +66806,21 @@ | ||
| 66824 | 66806 | ** |
| 66825 | 66807 | ** P3 is the number of fields in the records that will be stored by |
| 66826 | 66808 | ** the pseudo-table. |
| 66827 | 66809 | */ |
| 66828 | 66810 | case OP_OpenPseudo: { |
| 66829 | -#if 0 /* local variables moved into u.ay */ | |
| 66811 | +#if 0 /* local variables moved into u.az */ | |
| 66830 | 66812 | VdbeCursor *pCx; |
| 66831 | -#endif /* local variables moved into u.ay */ | |
| 66813 | +#endif /* local variables moved into u.az */ | |
| 66832 | 66814 | |
| 66833 | 66815 | assert( pOp->p1>=0 ); |
| 66834 | - u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); | |
| 66835 | - if( u.ay.pCx==0 ) goto no_mem; | |
| 66836 | - u.ay.pCx->nullRow = 1; | |
| 66837 | - u.ay.pCx->pseudoTableReg = pOp->p2; | |
| 66838 | - u.ay.pCx->isTable = 1; | |
| 66839 | - u.ay.pCx->isIndex = 0; | |
| 66816 | + u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); | |
| 66817 | + if( u.az.pCx==0 ) goto no_mem; | |
| 66818 | + u.az.pCx->nullRow = 1; | |
| 66819 | + u.az.pCx->pseudoTableReg = pOp->p2; | |
| 66820 | + u.az.pCx->isTable = 1; | |
| 66821 | + u.az.pCx->isIndex = 0; | |
| 66840 | 66822 | break; |
| 66841 | 66823 | } |
| 66842 | 66824 | |
| 66843 | 66825 | /* Opcode: Close P1 * * * * |
| 66844 | 66826 | ** |
| @@ -66906,39 +66888,39 @@ | ||
| 66906 | 66888 | */ |
| 66907 | 66889 | case OP_SeekLt: /* jump, in3 */ |
| 66908 | 66890 | case OP_SeekLe: /* jump, in3 */ |
| 66909 | 66891 | case OP_SeekGe: /* jump, in3 */ |
| 66910 | 66892 | case OP_SeekGt: { /* jump, in3 */ |
| 66911 | -#if 0 /* local variables moved into u.az */ | |
| 66893 | +#if 0 /* local variables moved into u.ba */ | |
| 66912 | 66894 | int res; |
| 66913 | 66895 | int oc; |
| 66914 | 66896 | VdbeCursor *pC; |
| 66915 | 66897 | UnpackedRecord r; |
| 66916 | 66898 | int nField; |
| 66917 | 66899 | i64 iKey; /* The rowid we are to seek to */ |
| 66918 | -#endif /* local variables moved into u.az */ | |
| 66900 | +#endif /* local variables moved into u.ba */ | |
| 66919 | 66901 | |
| 66920 | 66902 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 66921 | 66903 | assert( pOp->p2!=0 ); |
| 66922 | - u.az.pC = p->apCsr[pOp->p1]; | |
| 66923 | - assert( u.az.pC!=0 ); | |
| 66924 | - assert( u.az.pC->pseudoTableReg==0 ); | |
| 66904 | + u.ba.pC = p->apCsr[pOp->p1]; | |
| 66905 | + assert( u.ba.pC!=0 ); | |
| 66906 | + assert( u.ba.pC->pseudoTableReg==0 ); | |
| 66925 | 66907 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 66926 | 66908 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 66927 | 66909 | assert( OP_SeekGt == OP_SeekLt+3 ); |
| 66928 | - assert( u.az.pC->isOrdered ); | |
| 66929 | - if( ALWAYS(u.az.pC->pCursor!=0) ){ | |
| 66930 | - u.az.oc = pOp->opcode; | |
| 66931 | - u.az.pC->nullRow = 0; | |
| 66932 | - if( u.az.pC->isTable ){ | |
| 66910 | + assert( u.ba.pC->isOrdered ); | |
| 66911 | + if( ALWAYS(u.ba.pC->pCursor!=0) ){ | |
| 66912 | + u.ba.oc = pOp->opcode; | |
| 66913 | + u.ba.pC->nullRow = 0; | |
| 66914 | + if( u.ba.pC->isTable ){ | |
| 66933 | 66915 | /* The input value in P3 might be of any type: integer, real, string, |
| 66934 | 66916 | ** blob, or NULL. But it needs to be an integer before we can do |
| 66935 | 66917 | ** the seek, so covert it. */ |
| 66936 | 66918 | pIn3 = &aMem[pOp->p3]; |
| 66937 | 66919 | applyNumericAffinity(pIn3); |
| 66938 | - u.az.iKey = sqlite3VdbeIntValue(pIn3); | |
| 66939 | - u.az.pC->rowidIsValid = 0; | |
| 66920 | + u.ba.iKey = sqlite3VdbeIntValue(pIn3); | |
| 66921 | + u.ba.pC->rowidIsValid = 0; | |
| 66940 | 66922 | |
| 66941 | 66923 | /* If the P3 value could not be converted into an integer without |
| 66942 | 66924 | ** loss of information, then special processing is required... */ |
| 66943 | 66925 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 66944 | 66926 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -66949,105 +66931,105 @@ | ||
| 66949 | 66931 | } |
| 66950 | 66932 | /* If we reach this point, then the P3 value must be a floating |
| 66951 | 66933 | ** point number. */ |
| 66952 | 66934 | assert( (pIn3->flags & MEM_Real)!=0 ); |
| 66953 | 66935 | |
| 66954 | - if( u.az.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.az.iKey || pIn3->r>0) ){ | |
| 66955 | - /* The P3 value is too large in magnitude to be expressed as an | |
| 66956 | - ** integer. */ | |
| 66957 | - u.az.res = 1; | |
| 66958 | - if( pIn3->r<0 ){ | |
| 66959 | - if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); | |
| 66960 | - rc = sqlite3BtreeFirst(u.az.pC->pCursor, &u.az.res); | |
| 66961 | - if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 66962 | - } | |
| 66963 | - }else{ | |
| 66964 | - if( u.az.oc<=OP_SeekLe ){ assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); | |
| 66965 | - rc = sqlite3BtreeLast(u.az.pC->pCursor, &u.az.res); | |
| 66966 | - if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 66967 | - } | |
| 66968 | - } | |
| 66969 | - if( u.az.res ){ | |
| 66970 | - pc = pOp->p2 - 1; | |
| 66971 | - } | |
| 66972 | - break; | |
| 66973 | - }else if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekGe ){ | |
| 66974 | - /* Use the ceiling() function to convert real->int */ | |
| 66975 | - if( pIn3->r > (double)u.az.iKey ) u.az.iKey++; | |
| 66976 | - }else{ | |
| 66977 | - /* Use the floor() function to convert real->int */ | |
| 66978 | - assert( u.az.oc==OP_SeekLe || u.az.oc==OP_SeekGt ); | |
| 66979 | - if( pIn3->r < (double)u.az.iKey ) u.az.iKey--; | |
| 66980 | - } | |
| 66981 | - } | |
| 66982 | - rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, 0, (u64)u.az.iKey, 0, &u.az.res); | |
| 66983 | - if( rc!=SQLITE_OK ){ | |
| 66984 | - goto abort_due_to_error; | |
| 66985 | - } | |
| 66986 | - if( u.az.res==0 ){ | |
| 66987 | - u.az.pC->rowidIsValid = 1; | |
| 66988 | - u.az.pC->lastRowid = u.az.iKey; | |
| 66989 | - } | |
| 66990 | - }else{ | |
| 66991 | - u.az.nField = pOp->p4.i; | |
| 66992 | - assert( pOp->p4type==P4_INT32 ); | |
| 66993 | - assert( u.az.nField>0 ); | |
| 66994 | - u.az.r.pKeyInfo = u.az.pC->pKeyInfo; | |
| 66995 | - u.az.r.nField = (u16)u.az.nField; | |
| 66996 | - | |
| 66997 | - /* The next line of code computes as follows, only faster: | |
| 66998 | - ** if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekLe ){ | |
| 66999 | - ** u.az.r.flags = UNPACKED_INCRKEY; | |
| 67000 | - ** }else{ | |
| 67001 | - ** u.az.r.flags = 0; | |
| 67002 | - ** } | |
| 67003 | - */ | |
| 67004 | - u.az.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.az.oc - OP_SeekLt))); | |
| 67005 | - assert( u.az.oc!=OP_SeekGt || u.az.r.flags==UNPACKED_INCRKEY ); | |
| 67006 | - assert( u.az.oc!=OP_SeekLe || u.az.r.flags==UNPACKED_INCRKEY ); | |
| 67007 | - assert( u.az.oc!=OP_SeekGe || u.az.r.flags==0 ); | |
| 67008 | - assert( u.az.oc!=OP_SeekLt || u.az.r.flags==0 ); | |
| 67009 | - | |
| 67010 | - u.az.r.aMem = &aMem[pOp->p3]; | |
| 67011 | -#ifdef SQLITE_DEBUG | |
| 67012 | - { int i; for(i=0; i<u.az.r.nField; i++) assert( memIsValid(&u.az.r.aMem[i]) ); } | |
| 67013 | -#endif | |
| 67014 | - ExpandBlob(u.az.r.aMem); | |
| 67015 | - rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res); | |
| 67016 | - if( rc!=SQLITE_OK ){ | |
| 67017 | - goto abort_due_to_error; | |
| 67018 | - } | |
| 67019 | - u.az.pC->rowidIsValid = 0; | |
| 67020 | - } | |
| 67021 | - u.az.pC->deferredMoveto = 0; | |
| 67022 | - u.az.pC->cacheStatus = CACHE_STALE; | |
| 67023 | -#ifdef SQLITE_TEST | |
| 67024 | - sqlite3_search_count++; | |
| 67025 | -#endif | |
| 67026 | - if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); | |
| 67027 | - if( u.az.res<0 || (u.az.res==0 && u.az.oc==OP_SeekGt) ){ | |
| 67028 | - rc = sqlite3BtreeNext(u.az.pC->pCursor, &u.az.res); | |
| 67029 | - if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 67030 | - u.az.pC->rowidIsValid = 0; | |
| 67031 | - }else{ | |
| 67032 | - u.az.res = 0; | |
| 67033 | - } | |
| 67034 | - }else{ | |
| 67035 | - assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); | |
| 67036 | - if( u.az.res>0 || (u.az.res==0 && u.az.oc==OP_SeekLt) ){ | |
| 67037 | - rc = sqlite3BtreePrevious(u.az.pC->pCursor, &u.az.res); | |
| 67038 | - if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 67039 | - u.az.pC->rowidIsValid = 0; | |
| 67040 | - }else{ | |
| 67041 | - /* u.az.res might be negative because the table is empty. Check to | |
| 67042 | - ** see if this is the case. | |
| 67043 | - */ | |
| 67044 | - u.az.res = sqlite3BtreeEof(u.az.pC->pCursor); | |
| 67045 | - } | |
| 67046 | - } | |
| 67047 | - assert( pOp->p2>0 ); | |
| 67048 | - if( u.az.res ){ | |
| 66936 | + if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ | |
| 66937 | + /* The P3 value is too large in magnitude to be expressed as an | |
| 66938 | + ** integer. */ | |
| 66939 | + u.ba.res = 1; | |
| 66940 | + if( pIn3->r<0 ){ | |
| 66941 | + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); | |
| 66942 | + rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); | |
| 66943 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 66944 | + } | |
| 66945 | + }else{ | |
| 66946 | + if( u.ba.oc<=OP_SeekLe ){ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); | |
| 66947 | + rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); | |
| 66948 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 66949 | + } | |
| 66950 | + } | |
| 66951 | + if( u.ba.res ){ | |
| 66952 | + pc = pOp->p2 - 1; | |
| 66953 | + } | |
| 66954 | + break; | |
| 66955 | + }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ | |
| 66956 | + /* Use the ceiling() function to convert real->int */ | |
| 66957 | + if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; | |
| 66958 | + }else{ | |
| 66959 | + /* Use the floor() function to convert real->int */ | |
| 66960 | + assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); | |
| 66961 | + if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; | |
| 66962 | + } | |
| 66963 | + } | |
| 66964 | + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); | |
| 66965 | + if( rc!=SQLITE_OK ){ | |
| 66966 | + goto abort_due_to_error; | |
| 66967 | + } | |
| 66968 | + if( u.ba.res==0 ){ | |
| 66969 | + u.ba.pC->rowidIsValid = 1; | |
| 66970 | + u.ba.pC->lastRowid = u.ba.iKey; | |
| 66971 | + } | |
| 66972 | + }else{ | |
| 66973 | + u.ba.nField = pOp->p4.i; | |
| 66974 | + assert( pOp->p4type==P4_INT32 ); | |
| 66975 | + assert( u.ba.nField>0 ); | |
| 66976 | + u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; | |
| 66977 | + u.ba.r.nField = (u16)u.ba.nField; | |
| 66978 | + | |
| 66979 | + /* The next line of code computes as follows, only faster: | |
| 66980 | + ** if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ | |
| 66981 | + ** u.ba.r.flags = UNPACKED_INCRKEY; | |
| 66982 | + ** }else{ | |
| 66983 | + ** u.ba.r.flags = 0; | |
| 66984 | + ** } | |
| 66985 | + */ | |
| 66986 | + u.ba.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.ba.oc - OP_SeekLt))); | |
| 66987 | + assert( u.ba.oc!=OP_SeekGt || u.ba.r.flags==UNPACKED_INCRKEY ); | |
| 66988 | + assert( u.ba.oc!=OP_SeekLe || u.ba.r.flags==UNPACKED_INCRKEY ); | |
| 66989 | + assert( u.ba.oc!=OP_SeekGe || u.ba.r.flags==0 ); | |
| 66990 | + assert( u.ba.oc!=OP_SeekLt || u.ba.r.flags==0 ); | |
| 66991 | + | |
| 66992 | + u.ba.r.aMem = &aMem[pOp->p3]; | |
| 66993 | +#ifdef SQLITE_DEBUG | |
| 66994 | + { int i; for(i=0; i<u.ba.r.nField; i++) assert( memIsValid(&u.ba.r.aMem[i]) ); } | |
| 66995 | +#endif | |
| 66996 | + ExpandBlob(u.ba.r.aMem); | |
| 66997 | + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); | |
| 66998 | + if( rc!=SQLITE_OK ){ | |
| 66999 | + goto abort_due_to_error; | |
| 67000 | + } | |
| 67001 | + u.ba.pC->rowidIsValid = 0; | |
| 67002 | + } | |
| 67003 | + u.ba.pC->deferredMoveto = 0; | |
| 67004 | + u.ba.pC->cacheStatus = CACHE_STALE; | |
| 67005 | +#ifdef SQLITE_TEST | |
| 67006 | + sqlite3_search_count++; | |
| 67007 | +#endif | |
| 67008 | + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); | |
| 67009 | + if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ | |
| 67010 | + rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); | |
| 67011 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 67012 | + u.ba.pC->rowidIsValid = 0; | |
| 67013 | + }else{ | |
| 67014 | + u.ba.res = 0; | |
| 67015 | + } | |
| 67016 | + }else{ | |
| 67017 | + assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); | |
| 67018 | + if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ | |
| 67019 | + rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); | |
| 67020 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; | |
| 67021 | + u.ba.pC->rowidIsValid = 0; | |
| 67022 | + }else{ | |
| 67023 | + /* u.ba.res might be negative because the table is empty. Check to | |
| 67024 | + ** see if this is the case. | |
| 67025 | + */ | |
| 67026 | + u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); | |
| 67027 | + } | |
| 67028 | + } | |
| 67029 | + assert( pOp->p2>0 ); | |
| 67030 | + if( u.ba.res ){ | |
| 67049 | 67031 | pc = pOp->p2 - 1; |
| 67050 | 67032 | } |
| 67051 | 67033 | }else{ |
| 67052 | 67034 | /* This happens when attempting to open the sqlite3_master table |
| 67053 | 67035 | ** for read access returns SQLITE_EMPTY. In this case always |
| @@ -67066,24 +67048,24 @@ | ||
| 67066 | 67048 | ** This is actually a deferred seek. Nothing actually happens until |
| 67067 | 67049 | ** the cursor is used to read a record. That way, if no reads |
| 67068 | 67050 | ** occur, no unnecessary I/O happens. |
| 67069 | 67051 | */ |
| 67070 | 67052 | case OP_Seek: { /* in2 */ |
| 67071 | -#if 0 /* local variables moved into u.ba */ | |
| 67053 | +#if 0 /* local variables moved into u.bb */ | |
| 67072 | 67054 | VdbeCursor *pC; |
| 67073 | -#endif /* local variables moved into u.ba */ | |
| 67055 | +#endif /* local variables moved into u.bb */ | |
| 67074 | 67056 | |
| 67075 | 67057 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67076 | - u.ba.pC = p->apCsr[pOp->p1]; | |
| 67077 | - assert( u.ba.pC!=0 ); | |
| 67078 | - if( ALWAYS(u.ba.pC->pCursor!=0) ){ | |
| 67079 | - assert( u.ba.pC->isTable ); | |
| 67080 | - u.ba.pC->nullRow = 0; | |
| 67058 | + u.bb.pC = p->apCsr[pOp->p1]; | |
| 67059 | + assert( u.bb.pC!=0 ); | |
| 67060 | + if( ALWAYS(u.bb.pC->pCursor!=0) ){ | |
| 67061 | + assert( u.bb.pC->isTable ); | |
| 67062 | + u.bb.pC->nullRow = 0; | |
| 67081 | 67063 | pIn2 = &aMem[pOp->p2]; |
| 67082 | - u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); | |
| 67083 | - u.ba.pC->rowidIsValid = 0; | |
| 67084 | - u.ba.pC->deferredMoveto = 1; | |
| 67064 | + u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); | |
| 67065 | + u.bb.pC->rowidIsValid = 0; | |
| 67066 | + u.bb.pC->deferredMoveto = 1; | |
| 67085 | 67067 | } |
| 67086 | 67068 | break; |
| 67087 | 67069 | } |
| 67088 | 67070 | |
| 67089 | 67071 | |
| @@ -67111,66 +67093,66 @@ | ||
| 67111 | 67093 | ** |
| 67112 | 67094 | ** See also: Found, NotExists, IsUnique |
| 67113 | 67095 | */ |
| 67114 | 67096 | case OP_NotFound: /* jump, in3 */ |
| 67115 | 67097 | case OP_Found: { /* jump, in3 */ |
| 67116 | -#if 0 /* local variables moved into u.bb */ | |
| 67098 | +#if 0 /* local variables moved into u.bc */ | |
| 67117 | 67099 | int alreadyExists; |
| 67118 | 67100 | VdbeCursor *pC; |
| 67119 | 67101 | int res; |
| 67120 | 67102 | UnpackedRecord *pIdxKey; |
| 67121 | 67103 | UnpackedRecord r; |
| 67122 | 67104 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 67123 | -#endif /* local variables moved into u.bb */ | |
| 67105 | +#endif /* local variables moved into u.bc */ | |
| 67124 | 67106 | |
| 67125 | 67107 | #ifdef SQLITE_TEST |
| 67126 | 67108 | sqlite3_found_count++; |
| 67127 | 67109 | #endif |
| 67128 | 67110 | |
| 67129 | - u.bb.alreadyExists = 0; | |
| 67111 | + u.bc.alreadyExists = 0; | |
| 67130 | 67112 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67131 | 67113 | assert( pOp->p4type==P4_INT32 ); |
| 67132 | - u.bb.pC = p->apCsr[pOp->p1]; | |
| 67133 | - assert( u.bb.pC!=0 ); | |
| 67114 | + u.bc.pC = p->apCsr[pOp->p1]; | |
| 67115 | + assert( u.bc.pC!=0 ); | |
| 67134 | 67116 | pIn3 = &aMem[pOp->p3]; |
| 67135 | - if( ALWAYS(u.bb.pC->pCursor!=0) ){ | |
| 67117 | + if( ALWAYS(u.bc.pC->pCursor!=0) ){ | |
| 67136 | 67118 | |
| 67137 | - assert( u.bb.pC->isTable==0 ); | |
| 67119 | + assert( u.bc.pC->isTable==0 ); | |
| 67138 | 67120 | if( pOp->p4.i>0 ){ |
| 67139 | - u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo; | |
| 67140 | - u.bb.r.nField = (u16)pOp->p4.i; | |
| 67141 | - u.bb.r.aMem = pIn3; | |
| 67121 | + u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; | |
| 67122 | + u.bc.r.nField = (u16)pOp->p4.i; | |
| 67123 | + u.bc.r.aMem = pIn3; | |
| 67142 | 67124 | #ifdef SQLITE_DEBUG |
| 67143 | - { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); } | |
| 67125 | + { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } | |
| 67144 | 67126 | #endif |
| 67145 | - u.bb.r.flags = UNPACKED_PREFIX_MATCH; | |
| 67146 | - u.bb.pIdxKey = &u.bb.r; | |
| 67127 | + u.bc.r.flags = UNPACKED_PREFIX_MATCH; | |
| 67128 | + u.bc.pIdxKey = &u.bc.r; | |
| 67147 | 67129 | }else{ |
| 67148 | 67130 | assert( pIn3->flags & MEM_Blob ); |
| 67149 | 67131 | assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ |
| 67150 | - u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z, | |
| 67151 | - u.bb.aTempRec, sizeof(u.bb.aTempRec)); | |
| 67152 | - if( u.bb.pIdxKey==0 ){ | |
| 67132 | + u.bc.pIdxKey = sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, | |
| 67133 | + u.bc.aTempRec, sizeof(u.bc.aTempRec)); | |
| 67134 | + if( u.bc.pIdxKey==0 ){ | |
| 67153 | 67135 | goto no_mem; |
| 67154 | 67136 | } |
| 67155 | - u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; | |
| 67137 | + u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; | |
| 67156 | 67138 | } |
| 67157 | - rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, u.bb.pIdxKey, 0, 0, &u.bb.res); | |
| 67139 | + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); | |
| 67158 | 67140 | if( pOp->p4.i==0 ){ |
| 67159 | - sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey); | |
| 67141 | + sqlite3VdbeDeleteUnpackedRecord(u.bc.pIdxKey); | |
| 67160 | 67142 | } |
| 67161 | 67143 | if( rc!=SQLITE_OK ){ |
| 67162 | 67144 | break; |
| 67163 | 67145 | } |
| 67164 | - u.bb.alreadyExists = (u.bb.res==0); | |
| 67165 | - u.bb.pC->deferredMoveto = 0; | |
| 67166 | - u.bb.pC->cacheStatus = CACHE_STALE; | |
| 67146 | + u.bc.alreadyExists = (u.bc.res==0); | |
| 67147 | + u.bc.pC->deferredMoveto = 0; | |
| 67148 | + u.bc.pC->cacheStatus = CACHE_STALE; | |
| 67167 | 67149 | } |
| 67168 | 67150 | if( pOp->opcode==OP_Found ){ |
| 67169 | - if( u.bb.alreadyExists ) pc = pOp->p2 - 1; | |
| 67151 | + if( u.bc.alreadyExists ) pc = pOp->p2 - 1; | |
| 67170 | 67152 | }else{ |
| 67171 | - if( !u.bb.alreadyExists ) pc = pOp->p2 - 1; | |
| 67153 | + if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; | |
| 67172 | 67154 | } |
| 67173 | 67155 | break; |
| 67174 | 67156 | } |
| 67175 | 67157 | |
| 67176 | 67158 | /* Opcode: IsUnique P1 P2 P3 P4 * |
| @@ -67198,67 +67180,67 @@ | ||
| 67198 | 67180 | ** instruction. |
| 67199 | 67181 | ** |
| 67200 | 67182 | ** See also: NotFound, NotExists, Found |
| 67201 | 67183 | */ |
| 67202 | 67184 | case OP_IsUnique: { /* jump, in3 */ |
| 67203 | -#if 0 /* local variables moved into u.bc */ | |
| 67185 | +#if 0 /* local variables moved into u.bd */ | |
| 67204 | 67186 | u16 ii; |
| 67205 | 67187 | VdbeCursor *pCx; |
| 67206 | 67188 | BtCursor *pCrsr; |
| 67207 | 67189 | u16 nField; |
| 67208 | 67190 | Mem *aMx; |
| 67209 | 67191 | UnpackedRecord r; /* B-Tree index search key */ |
| 67210 | 67192 | i64 R; /* Rowid stored in register P3 */ |
| 67211 | -#endif /* local variables moved into u.bc */ | |
| 67193 | +#endif /* local variables moved into u.bd */ | |
| 67212 | 67194 | |
| 67213 | 67195 | pIn3 = &aMem[pOp->p3]; |
| 67214 | - u.bc.aMx = &aMem[pOp->p4.i]; | |
| 67196 | + u.bd.aMx = &aMem[pOp->p4.i]; | |
| 67215 | 67197 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 67216 | 67198 | assert( pOp->p4type==P4_INT32 ); |
| 67217 | 67199 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 67218 | 67200 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67219 | 67201 | |
| 67220 | 67202 | /* Find the index cursor. */ |
| 67221 | - u.bc.pCx = p->apCsr[pOp->p1]; | |
| 67222 | - assert( u.bc.pCx->deferredMoveto==0 ); | |
| 67223 | - u.bc.pCx->seekResult = 0; | |
| 67224 | - u.bc.pCx->cacheStatus = CACHE_STALE; | |
| 67225 | - u.bc.pCrsr = u.bc.pCx->pCursor; | |
| 67203 | + u.bd.pCx = p->apCsr[pOp->p1]; | |
| 67204 | + assert( u.bd.pCx->deferredMoveto==0 ); | |
| 67205 | + u.bd.pCx->seekResult = 0; | |
| 67206 | + u.bd.pCx->cacheStatus = CACHE_STALE; | |
| 67207 | + u.bd.pCrsr = u.bd.pCx->pCursor; | |
| 67226 | 67208 | |
| 67227 | 67209 | /* If any of the values are NULL, take the jump. */ |
| 67228 | - u.bc.nField = u.bc.pCx->pKeyInfo->nField; | |
| 67229 | - for(u.bc.ii=0; u.bc.ii<u.bc.nField; u.bc.ii++){ | |
| 67230 | - if( u.bc.aMx[u.bc.ii].flags & MEM_Null ){ | |
| 67210 | + u.bd.nField = u.bd.pCx->pKeyInfo->nField; | |
| 67211 | + for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ | |
| 67212 | + if( u.bd.aMx[u.bd.ii].flags & MEM_Null ){ | |
| 67231 | 67213 | pc = pOp->p2 - 1; |
| 67232 | - u.bc.pCrsr = 0; | |
| 67214 | + u.bd.pCrsr = 0; | |
| 67233 | 67215 | break; |
| 67234 | 67216 | } |
| 67235 | 67217 | } |
| 67236 | - assert( (u.bc.aMx[u.bc.nField].flags & MEM_Null)==0 ); | |
| 67218 | + assert( (u.bd.aMx[u.bd.nField].flags & MEM_Null)==0 ); | |
| 67237 | 67219 | |
| 67238 | - if( u.bc.pCrsr!=0 ){ | |
| 67220 | + if( u.bd.pCrsr!=0 ){ | |
| 67239 | 67221 | /* Populate the index search key. */ |
| 67240 | - u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo; | |
| 67241 | - u.bc.r.nField = u.bc.nField + 1; | |
| 67242 | - u.bc.r.flags = UNPACKED_PREFIX_SEARCH; | |
| 67243 | - u.bc.r.aMem = u.bc.aMx; | |
| 67222 | + u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; | |
| 67223 | + u.bd.r.nField = u.bd.nField + 1; | |
| 67224 | + u.bd.r.flags = UNPACKED_PREFIX_SEARCH; | |
| 67225 | + u.bd.r.aMem = u.bd.aMx; | |
| 67244 | 67226 | #ifdef SQLITE_DEBUG |
| 67245 | - { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } | |
| 67227 | + { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } | |
| 67246 | 67228 | #endif |
| 67247 | 67229 | |
| 67248 | - /* Extract the value of u.bc.R from register P3. */ | |
| 67230 | + /* Extract the value of u.bd.R from register P3. */ | |
| 67249 | 67231 | sqlite3VdbeMemIntegerify(pIn3); |
| 67250 | - u.bc.R = pIn3->u.i; | |
| 67232 | + u.bd.R = pIn3->u.i; | |
| 67251 | 67233 | |
| 67252 | 67234 | /* Search the B-Tree index. If no conflicting record is found, jump |
| 67253 | 67235 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
| 67254 | 67236 | ** register P3 and fall through to the next instruction. */ |
| 67255 | - rc = sqlite3BtreeMovetoUnpacked(u.bc.pCrsr, &u.bc.r, 0, 0, &u.bc.pCx->seekResult); | |
| 67256 | - if( (u.bc.r.flags & UNPACKED_PREFIX_SEARCH) || u.bc.r.rowid==u.bc.R ){ | |
| 67237 | + rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); | |
| 67238 | + if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ | |
| 67257 | 67239 | pc = pOp->p2 - 1; |
| 67258 | 67240 | }else{ |
| 67259 | - pIn3->u.i = u.bc.r.rowid; | |
| 67241 | + pIn3->u.i = u.bd.r.rowid; | |
| 67260 | 67242 | } |
| 67261 | 67243 | } |
| 67262 | 67244 | break; |
| 67263 | 67245 | } |
| 67264 | 67246 | |
| @@ -67275,46 +67257,46 @@ | ||
| 67275 | 67257 | ** P1 is an index. |
| 67276 | 67258 | ** |
| 67277 | 67259 | ** See also: Found, NotFound, IsUnique |
| 67278 | 67260 | */ |
| 67279 | 67261 | case OP_NotExists: { /* jump, in3 */ |
| 67280 | -#if 0 /* local variables moved into u.bd */ | |
| 67262 | +#if 0 /* local variables moved into u.be */ | |
| 67281 | 67263 | VdbeCursor *pC; |
| 67282 | 67264 | BtCursor *pCrsr; |
| 67283 | 67265 | int res; |
| 67284 | 67266 | u64 iKey; |
| 67285 | -#endif /* local variables moved into u.bd */ | |
| 67267 | +#endif /* local variables moved into u.be */ | |
| 67286 | 67268 | |
| 67287 | 67269 | pIn3 = &aMem[pOp->p3]; |
| 67288 | 67270 | assert( pIn3->flags & MEM_Int ); |
| 67289 | 67271 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67290 | - u.bd.pC = p->apCsr[pOp->p1]; | |
| 67291 | - assert( u.bd.pC!=0 ); | |
| 67292 | - assert( u.bd.pC->isTable ); | |
| 67293 | - assert( u.bd.pC->pseudoTableReg==0 ); | |
| 67294 | - u.bd.pCrsr = u.bd.pC->pCursor; | |
| 67295 | - if( ALWAYS(u.bd.pCrsr!=0) ){ | |
| 67296 | - u.bd.res = 0; | |
| 67297 | - u.bd.iKey = pIn3->u.i; | |
| 67298 | - rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, 0, u.bd.iKey, 0, &u.bd.res); | |
| 67299 | - u.bd.pC->lastRowid = pIn3->u.i; | |
| 67300 | - u.bd.pC->rowidIsValid = u.bd.res==0 ?1:0; | |
| 67301 | - u.bd.pC->nullRow = 0; | |
| 67302 | - u.bd.pC->cacheStatus = CACHE_STALE; | |
| 67303 | - u.bd.pC->deferredMoveto = 0; | |
| 67304 | - if( u.bd.res!=0 ){ | |
| 67272 | + u.be.pC = p->apCsr[pOp->p1]; | |
| 67273 | + assert( u.be.pC!=0 ); | |
| 67274 | + assert( u.be.pC->isTable ); | |
| 67275 | + assert( u.be.pC->pseudoTableReg==0 ); | |
| 67276 | + u.be.pCrsr = u.be.pC->pCursor; | |
| 67277 | + if( ALWAYS(u.be.pCrsr!=0) ){ | |
| 67278 | + u.be.res = 0; | |
| 67279 | + u.be.iKey = pIn3->u.i; | |
| 67280 | + rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); | |
| 67281 | + u.be.pC->lastRowid = pIn3->u.i; | |
| 67282 | + u.be.pC->rowidIsValid = u.be.res==0 ?1:0; | |
| 67283 | + u.be.pC->nullRow = 0; | |
| 67284 | + u.be.pC->cacheStatus = CACHE_STALE; | |
| 67285 | + u.be.pC->deferredMoveto = 0; | |
| 67286 | + if( u.be.res!=0 ){ | |
| 67305 | 67287 | pc = pOp->p2 - 1; |
| 67306 | - assert( u.bd.pC->rowidIsValid==0 ); | |
| 67288 | + assert( u.be.pC->rowidIsValid==0 ); | |
| 67307 | 67289 | } |
| 67308 | - u.bd.pC->seekResult = u.bd.res; | |
| 67290 | + u.be.pC->seekResult = u.be.res; | |
| 67309 | 67291 | }else{ |
| 67310 | 67292 | /* This happens when an attempt to open a read cursor on the |
| 67311 | 67293 | ** sqlite_master table returns SQLITE_EMPTY. |
| 67312 | 67294 | */ |
| 67313 | 67295 | pc = pOp->p2 - 1; |
| 67314 | - assert( u.bd.pC->rowidIsValid==0 ); | |
| 67315 | - u.bd.pC->seekResult = 0; | |
| 67296 | + assert( u.be.pC->rowidIsValid==0 ); | |
| 67297 | + u.be.pC->seekResult = 0; | |
| 67316 | 67298 | } |
| 67317 | 67299 | break; |
| 67318 | 67300 | } |
| 67319 | 67301 | |
| 67320 | 67302 | /* Opcode: Sequence P1 P2 * * * |
| @@ -67345,25 +67327,25 @@ | ||
| 67345 | 67327 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 67346 | 67328 | ** generated record number. This P3 mechanism is used to help implement the |
| 67347 | 67329 | ** AUTOINCREMENT feature. |
| 67348 | 67330 | */ |
| 67349 | 67331 | case OP_NewRowid: { /* out2-prerelease */ |
| 67350 | -#if 0 /* local variables moved into u.be */ | |
| 67332 | +#if 0 /* local variables moved into u.bf */ | |
| 67351 | 67333 | i64 v; /* The new rowid */ |
| 67352 | 67334 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 67353 | 67335 | int res; /* Result of an sqlite3BtreeLast() */ |
| 67354 | 67336 | int cnt; /* Counter to limit the number of searches */ |
| 67355 | 67337 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 67356 | 67338 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 67357 | -#endif /* local variables moved into u.be */ | |
| 67339 | +#endif /* local variables moved into u.bf */ | |
| 67358 | 67340 | |
| 67359 | - u.be.v = 0; | |
| 67360 | - u.be.res = 0; | |
| 67341 | + u.bf.v = 0; | |
| 67342 | + u.bf.res = 0; | |
| 67361 | 67343 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67362 | - u.be.pC = p->apCsr[pOp->p1]; | |
| 67363 | - assert( u.be.pC!=0 ); | |
| 67364 | - if( NEVER(u.be.pC->pCursor==0) ){ | |
| 67344 | + u.bf.pC = p->apCsr[pOp->p1]; | |
| 67345 | + assert( u.bf.pC!=0 ); | |
| 67346 | + if( NEVER(u.bf.pC->pCursor==0) ){ | |
| 67365 | 67347 | /* The zero initialization above is all that is needed */ |
| 67366 | 67348 | }else{ |
| 67367 | 67349 | /* The next rowid or record number (different terms for the same |
| 67368 | 67350 | ** thing) is obtained in a two-step algorithm. |
| 67369 | 67351 | ** |
| @@ -67375,11 +67357,11 @@ | ||
| 67375 | 67357 | ** The second algorithm is to select a rowid at random and see if |
| 67376 | 67358 | ** it already exists in the table. If it does not exist, we have |
| 67377 | 67359 | ** succeeded. If the random rowid does exist, we select a new one |
| 67378 | 67360 | ** and try again, up to 100 times. |
| 67379 | 67361 | */ |
| 67380 | - assert( u.be.pC->isTable ); | |
| 67362 | + assert( u.bf.pC->isTable ); | |
| 67381 | 67363 | |
| 67382 | 67364 | #ifdef SQLITE_32BIT_ROWID |
| 67383 | 67365 | # define MAX_ROWID 0x7fffffff |
| 67384 | 67366 | #else |
| 67385 | 67367 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| @@ -67387,101 +67369,101 @@ | ||
| 67387 | 67369 | ** to provide the constant while making all compilers happy. |
| 67388 | 67370 | */ |
| 67389 | 67371 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 67390 | 67372 | #endif |
| 67391 | 67373 | |
| 67392 | - if( !u.be.pC->useRandomRowid ){ | |
| 67393 | - u.be.v = sqlite3BtreeGetCachedRowid(u.be.pC->pCursor); | |
| 67394 | - if( u.be.v==0 ){ | |
| 67395 | - rc = sqlite3BtreeLast(u.be.pC->pCursor, &u.be.res); | |
| 67374 | + if( !u.bf.pC->useRandomRowid ){ | |
| 67375 | + u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); | |
| 67376 | + if( u.bf.v==0 ){ | |
| 67377 | + rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); | |
| 67396 | 67378 | if( rc!=SQLITE_OK ){ |
| 67397 | 67379 | goto abort_due_to_error; |
| 67398 | 67380 | } |
| 67399 | - if( u.be.res ){ | |
| 67400 | - u.be.v = 1; /* IMP: R-61914-48074 */ | |
| 67381 | + if( u.bf.res ){ | |
| 67382 | + u.bf.v = 1; /* IMP: R-61914-48074 */ | |
| 67401 | 67383 | }else{ |
| 67402 | - assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) ); | |
| 67403 | - rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v); | |
| 67384 | + assert( sqlite3BtreeCursorIsValid(u.bf.pC->pCursor) ); | |
| 67385 | + rc = sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); | |
| 67404 | 67386 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 67405 | - if( u.be.v==MAX_ROWID ){ | |
| 67406 | - u.be.pC->useRandomRowid = 1; | |
| 67387 | + if( u.bf.v==MAX_ROWID ){ | |
| 67388 | + u.bf.pC->useRandomRowid = 1; | |
| 67407 | 67389 | }else{ |
| 67408 | - u.be.v++; /* IMP: R-29538-34987 */ | |
| 67390 | + u.bf.v++; /* IMP: R-29538-34987 */ | |
| 67409 | 67391 | } |
| 67410 | 67392 | } |
| 67411 | 67393 | } |
| 67412 | 67394 | |
| 67413 | 67395 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 67414 | 67396 | if( pOp->p3 ){ |
| 67415 | 67397 | /* Assert that P3 is a valid memory cell. */ |
| 67416 | 67398 | assert( pOp->p3>0 ); |
| 67417 | 67399 | if( p->pFrame ){ |
| 67418 | - for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent); | |
| 67400 | + for(u.bf.pFrame=p->pFrame; u.bf.pFrame->pParent; u.bf.pFrame=u.bf.pFrame->pParent); | |
| 67419 | 67401 | /* Assert that P3 is a valid memory cell. */ |
| 67420 | - assert( pOp->p3<=u.be.pFrame->nMem ); | |
| 67421 | - u.be.pMem = &u.be.pFrame->aMem[pOp->p3]; | |
| 67402 | + assert( pOp->p3<=u.bf.pFrame->nMem ); | |
| 67403 | + u.bf.pMem = &u.bf.pFrame->aMem[pOp->p3]; | |
| 67422 | 67404 | }else{ |
| 67423 | 67405 | /* Assert that P3 is a valid memory cell. */ |
| 67424 | 67406 | assert( pOp->p3<=p->nMem ); |
| 67425 | - u.be.pMem = &aMem[pOp->p3]; | |
| 67426 | - memAboutToChange(p, u.be.pMem); | |
| 67427 | - } | |
| 67428 | - assert( memIsValid(u.be.pMem) ); | |
| 67429 | - | |
| 67430 | - REGISTER_TRACE(pOp->p3, u.be.pMem); | |
| 67431 | - sqlite3VdbeMemIntegerify(u.be.pMem); | |
| 67432 | - assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ | |
| 67433 | - if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){ | |
| 67407 | + u.bf.pMem = &aMem[pOp->p3]; | |
| 67408 | + memAboutToChange(p, u.bf.pMem); | |
| 67409 | + } | |
| 67410 | + assert( memIsValid(u.bf.pMem) ); | |
| 67411 | + | |
| 67412 | + REGISTER_TRACE(pOp->p3, u.bf.pMem); | |
| 67413 | + sqlite3VdbeMemIntegerify(u.bf.pMem); | |
| 67414 | + assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ | |
| 67415 | + if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ | |
| 67434 | 67416 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 67435 | 67417 | goto abort_due_to_error; |
| 67436 | 67418 | } |
| 67437 | - if( u.be.v<u.be.pMem->u.i+1 ){ | |
| 67438 | - u.be.v = u.be.pMem->u.i + 1; | |
| 67419 | + if( u.bf.v<u.bf.pMem->u.i+1 ){ | |
| 67420 | + u.bf.v = u.bf.pMem->u.i + 1; | |
| 67439 | 67421 | } |
| 67440 | - u.be.pMem->u.i = u.be.v; | |
| 67422 | + u.bf.pMem->u.i = u.bf.v; | |
| 67441 | 67423 | } |
| 67442 | 67424 | #endif |
| 67443 | 67425 | |
| 67444 | - sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0); | |
| 67426 | + sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); | |
| 67445 | 67427 | } |
| 67446 | - if( u.be.pC->useRandomRowid ){ | |
| 67428 | + if( u.bf.pC->useRandomRowid ){ | |
| 67447 | 67429 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 67448 | 67430 | ** largest possible integer (9223372036854775807) then the database |
| 67449 | 67431 | ** engine starts picking positive candidate ROWIDs at random until |
| 67450 | 67432 | ** it finds one that is not previously used. */ |
| 67451 | 67433 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 67452 | 67434 | ** an AUTOINCREMENT table. */ |
| 67453 | 67435 | /* on the first attempt, simply do one more than previous */ |
| 67454 | - u.be.v = lastRowid; | |
| 67455 | - u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | |
| 67456 | - u.be.v++; /* ensure non-zero */ | |
| 67457 | - u.be.cnt = 0; | |
| 67458 | - while( ((rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, | |
| 67459 | - 0, &u.be.res))==SQLITE_OK) | |
| 67460 | - && (u.be.res==0) | |
| 67461 | - && (++u.be.cnt<100)){ | |
| 67436 | + u.bf.v = lastRowid; | |
| 67437 | + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | |
| 67438 | + u.bf.v++; /* ensure non-zero */ | |
| 67439 | + u.bf.cnt = 0; | |
| 67440 | + while( ((rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, | |
| 67441 | + 0, &u.bf.res))==SQLITE_OK) | |
| 67442 | + && (u.bf.res==0) | |
| 67443 | + && (++u.bf.cnt<100)){ | |
| 67462 | 67444 | /* collision - try another random rowid */ |
| 67463 | - sqlite3_randomness(sizeof(u.be.v), &u.be.v); | |
| 67464 | - if( u.be.cnt<5 ){ | |
| 67445 | + sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); | |
| 67446 | + if( u.bf.cnt<5 ){ | |
| 67465 | 67447 | /* try "small" random rowids for the initial attempts */ |
| 67466 | - u.be.v &= 0xffffff; | |
| 67448 | + u.bf.v &= 0xffffff; | |
| 67467 | 67449 | }else{ |
| 67468 | - u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | |
| 67450 | + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ | |
| 67469 | 67451 | } |
| 67470 | - u.be.v++; /* ensure non-zero */ | |
| 67452 | + u.bf.v++; /* ensure non-zero */ | |
| 67471 | 67453 | } |
| 67472 | - if( rc==SQLITE_OK && u.be.res==0 ){ | |
| 67454 | + if( rc==SQLITE_OK && u.bf.res==0 ){ | |
| 67473 | 67455 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 67474 | 67456 | goto abort_due_to_error; |
| 67475 | 67457 | } |
| 67476 | - assert( u.be.v>0 ); /* EV: R-40812-03570 */ | |
| 67458 | + assert( u.bf.v>0 ); /* EV: R-40812-03570 */ | |
| 67477 | 67459 | } |
| 67478 | - u.be.pC->rowidIsValid = 0; | |
| 67479 | - u.be.pC->deferredMoveto = 0; | |
| 67480 | - u.be.pC->cacheStatus = CACHE_STALE; | |
| 67460 | + u.bf.pC->rowidIsValid = 0; | |
| 67461 | + u.bf.pC->deferredMoveto = 0; | |
| 67462 | + u.bf.pC->cacheStatus = CACHE_STALE; | |
| 67481 | 67463 | } |
| 67482 | - pOut->u.i = u.be.v; | |
| 67464 | + pOut->u.i = u.bf.v; | |
| 67483 | 67465 | break; |
| 67484 | 67466 | } |
| 67485 | 67467 | |
| 67486 | 67468 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 67487 | 67469 | ** |
| @@ -67527,74 +67509,74 @@ | ||
| 67527 | 67509 | ** This works exactly like OP_Insert except that the key is the |
| 67528 | 67510 | ** integer value P3, not the value of the integer stored in register P3. |
| 67529 | 67511 | */ |
| 67530 | 67512 | case OP_Insert: |
| 67531 | 67513 | case OP_InsertInt: { |
| 67532 | -#if 0 /* local variables moved into u.bf */ | |
| 67514 | +#if 0 /* local variables moved into u.bg */ | |
| 67533 | 67515 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 67534 | 67516 | Mem *pKey; /* MEM cell holding key for the record */ |
| 67535 | 67517 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 67536 | 67518 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 67537 | 67519 | int nZero; /* Number of zero-bytes to append */ |
| 67538 | 67520 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 67539 | 67521 | const char *zDb; /* database name - used by the update hook */ |
| 67540 | 67522 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 67541 | 67523 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 67542 | -#endif /* local variables moved into u.bf */ | |
| 67524 | +#endif /* local variables moved into u.bg */ | |
| 67543 | 67525 | |
| 67544 | - u.bf.pData = &aMem[pOp->p2]; | |
| 67526 | + u.bg.pData = &aMem[pOp->p2]; | |
| 67545 | 67527 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67546 | - assert( memIsValid(u.bf.pData) ); | |
| 67547 | - u.bf.pC = p->apCsr[pOp->p1]; | |
| 67548 | - assert( u.bf.pC!=0 ); | |
| 67549 | - assert( u.bf.pC->pCursor!=0 ); | |
| 67550 | - assert( u.bf.pC->pseudoTableReg==0 ); | |
| 67551 | - assert( u.bf.pC->isTable ); | |
| 67552 | - REGISTER_TRACE(pOp->p2, u.bf.pData); | |
| 67528 | + assert( memIsValid(u.bg.pData) ); | |
| 67529 | + u.bg.pC = p->apCsr[pOp->p1]; | |
| 67530 | + assert( u.bg.pC!=0 ); | |
| 67531 | + assert( u.bg.pC->pCursor!=0 ); | |
| 67532 | + assert( u.bg.pC->pseudoTableReg==0 ); | |
| 67533 | + assert( u.bg.pC->isTable ); | |
| 67534 | + REGISTER_TRACE(pOp->p2, u.bg.pData); | |
| 67553 | 67535 | |
| 67554 | 67536 | if( pOp->opcode==OP_Insert ){ |
| 67555 | - u.bf.pKey = &aMem[pOp->p3]; | |
| 67556 | - assert( u.bf.pKey->flags & MEM_Int ); | |
| 67557 | - assert( memIsValid(u.bf.pKey) ); | |
| 67558 | - REGISTER_TRACE(pOp->p3, u.bf.pKey); | |
| 67559 | - u.bf.iKey = u.bf.pKey->u.i; | |
| 67537 | + u.bg.pKey = &aMem[pOp->p3]; | |
| 67538 | + assert( u.bg.pKey->flags & MEM_Int ); | |
| 67539 | + assert( memIsValid(u.bg.pKey) ); | |
| 67540 | + REGISTER_TRACE(pOp->p3, u.bg.pKey); | |
| 67541 | + u.bg.iKey = u.bg.pKey->u.i; | |
| 67560 | 67542 | }else{ |
| 67561 | 67543 | assert( pOp->opcode==OP_InsertInt ); |
| 67562 | - u.bf.iKey = pOp->p3; | |
| 67544 | + u.bg.iKey = pOp->p3; | |
| 67563 | 67545 | } |
| 67564 | 67546 | |
| 67565 | 67547 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 67566 | - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bf.iKey; | |
| 67567 | - if( u.bf.pData->flags & MEM_Null ){ | |
| 67568 | - u.bf.pData->z = 0; | |
| 67569 | - u.bf.pData->n = 0; | |
| 67570 | - }else{ | |
| 67571 | - assert( u.bf.pData->flags & (MEM_Blob|MEM_Str) ); | |
| 67572 | - } | |
| 67573 | - u.bf.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bf.pC->seekResult : 0); | |
| 67574 | - if( u.bf.pData->flags & MEM_Zero ){ | |
| 67575 | - u.bf.nZero = u.bf.pData->u.nZero; | |
| 67576 | - }else{ | |
| 67577 | - u.bf.nZero = 0; | |
| 67578 | - } | |
| 67579 | - sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, 0); | |
| 67580 | - rc = sqlite3BtreeInsert(u.bf.pC->pCursor, 0, u.bf.iKey, | |
| 67581 | - u.bf.pData->z, u.bf.pData->n, u.bf.nZero, | |
| 67582 | - pOp->p5 & OPFLAG_APPEND, u.bf.seekResult | |
| 67548 | + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey; | |
| 67549 | + if( u.bg.pData->flags & MEM_Null ){ | |
| 67550 | + u.bg.pData->z = 0; | |
| 67551 | + u.bg.pData->n = 0; | |
| 67552 | + }else{ | |
| 67553 | + assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); | |
| 67554 | + } | |
| 67555 | + u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); | |
| 67556 | + if( u.bg.pData->flags & MEM_Zero ){ | |
| 67557 | + u.bg.nZero = u.bg.pData->u.nZero; | |
| 67558 | + }else{ | |
| 67559 | + u.bg.nZero = 0; | |
| 67560 | + } | |
| 67561 | + sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); | |
| 67562 | + rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, | |
| 67563 | + u.bg.pData->z, u.bg.pData->n, u.bg.nZero, | |
| 67564 | + pOp->p5 & OPFLAG_APPEND, u.bg.seekResult | |
| 67583 | 67565 | ); |
| 67584 | - u.bf.pC->rowidIsValid = 0; | |
| 67585 | - u.bf.pC->deferredMoveto = 0; | |
| 67586 | - u.bf.pC->cacheStatus = CACHE_STALE; | |
| 67566 | + u.bg.pC->rowidIsValid = 0; | |
| 67567 | + u.bg.pC->deferredMoveto = 0; | |
| 67568 | + u.bg.pC->cacheStatus = CACHE_STALE; | |
| 67587 | 67569 | |
| 67588 | 67570 | /* Invoke the update-hook if required. */ |
| 67589 | 67571 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67590 | - u.bf.zDb = db->aDb[u.bf.pC->iDb].zName; | |
| 67591 | - u.bf.zTbl = pOp->p4.z; | |
| 67592 | - u.bf.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); | |
| 67593 | - assert( u.bf.pC->isTable ); | |
| 67594 | - db->xUpdateCallback(db->pUpdateArg, u.bf.op, u.bf.zDb, u.bf.zTbl, u.bf.iKey); | |
| 67595 | - assert( u.bf.pC->iDb>=0 ); | |
| 67572 | + u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; | |
| 67573 | + u.bg.zTbl = pOp->p4.z; | |
| 67574 | + u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); | |
| 67575 | + assert( u.bg.pC->isTable ); | |
| 67576 | + db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); | |
| 67577 | + assert( u.bg.pC->iDb>=0 ); | |
| 67596 | 67578 | } |
| 67597 | 67579 | break; |
| 67598 | 67580 | } |
| 67599 | 67581 | |
| 67600 | 67582 | /* Opcode: Delete P1 P2 * P4 * |
| @@ -67616,51 +67598,51 @@ | ||
| 67616 | 67598 | ** pointing to. The update hook will be invoked, if it exists. |
| 67617 | 67599 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 67618 | 67600 | ** using OP_NotFound prior to invoking this opcode. |
| 67619 | 67601 | */ |
| 67620 | 67602 | case OP_Delete: { |
| 67621 | -#if 0 /* local variables moved into u.bg */ | |
| 67603 | +#if 0 /* local variables moved into u.bh */ | |
| 67622 | 67604 | i64 iKey; |
| 67623 | 67605 | VdbeCursor *pC; |
| 67624 | -#endif /* local variables moved into u.bg */ | |
| 67606 | +#endif /* local variables moved into u.bh */ | |
| 67625 | 67607 | |
| 67626 | - u.bg.iKey = 0; | |
| 67608 | + u.bh.iKey = 0; | |
| 67627 | 67609 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67628 | - u.bg.pC = p->apCsr[pOp->p1]; | |
| 67629 | - assert( u.bg.pC!=0 ); | |
| 67630 | - assert( u.bg.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ | |
| 67610 | + u.bh.pC = p->apCsr[pOp->p1]; | |
| 67611 | + assert( u.bh.pC!=0 ); | |
| 67612 | + assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ | |
| 67631 | 67613 | |
| 67632 | - /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the | |
| 67614 | + /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the | |
| 67633 | 67615 | ** row being deleted. |
| 67634 | 67616 | */ |
| 67635 | 67617 | if( db->xUpdateCallback && pOp->p4.z ){ |
| 67636 | - assert( u.bg.pC->isTable ); | |
| 67637 | - assert( u.bg.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ | |
| 67638 | - u.bg.iKey = u.bg.pC->lastRowid; | |
| 67618 | + assert( u.bh.pC->isTable ); | |
| 67619 | + assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ | |
| 67620 | + u.bh.iKey = u.bh.pC->lastRowid; | |
| 67639 | 67621 | } |
| 67640 | 67622 | |
| 67641 | 67623 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 67642 | 67624 | ** OP_Column on the same table without any intervening operations that |
| 67643 | - ** might move or invalidate the cursor. Hence cursor u.bg.pC is always pointing | |
| 67625 | + ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing | |
| 67644 | 67626 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 67645 | 67627 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 67646 | 67628 | ** to guard against future changes to the code generator. |
| 67647 | 67629 | **/ |
| 67648 | - assert( u.bg.pC->deferredMoveto==0 ); | |
| 67649 | - rc = sqlite3VdbeCursorMoveto(u.bg.pC); | |
| 67630 | + assert( u.bh.pC->deferredMoveto==0 ); | |
| 67631 | + rc = sqlite3VdbeCursorMoveto(u.bh.pC); | |
| 67650 | 67632 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67651 | 67633 | |
| 67652 | - sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); | |
| 67653 | - rc = sqlite3BtreeDelete(u.bg.pC->pCursor); | |
| 67654 | - u.bg.pC->cacheStatus = CACHE_STALE; | |
| 67634 | + sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); | |
| 67635 | + rc = sqlite3BtreeDelete(u.bh.pC->pCursor); | |
| 67636 | + u.bh.pC->cacheStatus = CACHE_STALE; | |
| 67655 | 67637 | |
| 67656 | 67638 | /* Invoke the update-hook if required. */ |
| 67657 | 67639 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67658 | - const char *zDb = db->aDb[u.bg.pC->iDb].zName; | |
| 67640 | + const char *zDb = db->aDb[u.bh.pC->iDb].zName; | |
| 67659 | 67641 | const char *zTbl = pOp->p4.z; |
| 67660 | - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bg.iKey); | |
| 67661 | - assert( u.bg.pC->iDb>=0 ); | |
| 67642 | + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); | |
| 67643 | + assert( u.bh.pC->iDb>=0 ); | |
| 67662 | 67644 | } |
| 67663 | 67645 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 67664 | 67646 | break; |
| 67665 | 67647 | } |
| 67666 | 67648 | /* Opcode: ResetCount * * * * * |
| @@ -67673,10 +67655,53 @@ | ||
| 67673 | 67655 | case OP_ResetCount: { |
| 67674 | 67656 | sqlite3VdbeSetChanges(db, p->nChange); |
| 67675 | 67657 | p->nChange = 0; |
| 67676 | 67658 | break; |
| 67677 | 67659 | } |
| 67660 | + | |
| 67661 | +/* Opcode: SorterCompare P1 P2 P3 | |
| 67662 | +** | |
| 67663 | +** P1 is a sorter cursor. This instruction compares the record blob in | |
| 67664 | +** register P3 with the entry that the sorter cursor currently points to. | |
| 67665 | +** If, excluding the rowid fields at the end, the two records are a match, | |
| 67666 | +** fall through to the next instruction. Otherwise, jump to instruction P2. | |
| 67667 | +*/ | |
| 67668 | +case OP_SorterCompare: { | |
| 67669 | +#if 0 /* local variables moved into u.bi */ | |
| 67670 | + VdbeCursor *pC; | |
| 67671 | + int res; | |
| 67672 | +#endif /* local variables moved into u.bi */ | |
| 67673 | + | |
| 67674 | + u.bi.pC = p->apCsr[pOp->p1]; | |
| 67675 | + assert( isSorter(u.bi.pC) ); | |
| 67676 | + pIn3 = &aMem[pOp->p3]; | |
| 67677 | + rc = sqlite3VdbeSorterCompare(u.bi.pC, pIn3, &u.bi.res); | |
| 67678 | + if( u.bi.res ){ | |
| 67679 | + pc = pOp->p2-1; | |
| 67680 | + } | |
| 67681 | + break; | |
| 67682 | +}; | |
| 67683 | + | |
| 67684 | +/* Opcode: SorterData P1 P2 * * * | |
| 67685 | +** | |
| 67686 | +** Write into register P2 the current sorter data for sorter cursor P1. | |
| 67687 | +*/ | |
| 67688 | +case OP_SorterData: { | |
| 67689 | +#if 0 /* local variables moved into u.bj */ | |
| 67690 | + VdbeCursor *pC; | |
| 67691 | +#endif /* local variables moved into u.bj */ | |
| 67692 | +#ifndef SQLITE_OMIT_MERGE_SORT | |
| 67693 | + pOut = &aMem[pOp->p2]; | |
| 67694 | + u.bj.pC = p->apCsr[pOp->p1]; | |
| 67695 | + assert( u.bj.pC->isSorter ); | |
| 67696 | + rc = sqlite3VdbeSorterRowkey(u.bj.pC, pOut); | |
| 67697 | +#else | |
| 67698 | + pOp->opcode = OP_RowKey; | |
| 67699 | + pc--; | |
| 67700 | +#endif | |
| 67701 | + break; | |
| 67702 | +} | |
| 67678 | 67703 | |
| 67679 | 67704 | /* Opcode: RowData P1 P2 * * * |
| 67680 | 67705 | ** |
| 67681 | 67706 | ** Write into register P2 the complete row data for cursor P1. |
| 67682 | 67707 | ** There is no interpretation of the data. |
| @@ -67696,72 +67721,67 @@ | ||
| 67696 | 67721 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 67697 | 67722 | ** of a real table, not a pseudo-table. |
| 67698 | 67723 | */ |
| 67699 | 67724 | case OP_RowKey: |
| 67700 | 67725 | case OP_RowData: { |
| 67701 | -#if 0 /* local variables moved into u.bh */ | |
| 67726 | +#if 0 /* local variables moved into u.bk */ | |
| 67702 | 67727 | VdbeCursor *pC; |
| 67703 | 67728 | BtCursor *pCrsr; |
| 67704 | 67729 | u32 n; |
| 67705 | 67730 | i64 n64; |
| 67706 | -#endif /* local variables moved into u.bh */ | |
| 67731 | +#endif /* local variables moved into u.bk */ | |
| 67707 | 67732 | |
| 67708 | 67733 | pOut = &aMem[pOp->p2]; |
| 67709 | 67734 | memAboutToChange(p, pOut); |
| 67710 | 67735 | |
| 67711 | 67736 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 67712 | 67737 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67713 | - u.bh.pC = p->apCsr[pOp->p1]; | |
| 67714 | - assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey ); | |
| 67715 | - assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData ); | |
| 67716 | - assert( u.bh.pC!=0 ); | |
| 67717 | - assert( u.bh.pC->nullRow==0 ); | |
| 67718 | - assert( u.bh.pC->pseudoTableReg==0 ); | |
| 67719 | - | |
| 67720 | - if( isSorter(u.bh.pC) ){ | |
| 67721 | - assert( pOp->opcode==OP_RowKey ); | |
| 67722 | - rc = sqlite3VdbeSorterRowkey(u.bh.pC, pOut); | |
| 67723 | - break; | |
| 67724 | - } | |
| 67725 | - | |
| 67726 | - assert( u.bh.pC->pCursor!=0 ); | |
| 67727 | - u.bh.pCrsr = u.bh.pC->pCursor; | |
| 67728 | - assert( sqlite3BtreeCursorIsValid(u.bh.pCrsr) ); | |
| 67738 | + u.bk.pC = p->apCsr[pOp->p1]; | |
| 67739 | + assert( u.bk.pC->isSorter==0 ); | |
| 67740 | + assert( u.bk.pC->isTable || pOp->opcode!=OP_RowData ); | |
| 67741 | + assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); | |
| 67742 | + assert( u.bk.pC!=0 ); | |
| 67743 | + assert( u.bk.pC->nullRow==0 ); | |
| 67744 | + assert( u.bk.pC->pseudoTableReg==0 ); | |
| 67745 | + assert( !u.bk.pC->isSorter ); | |
| 67746 | + assert( u.bk.pC->pCursor!=0 ); | |
| 67747 | + u.bk.pCrsr = u.bk.pC->pCursor; | |
| 67748 | + assert( sqlite3BtreeCursorIsValid(u.bk.pCrsr) ); | |
| 67729 | 67749 | |
| 67730 | 67750 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 67731 | 67751 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 67732 | 67752 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 67733 | 67753 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 67734 | 67754 | */ |
| 67735 | - assert( u.bh.pC->deferredMoveto==0 ); | |
| 67736 | - rc = sqlite3VdbeCursorMoveto(u.bh.pC); | |
| 67737 | - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | |
| 67738 | - | |
| 67739 | - if( u.bh.pC->isIndex ){ | |
| 67740 | - assert( !u.bh.pC->isTable ); | |
| 67741 | - rc = sqlite3BtreeKeySize(u.bh.pCrsr, &u.bh.n64); | |
| 67742 | - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ | |
| 67743 | - if( u.bh.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | |
| 67744 | - goto too_big; | |
| 67745 | - } | |
| 67746 | - u.bh.n = (u32)u.bh.n64; | |
| 67747 | - }else{ | |
| 67748 | - rc = sqlite3BtreeDataSize(u.bh.pCrsr, &u.bh.n); | |
| 67749 | - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ | |
| 67750 | - if( u.bh.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ | |
| 67751 | - goto too_big; | |
| 67752 | - } | |
| 67753 | - } | |
| 67754 | - if( sqlite3VdbeMemGrow(pOut, u.bh.n, 0) ){ | |
| 67755 | - goto no_mem; | |
| 67756 | - } | |
| 67757 | - pOut->n = u.bh.n; | |
| 67758 | - MemSetTypeFlag(pOut, MEM_Blob); | |
| 67759 | - if( u.bh.pC->isIndex ){ | |
| 67760 | - rc = sqlite3BtreeKey(u.bh.pCrsr, 0, u.bh.n, pOut->z); | |
| 67761 | - }else{ | |
| 67762 | - rc = sqlite3BtreeData(u.bh.pCrsr, 0, u.bh.n, pOut->z); | |
| 67755 | + assert( u.bk.pC->deferredMoveto==0 ); | |
| 67756 | + rc = sqlite3VdbeCursorMoveto(u.bk.pC); | |
| 67757 | + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | |
| 67758 | + | |
| 67759 | + if( u.bk.pC->isIndex ){ | |
| 67760 | + assert( !u.bk.pC->isTable ); | |
| 67761 | + rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); | |
| 67762 | + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ | |
| 67763 | + if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ | |
| 67764 | + goto too_big; | |
| 67765 | + } | |
| 67766 | + u.bk.n = (u32)u.bk.n64; | |
| 67767 | + }else{ | |
| 67768 | + rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); | |
| 67769 | + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ | |
| 67770 | + if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ | |
| 67771 | + goto too_big; | |
| 67772 | + } | |
| 67773 | + } | |
| 67774 | + if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ | |
| 67775 | + goto no_mem; | |
| 67776 | + } | |
| 67777 | + pOut->n = u.bk.n; | |
| 67778 | + MemSetTypeFlag(pOut, MEM_Blob); | |
| 67779 | + if( u.bk.pC->isIndex ){ | |
| 67780 | + rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); | |
| 67781 | + }else{ | |
| 67782 | + rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); | |
| 67763 | 67783 | } |
| 67764 | 67784 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 67765 | 67785 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67766 | 67786 | break; |
| 67767 | 67787 | } |
| @@ -67774,46 +67794,46 @@ | ||
| 67774 | 67794 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 67775 | 67795 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 67776 | 67796 | ** one opcode now works for both table types. |
| 67777 | 67797 | */ |
| 67778 | 67798 | case OP_Rowid: { /* out2-prerelease */ |
| 67779 | -#if 0 /* local variables moved into u.bi */ | |
| 67799 | +#if 0 /* local variables moved into u.bl */ | |
| 67780 | 67800 | VdbeCursor *pC; |
| 67781 | 67801 | i64 v; |
| 67782 | 67802 | sqlite3_vtab *pVtab; |
| 67783 | 67803 | const sqlite3_module *pModule; |
| 67784 | -#endif /* local variables moved into u.bi */ | |
| 67804 | +#endif /* local variables moved into u.bl */ | |
| 67785 | 67805 | |
| 67786 | 67806 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67787 | - u.bi.pC = p->apCsr[pOp->p1]; | |
| 67788 | - assert( u.bi.pC!=0 ); | |
| 67789 | - assert( u.bi.pC->pseudoTableReg==0 ); | |
| 67790 | - if( u.bi.pC->nullRow ){ | |
| 67807 | + u.bl.pC = p->apCsr[pOp->p1]; | |
| 67808 | + assert( u.bl.pC!=0 ); | |
| 67809 | + assert( u.bl.pC->pseudoTableReg==0 ); | |
| 67810 | + if( u.bl.pC->nullRow ){ | |
| 67791 | 67811 | pOut->flags = MEM_Null; |
| 67792 | 67812 | break; |
| 67793 | - }else if( u.bi.pC->deferredMoveto ){ | |
| 67794 | - u.bi.v = u.bi.pC->movetoTarget; | |
| 67813 | + }else if( u.bl.pC->deferredMoveto ){ | |
| 67814 | + u.bl.v = u.bl.pC->movetoTarget; | |
| 67795 | 67815 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 67796 | - }else if( u.bi.pC->pVtabCursor ){ | |
| 67797 | - u.bi.pVtab = u.bi.pC->pVtabCursor->pVtab; | |
| 67798 | - u.bi.pModule = u.bi.pVtab->pModule; | |
| 67799 | - assert( u.bi.pModule->xRowid ); | |
| 67800 | - rc = u.bi.pModule->xRowid(u.bi.pC->pVtabCursor, &u.bi.v); | |
| 67801 | - importVtabErrMsg(p, u.bi.pVtab); | |
| 67816 | + }else if( u.bl.pC->pVtabCursor ){ | |
| 67817 | + u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; | |
| 67818 | + u.bl.pModule = u.bl.pVtab->pModule; | |
| 67819 | + assert( u.bl.pModule->xRowid ); | |
| 67820 | + rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); | |
| 67821 | + importVtabErrMsg(p, u.bl.pVtab); | |
| 67802 | 67822 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 67803 | 67823 | }else{ |
| 67804 | - assert( u.bi.pC->pCursor!=0 ); | |
| 67805 | - rc = sqlite3VdbeCursorMoveto(u.bi.pC); | |
| 67824 | + assert( u.bl.pC->pCursor!=0 ); | |
| 67825 | + rc = sqlite3VdbeCursorMoveto(u.bl.pC); | |
| 67806 | 67826 | if( rc ) goto abort_due_to_error; |
| 67807 | - if( u.bi.pC->rowidIsValid ){ | |
| 67808 | - u.bi.v = u.bi.pC->lastRowid; | |
| 67827 | + if( u.bl.pC->rowidIsValid ){ | |
| 67828 | + u.bl.v = u.bl.pC->lastRowid; | |
| 67809 | 67829 | }else{ |
| 67810 | - rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v); | |
| 67830 | + rc = sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); | |
| 67811 | 67831 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 67812 | 67832 | } |
| 67813 | 67833 | } |
| 67814 | - pOut->u.i = u.bi.v; | |
| 67834 | + pOut->u.i = u.bl.v; | |
| 67815 | 67835 | break; |
| 67816 | 67836 | } |
| 67817 | 67837 | |
| 67818 | 67838 | /* Opcode: NullRow P1 * * * * |
| 67819 | 67839 | ** |
| @@ -67820,22 +67840,22 @@ | ||
| 67820 | 67840 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 67821 | 67841 | ** that occur while the cursor is on the null row will always |
| 67822 | 67842 | ** write a NULL. |
| 67823 | 67843 | */ |
| 67824 | 67844 | case OP_NullRow: { |
| 67825 | -#if 0 /* local variables moved into u.bj */ | |
| 67845 | +#if 0 /* local variables moved into u.bm */ | |
| 67826 | 67846 | VdbeCursor *pC; |
| 67827 | -#endif /* local variables moved into u.bj */ | |
| 67847 | +#endif /* local variables moved into u.bm */ | |
| 67828 | 67848 | |
| 67829 | 67849 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67830 | - u.bj.pC = p->apCsr[pOp->p1]; | |
| 67831 | - assert( u.bj.pC!=0 ); | |
| 67832 | - u.bj.pC->nullRow = 1; | |
| 67833 | - u.bj.pC->rowidIsValid = 0; | |
| 67834 | - assert( u.bj.pC->pCursor || u.bj.pC->pVtabCursor ); | |
| 67835 | - if( u.bj.pC->pCursor ){ | |
| 67836 | - sqlite3BtreeClearCursor(u.bj.pC->pCursor); | |
| 67850 | + u.bm.pC = p->apCsr[pOp->p1]; | |
| 67851 | + assert( u.bm.pC!=0 ); | |
| 67852 | + u.bm.pC->nullRow = 1; | |
| 67853 | + u.bm.pC->rowidIsValid = 0; | |
| 67854 | + assert( u.bm.pC->pCursor || u.bm.pC->pVtabCursor ); | |
| 67855 | + if( u.bm.pC->pCursor ){ | |
| 67856 | + sqlite3BtreeClearCursor(u.bm.pC->pCursor); | |
| 67837 | 67857 | } |
| 67838 | 67858 | break; |
| 67839 | 67859 | } |
| 67840 | 67860 | |
| 67841 | 67861 | /* Opcode: Last P1 P2 * * * |
| @@ -67845,30 +67865,30 @@ | ||
| 67845 | 67865 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67846 | 67866 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67847 | 67867 | ** to the following instruction. |
| 67848 | 67868 | */ |
| 67849 | 67869 | case OP_Last: { /* jump */ |
| 67850 | -#if 0 /* local variables moved into u.bk */ | |
| 67870 | +#if 0 /* local variables moved into u.bn */ | |
| 67851 | 67871 | VdbeCursor *pC; |
| 67852 | 67872 | BtCursor *pCrsr; |
| 67853 | 67873 | int res; |
| 67854 | -#endif /* local variables moved into u.bk */ | |
| 67874 | +#endif /* local variables moved into u.bn */ | |
| 67855 | 67875 | |
| 67856 | 67876 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67857 | - u.bk.pC = p->apCsr[pOp->p1]; | |
| 67858 | - assert( u.bk.pC!=0 ); | |
| 67859 | - u.bk.pCrsr = u.bk.pC->pCursor; | |
| 67860 | - if( NEVER(u.bk.pCrsr==0) ){ | |
| 67861 | - u.bk.res = 1; | |
| 67877 | + u.bn.pC = p->apCsr[pOp->p1]; | |
| 67878 | + assert( u.bn.pC!=0 ); | |
| 67879 | + u.bn.pCrsr = u.bn.pC->pCursor; | |
| 67880 | + if( NEVER(u.bn.pCrsr==0) ){ | |
| 67881 | + u.bn.res = 1; | |
| 67862 | 67882 | }else{ |
| 67863 | - rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res); | |
| 67883 | + rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); | |
| 67864 | 67884 | } |
| 67865 | - u.bk.pC->nullRow = (u8)u.bk.res; | |
| 67866 | - u.bk.pC->deferredMoveto = 0; | |
| 67867 | - u.bk.pC->rowidIsValid = 0; | |
| 67868 | - u.bk.pC->cacheStatus = CACHE_STALE; | |
| 67869 | - if( pOp->p2>0 && u.bk.res ){ | |
| 67885 | + u.bn.pC->nullRow = (u8)u.bn.res; | |
| 67886 | + u.bn.pC->deferredMoveto = 0; | |
| 67887 | + u.bn.pC->rowidIsValid = 0; | |
| 67888 | + u.bn.pC->cacheStatus = CACHE_STALE; | |
| 67889 | + if( pOp->p2>0 && u.bn.res ){ | |
| 67870 | 67890 | pc = pOp->p2 - 1; |
| 67871 | 67891 | } |
| 67872 | 67892 | break; |
| 67873 | 67893 | } |
| 67874 | 67894 | |
| @@ -67883,10 +67903,14 @@ | ||
| 67883 | 67903 | ** end. We use the OP_Sort opcode instead of OP_Rewind to do the |
| 67884 | 67904 | ** rewinding so that the global variable will be incremented and |
| 67885 | 67905 | ** regression tests can determine whether or not the optimizer is |
| 67886 | 67906 | ** correctly optimizing out sorts. |
| 67887 | 67907 | */ |
| 67908 | +case OP_SorterSort: /* jump */ | |
| 67909 | +#ifdef SQLITE_OMIT_MERGE_SORT | |
| 67910 | + pOp->opcode = OP_Sort; | |
| 67911 | +#endif | |
| 67888 | 67912 | case OP_Sort: { /* jump */ |
| 67889 | 67913 | #ifdef SQLITE_TEST |
| 67890 | 67914 | sqlite3_sort_count++; |
| 67891 | 67915 | sqlite3_search_count--; |
| 67892 | 67916 | #endif |
| @@ -67900,34 +67924,35 @@ | ||
| 67900 | 67924 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67901 | 67925 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67902 | 67926 | ** to the following instruction. |
| 67903 | 67927 | */ |
| 67904 | 67928 | case OP_Rewind: { /* jump */ |
| 67905 | -#if 0 /* local variables moved into u.bl */ | |
| 67929 | +#if 0 /* local variables moved into u.bo */ | |
| 67906 | 67930 | VdbeCursor *pC; |
| 67907 | 67931 | BtCursor *pCrsr; |
| 67908 | 67932 | int res; |
| 67909 | -#endif /* local variables moved into u.bl */ | |
| 67933 | +#endif /* local variables moved into u.bo */ | |
| 67910 | 67934 | |
| 67911 | 67935 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67912 | - u.bl.pC = p->apCsr[pOp->p1]; | |
| 67913 | - assert( u.bl.pC!=0 ); | |
| 67914 | - u.bl.res = 1; | |
| 67915 | - if( isSorter(u.bl.pC) ){ | |
| 67916 | - rc = sqlite3VdbeSorterRewind(db, u.bl.pC, &u.bl.res); | |
| 67936 | + u.bo.pC = p->apCsr[pOp->p1]; | |
| 67937 | + assert( u.bo.pC!=0 ); | |
| 67938 | + assert( u.bo.pC->isSorter==(pOp->opcode==OP_SorterSort) ); | |
| 67939 | + u.bo.res = 1; | |
| 67940 | + if( isSorter(u.bo.pC) ){ | |
| 67941 | + rc = sqlite3VdbeSorterRewind(db, u.bo.pC, &u.bo.res); | |
| 67917 | 67942 | }else{ |
| 67918 | - u.bl.pCrsr = u.bl.pC->pCursor; | |
| 67919 | - assert( u.bl.pCrsr ); | |
| 67920 | - rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); | |
| 67921 | - u.bl.pC->atFirst = u.bl.res==0 ?1:0; | |
| 67922 | - u.bl.pC->deferredMoveto = 0; | |
| 67923 | - u.bl.pC->cacheStatus = CACHE_STALE; | |
| 67924 | - u.bl.pC->rowidIsValid = 0; | |
| 67925 | - } | |
| 67926 | - u.bl.pC->nullRow = (u8)u.bl.res; | |
| 67943 | + u.bo.pCrsr = u.bo.pC->pCursor; | |
| 67944 | + assert( u.bo.pCrsr ); | |
| 67945 | + rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); | |
| 67946 | + u.bo.pC->atFirst = u.bo.res==0 ?1:0; | |
| 67947 | + u.bo.pC->deferredMoveto = 0; | |
| 67948 | + u.bo.pC->cacheStatus = CACHE_STALE; | |
| 67949 | + u.bo.pC->rowidIsValid = 0; | |
| 67950 | + } | |
| 67951 | + u.bo.pC->nullRow = (u8)u.bo.res; | |
| 67927 | 67952 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 67928 | - if( u.bl.res ){ | |
| 67953 | + if( u.bo.res ){ | |
| 67929 | 67954 | pc = pOp->p2 - 1; |
| 67930 | 67955 | } |
| 67931 | 67956 | break; |
| 67932 | 67957 | } |
| 67933 | 67958 | |
| @@ -67961,45 +67986,50 @@ | ||
| 67961 | 67986 | ** sqlite3BtreePrevious(). |
| 67962 | 67987 | ** |
| 67963 | 67988 | ** If P5 is positive and the jump is taken, then event counter |
| 67964 | 67989 | ** number P5-1 in the prepared statement is incremented. |
| 67965 | 67990 | */ |
| 67991 | +case OP_SorterNext: /* jump */ | |
| 67992 | +#ifdef SQLITE_OMIT_MERGE_SORT | |
| 67993 | + pOp->opcode = OP_Next; | |
| 67994 | +#endif | |
| 67966 | 67995 | case OP_Prev: /* jump */ |
| 67967 | 67996 | case OP_Next: { /* jump */ |
| 67968 | -#if 0 /* local variables moved into u.bm */ | |
| 67997 | +#if 0 /* local variables moved into u.bp */ | |
| 67969 | 67998 | VdbeCursor *pC; |
| 67970 | 67999 | int res; |
| 67971 | -#endif /* local variables moved into u.bm */ | |
| 68000 | +#endif /* local variables moved into u.bp */ | |
| 67972 | 68001 | |
| 67973 | 68002 | CHECK_FOR_INTERRUPT; |
| 67974 | 68003 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67975 | 68004 | assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 67976 | - u.bm.pC = p->apCsr[pOp->p1]; | |
| 67977 | - if( u.bm.pC==0 ){ | |
| 68005 | + u.bp.pC = p->apCsr[pOp->p1]; | |
| 68006 | + if( u.bp.pC==0 ){ | |
| 67978 | 68007 | break; /* See ticket #2273 */ |
| 67979 | 68008 | } |
| 67980 | - if( isSorter(u.bm.pC) ){ | |
| 67981 | - assert( pOp->opcode==OP_Next ); | |
| 67982 | - rc = sqlite3VdbeSorterNext(db, u.bm.pC, &u.bm.res); | |
| 68009 | + assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterNext) ); | |
| 68010 | + if( isSorter(u.bp.pC) ){ | |
| 68011 | + assert( pOp->opcode==OP_SorterNext ); | |
| 68012 | + rc = sqlite3VdbeSorterNext(db, u.bp.pC, &u.bp.res); | |
| 67983 | 68013 | }else{ |
| 67984 | - u.bm.res = 1; | |
| 67985 | - assert( u.bm.pC->deferredMoveto==0 ); | |
| 67986 | - assert( u.bm.pC->pCursor ); | |
| 68014 | + u.bp.res = 1; | |
| 68015 | + assert( u.bp.pC->deferredMoveto==0 ); | |
| 68016 | + assert( u.bp.pC->pCursor ); | |
| 67987 | 68017 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 67988 | 68018 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 67989 | - rc = pOp->p4.xAdvance(u.bm.pC->pCursor, &u.bm.res); | |
| 68019 | + rc = pOp->p4.xAdvance(u.bp.pC->pCursor, &u.bp.res); | |
| 67990 | 68020 | } |
| 67991 | - u.bm.pC->nullRow = (u8)u.bm.res; | |
| 67992 | - u.bm.pC->cacheStatus = CACHE_STALE; | |
| 67993 | - if( u.bm.res==0 ){ | |
| 68021 | + u.bp.pC->nullRow = (u8)u.bp.res; | |
| 68022 | + u.bp.pC->cacheStatus = CACHE_STALE; | |
| 68023 | + if( u.bp.res==0 ){ | |
| 67994 | 68024 | pc = pOp->p2 - 1; |
| 67995 | 68025 | if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 67996 | 68026 | #ifdef SQLITE_TEST |
| 67997 | 68027 | sqlite3_search_count++; |
| 67998 | 68028 | #endif |
| 67999 | 68029 | } |
| 68000 | - u.bm.pC->rowidIsValid = 0; | |
| 68030 | + u.bp.pC->rowidIsValid = 0; | |
| 68001 | 68031 | break; |
| 68002 | 68032 | } |
| 68003 | 68033 | |
| 68004 | 68034 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 68005 | 68035 | ** |
| @@ -68011,38 +68041,44 @@ | ||
| 68011 | 68041 | ** insert is likely to be an append. |
| 68012 | 68042 | ** |
| 68013 | 68043 | ** This instruction only works for indices. The equivalent instruction |
| 68014 | 68044 | ** for tables is OP_Insert. |
| 68015 | 68045 | */ |
| 68046 | +case OP_SorterInsert: /* in2 */ | |
| 68047 | +#ifdef SQLITE_OMIT_MERGE_SORT | |
| 68048 | + pOp->opcode = OP_IdxInsert; | |
| 68049 | +#endif | |
| 68016 | 68050 | case OP_IdxInsert: { /* in2 */ |
| 68017 | -#if 0 /* local variables moved into u.bn */ | |
| 68051 | +#if 0 /* local variables moved into u.bq */ | |
| 68018 | 68052 | VdbeCursor *pC; |
| 68019 | 68053 | BtCursor *pCrsr; |
| 68020 | 68054 | int nKey; |
| 68021 | 68055 | const char *zKey; |
| 68022 | -#endif /* local variables moved into u.bn */ | |
| 68056 | +#endif /* local variables moved into u.bq */ | |
| 68023 | 68057 | |
| 68024 | 68058 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68025 | - u.bn.pC = p->apCsr[pOp->p1]; | |
| 68026 | - assert( u.bn.pC!=0 ); | |
| 68059 | + u.bq.pC = p->apCsr[pOp->p1]; | |
| 68060 | + assert( u.bq.pC!=0 ); | |
| 68061 | + assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); | |
| 68027 | 68062 | pIn2 = &aMem[pOp->p2]; |
| 68028 | 68063 | assert( pIn2->flags & MEM_Blob ); |
| 68029 | - u.bn.pCrsr = u.bn.pC->pCursor; | |
| 68030 | - if( ALWAYS(u.bn.pCrsr!=0) ){ | |
| 68031 | - assert( u.bn.pC->isTable==0 ); | |
| 68064 | + u.bq.pCrsr = u.bq.pC->pCursor; | |
| 68065 | + if( ALWAYS(u.bq.pCrsr!=0) ){ | |
| 68066 | + assert( u.bq.pC->isTable==0 ); | |
| 68032 | 68067 | rc = ExpandBlob(pIn2); |
| 68033 | 68068 | if( rc==SQLITE_OK ){ |
| 68034 | - u.bn.nKey = pIn2->n; | |
| 68035 | - u.bn.zKey = pIn2->z; | |
| 68036 | - rc = sqlite3VdbeSorterWrite(db, u.bn.pC, u.bn.nKey); | |
| 68037 | - if( rc==SQLITE_OK ){ | |
| 68038 | - rc = sqlite3BtreeInsert(u.bn.pCrsr, u.bn.zKey, u.bn.nKey, "", 0, 0, pOp->p3, | |
| 68039 | - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bn.pC->seekResult : 0) | |
| 68040 | - ); | |
| 68041 | - assert( u.bn.pC->deferredMoveto==0 ); | |
| 68042 | - } | |
| 68043 | - u.bn.pC->cacheStatus = CACHE_STALE; | |
| 68069 | + if( isSorter(u.bq.pC) ){ | |
| 68070 | + rc = sqlite3VdbeSorterWrite(db, u.bq.pC, pIn2); | |
| 68071 | + }else{ | |
| 68072 | + u.bq.nKey = pIn2->n; | |
| 68073 | + u.bq.zKey = pIn2->z; | |
| 68074 | + rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, | |
| 68075 | + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) | |
| 68076 | + ); | |
| 68077 | + assert( u.bq.pC->deferredMoveto==0 ); | |
| 68078 | + u.bq.pC->cacheStatus = CACHE_STALE; | |
| 68079 | + } | |
| 68044 | 68080 | } |
| 68045 | 68081 | } |
| 68046 | 68082 | break; |
| 68047 | 68083 | } |
| 68048 | 68084 | |
| @@ -68051,37 +68087,37 @@ | ||
| 68051 | 68087 | ** The content of P3 registers starting at register P2 form |
| 68052 | 68088 | ** an unpacked index key. This opcode removes that entry from the |
| 68053 | 68089 | ** index opened by cursor P1. |
| 68054 | 68090 | */ |
| 68055 | 68091 | case OP_IdxDelete: { |
| 68056 | -#if 0 /* local variables moved into u.bo */ | |
| 68092 | +#if 0 /* local variables moved into u.br */ | |
| 68057 | 68093 | VdbeCursor *pC; |
| 68058 | 68094 | BtCursor *pCrsr; |
| 68059 | 68095 | int res; |
| 68060 | 68096 | UnpackedRecord r; |
| 68061 | -#endif /* local variables moved into u.bo */ | |
| 68097 | +#endif /* local variables moved into u.br */ | |
| 68062 | 68098 | |
| 68063 | 68099 | assert( pOp->p3>0 ); |
| 68064 | 68100 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 68065 | 68101 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68066 | - u.bo.pC = p->apCsr[pOp->p1]; | |
| 68067 | - assert( u.bo.pC!=0 ); | |
| 68068 | - u.bo.pCrsr = u.bo.pC->pCursor; | |
| 68069 | - if( ALWAYS(u.bo.pCrsr!=0) ){ | |
| 68070 | - u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo; | |
| 68071 | - u.bo.r.nField = (u16)pOp->p3; | |
| 68072 | - u.bo.r.flags = 0; | |
| 68073 | - u.bo.r.aMem = &aMem[pOp->p2]; | |
| 68102 | + u.br.pC = p->apCsr[pOp->p1]; | |
| 68103 | + assert( u.br.pC!=0 ); | |
| 68104 | + u.br.pCrsr = u.br.pC->pCursor; | |
| 68105 | + if( ALWAYS(u.br.pCrsr!=0) ){ | |
| 68106 | + u.br.r.pKeyInfo = u.br.pC->pKeyInfo; | |
| 68107 | + u.br.r.nField = (u16)pOp->p3; | |
| 68108 | + u.br.r.flags = 0; | |
| 68109 | + u.br.r.aMem = &aMem[pOp->p2]; | |
| 68074 | 68110 | #ifdef SQLITE_DEBUG |
| 68075 | - { int i; for(i=0; i<u.bo.r.nField; i++) assert( memIsValid(&u.bo.r.aMem[i]) ); } | |
| 68111 | + { int i; for(i=0; i<u.br.r.nField; i++) assert( memIsValid(&u.br.r.aMem[i]) ); } | |
| 68076 | 68112 | #endif |
| 68077 | - rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res); | |
| 68078 | - if( rc==SQLITE_OK && u.bo.res==0 ){ | |
| 68079 | - rc = sqlite3BtreeDelete(u.bo.pCrsr); | |
| 68113 | + rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &u.br.r, 0, 0, &u.br.res); | |
| 68114 | + if( rc==SQLITE_OK && u.br.res==0 ){ | |
| 68115 | + rc = sqlite3BtreeDelete(u.br.pCrsr); | |
| 68080 | 68116 | } |
| 68081 | - assert( u.bo.pC->deferredMoveto==0 ); | |
| 68082 | - u.bo.pC->cacheStatus = CACHE_STALE; | |
| 68117 | + assert( u.br.pC->deferredMoveto==0 ); | |
| 68118 | + u.br.pC->cacheStatus = CACHE_STALE; | |
| 68083 | 68119 | } |
| 68084 | 68120 | break; |
| 68085 | 68121 | } |
| 68086 | 68122 | |
| 68087 | 68123 | /* Opcode: IdxRowid P1 P2 * * * |
| @@ -68091,32 +68127,32 @@ | ||
| 68091 | 68127 | ** the rowid of the table entry to which this index entry points. |
| 68092 | 68128 | ** |
| 68093 | 68129 | ** See also: Rowid, MakeRecord. |
| 68094 | 68130 | */ |
| 68095 | 68131 | case OP_IdxRowid: { /* out2-prerelease */ |
| 68096 | -#if 0 /* local variables moved into u.bp */ | |
| 68132 | +#if 0 /* local variables moved into u.bs */ | |
| 68097 | 68133 | BtCursor *pCrsr; |
| 68098 | 68134 | VdbeCursor *pC; |
| 68099 | 68135 | i64 rowid; |
| 68100 | -#endif /* local variables moved into u.bp */ | |
| 68136 | +#endif /* local variables moved into u.bs */ | |
| 68101 | 68137 | |
| 68102 | 68138 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68103 | - u.bp.pC = p->apCsr[pOp->p1]; | |
| 68104 | - assert( u.bp.pC!=0 ); | |
| 68105 | - u.bp.pCrsr = u.bp.pC->pCursor; | |
| 68139 | + u.bs.pC = p->apCsr[pOp->p1]; | |
| 68140 | + assert( u.bs.pC!=0 ); | |
| 68141 | + u.bs.pCrsr = u.bs.pC->pCursor; | |
| 68106 | 68142 | pOut->flags = MEM_Null; |
| 68107 | - if( ALWAYS(u.bp.pCrsr!=0) ){ | |
| 68108 | - rc = sqlite3VdbeCursorMoveto(u.bp.pC); | |
| 68143 | + if( ALWAYS(u.bs.pCrsr!=0) ){ | |
| 68144 | + rc = sqlite3VdbeCursorMoveto(u.bs.pC); | |
| 68109 | 68145 | if( NEVER(rc) ) goto abort_due_to_error; |
| 68110 | - assert( u.bp.pC->deferredMoveto==0 ); | |
| 68111 | - assert( u.bp.pC->isTable==0 ); | |
| 68112 | - if( !u.bp.pC->nullRow ){ | |
| 68113 | - rc = sqlite3VdbeIdxRowid(db, u.bp.pCrsr, &u.bp.rowid); | |
| 68146 | + assert( u.bs.pC->deferredMoveto==0 ); | |
| 68147 | + assert( u.bs.pC->isTable==0 ); | |
| 68148 | + if( !u.bs.pC->nullRow ){ | |
| 68149 | + rc = sqlite3VdbeIdxRowid(db, u.bs.pCrsr, &u.bs.rowid); | |
| 68114 | 68150 | if( rc!=SQLITE_OK ){ |
| 68115 | 68151 | goto abort_due_to_error; |
| 68116 | 68152 | } |
| 68117 | - pOut->u.i = u.bp.rowid; | |
| 68153 | + pOut->u.i = u.bs.rowid; | |
| 68118 | 68154 | pOut->flags = MEM_Int; |
| 68119 | 68155 | } |
| 68120 | 68156 | } |
| 68121 | 68157 | break; |
| 68122 | 68158 | } |
| @@ -68147,43 +68183,43 @@ | ||
| 68147 | 68183 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 68148 | 68184 | ** to the comparison. This makes the opcode work like IdxLE. |
| 68149 | 68185 | */ |
| 68150 | 68186 | case OP_IdxLT: /* jump */ |
| 68151 | 68187 | case OP_IdxGE: { /* jump */ |
| 68152 | -#if 0 /* local variables moved into u.bq */ | |
| 68188 | +#if 0 /* local variables moved into u.bt */ | |
| 68153 | 68189 | VdbeCursor *pC; |
| 68154 | 68190 | int res; |
| 68155 | 68191 | UnpackedRecord r; |
| 68156 | -#endif /* local variables moved into u.bq */ | |
| 68192 | +#endif /* local variables moved into u.bt */ | |
| 68157 | 68193 | |
| 68158 | 68194 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68159 | - u.bq.pC = p->apCsr[pOp->p1]; | |
| 68160 | - assert( u.bq.pC!=0 ); | |
| 68161 | - assert( u.bq.pC->isOrdered ); | |
| 68162 | - if( ALWAYS(u.bq.pC->pCursor!=0) ){ | |
| 68163 | - assert( u.bq.pC->deferredMoveto==0 ); | |
| 68195 | + u.bt.pC = p->apCsr[pOp->p1]; | |
| 68196 | + assert( u.bt.pC!=0 ); | |
| 68197 | + assert( u.bt.pC->isOrdered ); | |
| 68198 | + if( ALWAYS(u.bt.pC->pCursor!=0) ){ | |
| 68199 | + assert( u.bt.pC->deferredMoveto==0 ); | |
| 68164 | 68200 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 68165 | 68201 | assert( pOp->p4type==P4_INT32 ); |
| 68166 | - u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo; | |
| 68167 | - u.bq.r.nField = (u16)pOp->p4.i; | |
| 68202 | + u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; | |
| 68203 | + u.bt.r.nField = (u16)pOp->p4.i; | |
| 68168 | 68204 | if( pOp->p5 ){ |
| 68169 | - u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; | |
| 68205 | + u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; | |
| 68170 | 68206 | }else{ |
| 68171 | - u.bq.r.flags = UNPACKED_IGNORE_ROWID; | |
| 68207 | + u.bt.r.flags = UNPACKED_IGNORE_ROWID; | |
| 68172 | 68208 | } |
| 68173 | - u.bq.r.aMem = &aMem[pOp->p3]; | |
| 68209 | + u.bt.r.aMem = &aMem[pOp->p3]; | |
| 68174 | 68210 | #ifdef SQLITE_DEBUG |
| 68175 | - { int i; for(i=0; i<u.bq.r.nField; i++) assert( memIsValid(&u.bq.r.aMem[i]) ); } | |
| 68211 | + { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } | |
| 68176 | 68212 | #endif |
| 68177 | - rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res); | |
| 68213 | + rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); | |
| 68178 | 68214 | if( pOp->opcode==OP_IdxLT ){ |
| 68179 | - u.bq.res = -u.bq.res; | |
| 68215 | + u.bt.res = -u.bt.res; | |
| 68180 | 68216 | }else{ |
| 68181 | 68217 | assert( pOp->opcode==OP_IdxGE ); |
| 68182 | - u.bq.res++; | |
| 68218 | + u.bt.res++; | |
| 68183 | 68219 | } |
| 68184 | - if( u.bq.res>0 ){ | |
| 68220 | + if( u.bt.res>0 ){ | |
| 68185 | 68221 | pc = pOp->p2 - 1 ; |
| 68186 | 68222 | } |
| 68187 | 68223 | } |
| 68188 | 68224 | break; |
| 68189 | 68225 | } |
| @@ -68207,43 +68243,43 @@ | ||
| 68207 | 68243 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 68208 | 68244 | ** |
| 68209 | 68245 | ** See also: Clear |
| 68210 | 68246 | */ |
| 68211 | 68247 | case OP_Destroy: { /* out2-prerelease */ |
| 68212 | -#if 0 /* local variables moved into u.br */ | |
| 68248 | +#if 0 /* local variables moved into u.bu */ | |
| 68213 | 68249 | int iMoved; |
| 68214 | 68250 | int iCnt; |
| 68215 | 68251 | Vdbe *pVdbe; |
| 68216 | 68252 | int iDb; |
| 68217 | -#endif /* local variables moved into u.br */ | |
| 68253 | +#endif /* local variables moved into u.bu */ | |
| 68218 | 68254 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 68219 | - u.br.iCnt = 0; | |
| 68220 | - for(u.br.pVdbe=db->pVdbe; u.br.pVdbe; u.br.pVdbe = u.br.pVdbe->pNext){ | |
| 68221 | - if( u.br.pVdbe->magic==VDBE_MAGIC_RUN && u.br.pVdbe->inVtabMethod<2 && u.br.pVdbe->pc>=0 ){ | |
| 68222 | - u.br.iCnt++; | |
| 68255 | + u.bu.iCnt = 0; | |
| 68256 | + for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ | |
| 68257 | + if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ | |
| 68258 | + u.bu.iCnt++; | |
| 68223 | 68259 | } |
| 68224 | 68260 | } |
| 68225 | 68261 | #else |
| 68226 | - u.br.iCnt = db->activeVdbeCnt; | |
| 68262 | + u.bu.iCnt = db->activeVdbeCnt; | |
| 68227 | 68263 | #endif |
| 68228 | 68264 | pOut->flags = MEM_Null; |
| 68229 | - if( u.br.iCnt>1 ){ | |
| 68265 | + if( u.bu.iCnt>1 ){ | |
| 68230 | 68266 | rc = SQLITE_LOCKED; |
| 68231 | 68267 | p->errorAction = OE_Abort; |
| 68232 | 68268 | }else{ |
| 68233 | - u.br.iDb = pOp->p3; | |
| 68234 | - assert( u.br.iCnt==1 ); | |
| 68235 | - assert( (p->btreeMask & (((yDbMask)1)<<u.br.iDb))!=0 ); | |
| 68236 | - rc = sqlite3BtreeDropTable(db->aDb[u.br.iDb].pBt, pOp->p1, &u.br.iMoved); | |
| 68269 | + u.bu.iDb = pOp->p3; | |
| 68270 | + assert( u.bu.iCnt==1 ); | |
| 68271 | + assert( (p->btreeMask & (((yDbMask)1)<<u.bu.iDb))!=0 ); | |
| 68272 | + rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); | |
| 68237 | 68273 | pOut->flags = MEM_Int; |
| 68238 | - pOut->u.i = u.br.iMoved; | |
| 68274 | + pOut->u.i = u.bu.iMoved; | |
| 68239 | 68275 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 68240 | - if( rc==SQLITE_OK && u.br.iMoved!=0 ){ | |
| 68241 | - sqlite3RootPageMoved(db, u.br.iDb, u.br.iMoved, pOp->p1); | |
| 68276 | + if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ | |
| 68277 | + sqlite3RootPageMoved(db, u.bu.iDb, u.bu.iMoved, pOp->p1); | |
| 68242 | 68278 | /* All OP_Destroy operations occur on the same btree */ |
| 68243 | - assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.br.iDb+1 ); | |
| 68244 | - resetSchemaOnFault = u.br.iDb+1; | |
| 68279 | + assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bu.iDb+1 ); | |
| 68280 | + resetSchemaOnFault = u.bu.iDb+1; | |
| 68245 | 68281 | } |
| 68246 | 68282 | #endif |
| 68247 | 68283 | } |
| 68248 | 68284 | break; |
| 68249 | 68285 | } |
| @@ -68265,25 +68301,25 @@ | ||
| 68265 | 68301 | ** also incremented by the number of rows in the table being cleared. |
| 68266 | 68302 | ** |
| 68267 | 68303 | ** See also: Destroy |
| 68268 | 68304 | */ |
| 68269 | 68305 | case OP_Clear: { |
| 68270 | -#if 0 /* local variables moved into u.bs */ | |
| 68306 | +#if 0 /* local variables moved into u.bv */ | |
| 68271 | 68307 | int nChange; |
| 68272 | -#endif /* local variables moved into u.bs */ | |
| 68308 | +#endif /* local variables moved into u.bv */ | |
| 68273 | 68309 | |
| 68274 | - u.bs.nChange = 0; | |
| 68310 | + u.bv.nChange = 0; | |
| 68275 | 68311 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 68276 | 68312 | rc = sqlite3BtreeClearTable( |
| 68277 | - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0) | |
| 68313 | + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) | |
| 68278 | 68314 | ); |
| 68279 | 68315 | if( pOp->p3 ){ |
| 68280 | - p->nChange += u.bs.nChange; | |
| 68316 | + p->nChange += u.bv.nChange; | |
| 68281 | 68317 | if( pOp->p3>0 ){ |
| 68282 | 68318 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 68283 | 68319 | memAboutToChange(p, &aMem[pOp->p3]); |
| 68284 | - aMem[pOp->p3].u.i += u.bs.nChange; | |
| 68320 | + aMem[pOp->p3].u.i += u.bv.nChange; | |
| 68285 | 68321 | } |
| 68286 | 68322 | } |
| 68287 | 68323 | break; |
| 68288 | 68324 | } |
| 68289 | 68325 | |
| @@ -68309,29 +68345,29 @@ | ||
| 68309 | 68345 | ** |
| 68310 | 68346 | ** See documentation on OP_CreateTable for additional information. |
| 68311 | 68347 | */ |
| 68312 | 68348 | case OP_CreateIndex: /* out2-prerelease */ |
| 68313 | 68349 | case OP_CreateTable: { /* out2-prerelease */ |
| 68314 | -#if 0 /* local variables moved into u.bt */ | |
| 68350 | +#if 0 /* local variables moved into u.bw */ | |
| 68315 | 68351 | int pgno; |
| 68316 | 68352 | int flags; |
| 68317 | 68353 | Db *pDb; |
| 68318 | -#endif /* local variables moved into u.bt */ | |
| 68354 | +#endif /* local variables moved into u.bw */ | |
| 68319 | 68355 | |
| 68320 | - u.bt.pgno = 0; | |
| 68356 | + u.bw.pgno = 0; | |
| 68321 | 68357 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68322 | 68358 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68323 | - u.bt.pDb = &db->aDb[pOp->p1]; | |
| 68324 | - assert( u.bt.pDb->pBt!=0 ); | |
| 68359 | + u.bw.pDb = &db->aDb[pOp->p1]; | |
| 68360 | + assert( u.bw.pDb->pBt!=0 ); | |
| 68325 | 68361 | if( pOp->opcode==OP_CreateTable ){ |
| 68326 | - /* u.bt.flags = BTREE_INTKEY; */ | |
| 68327 | - u.bt.flags = BTREE_INTKEY; | |
| 68362 | + /* u.bw.flags = BTREE_INTKEY; */ | |
| 68363 | + u.bw.flags = BTREE_INTKEY; | |
| 68328 | 68364 | }else{ |
| 68329 | - u.bt.flags = BTREE_BLOBKEY; | |
| 68365 | + u.bw.flags = BTREE_BLOBKEY; | |
| 68330 | 68366 | } |
| 68331 | - rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); | |
| 68332 | - pOut->u.i = u.bt.pgno; | |
| 68367 | + rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); | |
| 68368 | + pOut->u.i = u.bw.pgno; | |
| 68333 | 68369 | break; |
| 68334 | 68370 | } |
| 68335 | 68371 | |
| 68336 | 68372 | /* Opcode: ParseSchema P1 * * P4 * |
| 68337 | 68373 | ** |
| @@ -68340,48 +68376,48 @@ | ||
| 68340 | 68376 | ** |
| 68341 | 68377 | ** This opcode invokes the parser to create a new virtual machine, |
| 68342 | 68378 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 68343 | 68379 | */ |
| 68344 | 68380 | case OP_ParseSchema: { |
| 68345 | -#if 0 /* local variables moved into u.bu */ | |
| 68381 | +#if 0 /* local variables moved into u.bx */ | |
| 68346 | 68382 | int iDb; |
| 68347 | 68383 | const char *zMaster; |
| 68348 | 68384 | char *zSql; |
| 68349 | 68385 | InitData initData; |
| 68350 | -#endif /* local variables moved into u.bu */ | |
| 68386 | +#endif /* local variables moved into u.bx */ | |
| 68351 | 68387 | |
| 68352 | 68388 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 68353 | 68389 | ** on every btree. This is a prerequisite for invoking |
| 68354 | 68390 | ** sqlite3InitCallback(). |
| 68355 | 68391 | */ |
| 68356 | 68392 | #ifdef SQLITE_DEBUG |
| 68357 | - for(u.bu.iDb=0; u.bu.iDb<db->nDb; u.bu.iDb++){ | |
| 68358 | - assert( u.bu.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) ); | |
| 68393 | + for(u.bx.iDb=0; u.bx.iDb<db->nDb; u.bx.iDb++){ | |
| 68394 | + assert( u.bx.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); | |
| 68359 | 68395 | } |
| 68360 | 68396 | #endif |
| 68361 | 68397 | |
| 68362 | - u.bu.iDb = pOp->p1; | |
| 68363 | - assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb ); | |
| 68364 | - assert( DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ); | |
| 68398 | + u.bx.iDb = pOp->p1; | |
| 68399 | + assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); | |
| 68400 | + assert( DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ); | |
| 68365 | 68401 | /* Used to be a conditional */ { |
| 68366 | - u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb); | |
| 68367 | - u.bu.initData.db = db; | |
| 68368 | - u.bu.initData.iDb = pOp->p1; | |
| 68369 | - u.bu.initData.pzErrMsg = &p->zErrMsg; | |
| 68370 | - u.bu.zSql = sqlite3MPrintf(db, | |
| 68402 | + u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); | |
| 68403 | + u.bx.initData.db = db; | |
| 68404 | + u.bx.initData.iDb = pOp->p1; | |
| 68405 | + u.bx.initData.pzErrMsg = &p->zErrMsg; | |
| 68406 | + u.bx.zSql = sqlite3MPrintf(db, | |
| 68371 | 68407 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| 68372 | - db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z); | |
| 68373 | - if( u.bu.zSql==0 ){ | |
| 68408 | + db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); | |
| 68409 | + if( u.bx.zSql==0 ){ | |
| 68374 | 68410 | rc = SQLITE_NOMEM; |
| 68375 | 68411 | }else{ |
| 68376 | 68412 | assert( db->init.busy==0 ); |
| 68377 | 68413 | db->init.busy = 1; |
| 68378 | - u.bu.initData.rc = SQLITE_OK; | |
| 68414 | + u.bx.initData.rc = SQLITE_OK; | |
| 68379 | 68415 | assert( !db->mallocFailed ); |
| 68380 | - rc = sqlite3_exec(db, u.bu.zSql, sqlite3InitCallback, &u.bu.initData, 0); | |
| 68381 | - if( rc==SQLITE_OK ) rc = u.bu.initData.rc; | |
| 68382 | - sqlite3DbFree(db, u.bu.zSql); | |
| 68416 | + rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); | |
| 68417 | + if( rc==SQLITE_OK ) rc = u.bx.initData.rc; | |
| 68418 | + sqlite3DbFree(db, u.bx.zSql); | |
| 68383 | 68419 | db->init.busy = 0; |
| 68384 | 68420 | } |
| 68385 | 68421 | } |
| 68386 | 68422 | if( rc==SQLITE_NOMEM ){ |
| 68387 | 68423 | goto no_mem; |
| @@ -68460,45 +68496,45 @@ | ||
| 68460 | 68496 | ** file, not the main database file. |
| 68461 | 68497 | ** |
| 68462 | 68498 | ** This opcode is used to implement the integrity_check pragma. |
| 68463 | 68499 | */ |
| 68464 | 68500 | case OP_IntegrityCk: { |
| 68465 | -#if 0 /* local variables moved into u.bv */ | |
| 68501 | +#if 0 /* local variables moved into u.by */ | |
| 68466 | 68502 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 68467 | 68503 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 68468 | 68504 | int j; /* Loop counter */ |
| 68469 | 68505 | int nErr; /* Number of errors reported */ |
| 68470 | 68506 | char *z; /* Text of the error report */ |
| 68471 | 68507 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 68472 | -#endif /* local variables moved into u.bv */ | |
| 68508 | +#endif /* local variables moved into u.by */ | |
| 68473 | 68509 | |
| 68474 | - u.bv.nRoot = pOp->p2; | |
| 68475 | - assert( u.bv.nRoot>0 ); | |
| 68476 | - u.bv.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bv.nRoot+1) ); | |
| 68477 | - if( u.bv.aRoot==0 ) goto no_mem; | |
| 68510 | + u.by.nRoot = pOp->p2; | |
| 68511 | + assert( u.by.nRoot>0 ); | |
| 68512 | + u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); | |
| 68513 | + if( u.by.aRoot==0 ) goto no_mem; | |
| 68478 | 68514 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68479 | - u.bv.pnErr = &aMem[pOp->p3]; | |
| 68480 | - assert( (u.bv.pnErr->flags & MEM_Int)!=0 ); | |
| 68481 | - assert( (u.bv.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); | |
| 68515 | + u.by.pnErr = &aMem[pOp->p3]; | |
| 68516 | + assert( (u.by.pnErr->flags & MEM_Int)!=0 ); | |
| 68517 | + assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); | |
| 68482 | 68518 | pIn1 = &aMem[pOp->p1]; |
| 68483 | - for(u.bv.j=0; u.bv.j<u.bv.nRoot; u.bv.j++){ | |
| 68484 | - u.bv.aRoot[u.bv.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bv.j]); | |
| 68519 | + for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ | |
| 68520 | + u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); | |
| 68485 | 68521 | } |
| 68486 | - u.bv.aRoot[u.bv.j] = 0; | |
| 68522 | + u.by.aRoot[u.by.j] = 0; | |
| 68487 | 68523 | assert( pOp->p5<db->nDb ); |
| 68488 | 68524 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 68489 | - u.bv.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bv.aRoot, u.bv.nRoot, | |
| 68490 | - (int)u.bv.pnErr->u.i, &u.bv.nErr); | |
| 68491 | - sqlite3DbFree(db, u.bv.aRoot); | |
| 68492 | - u.bv.pnErr->u.i -= u.bv.nErr; | |
| 68525 | + u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, | |
| 68526 | + (int)u.by.pnErr->u.i, &u.by.nErr); | |
| 68527 | + sqlite3DbFree(db, u.by.aRoot); | |
| 68528 | + u.by.pnErr->u.i -= u.by.nErr; | |
| 68493 | 68529 | sqlite3VdbeMemSetNull(pIn1); |
| 68494 | - if( u.bv.nErr==0 ){ | |
| 68495 | - assert( u.bv.z==0 ); | |
| 68496 | - }else if( u.bv.z==0 ){ | |
| 68530 | + if( u.by.nErr==0 ){ | |
| 68531 | + assert( u.by.z==0 ); | |
| 68532 | + }else if( u.by.z==0 ){ | |
| 68497 | 68533 | goto no_mem; |
| 68498 | 68534 | }else{ |
| 68499 | - sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free); | |
| 68535 | + sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); | |
| 68500 | 68536 | } |
| 68501 | 68537 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 68502 | 68538 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 68503 | 68539 | break; |
| 68504 | 68540 | } |
| @@ -68528,24 +68564,24 @@ | ||
| 68528 | 68564 | ** Extract the smallest value from boolean index P1 and put that value into |
| 68529 | 68565 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 68530 | 68566 | ** unchanged and jump to instruction P2. |
| 68531 | 68567 | */ |
| 68532 | 68568 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 68533 | -#if 0 /* local variables moved into u.bw */ | |
| 68569 | +#if 0 /* local variables moved into u.bz */ | |
| 68534 | 68570 | i64 val; |
| 68535 | -#endif /* local variables moved into u.bw */ | |
| 68571 | +#endif /* local variables moved into u.bz */ | |
| 68536 | 68572 | CHECK_FOR_INTERRUPT; |
| 68537 | 68573 | pIn1 = &aMem[pOp->p1]; |
| 68538 | 68574 | if( (pIn1->flags & MEM_RowSet)==0 |
| 68539 | - || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bw.val)==0 | |
| 68575 | + || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bz.val)==0 | |
| 68540 | 68576 | ){ |
| 68541 | 68577 | /* The boolean index is empty */ |
| 68542 | 68578 | sqlite3VdbeMemSetNull(pIn1); |
| 68543 | 68579 | pc = pOp->p2 - 1; |
| 68544 | 68580 | }else{ |
| 68545 | 68581 | /* A value was pulled from the index */ |
| 68546 | - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bw.val); | |
| 68582 | + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bz.val); | |
| 68547 | 68583 | } |
| 68548 | 68584 | break; |
| 68549 | 68585 | } |
| 68550 | 68586 | |
| 68551 | 68587 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| @@ -68570,18 +68606,18 @@ | ||
| 68570 | 68606 | ** inserted, there is no need to search to see if the same value was |
| 68571 | 68607 | ** previously inserted as part of set X (only if it was previously |
| 68572 | 68608 | ** inserted as part of some other set). |
| 68573 | 68609 | */ |
| 68574 | 68610 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 68575 | -#if 0 /* local variables moved into u.bx */ | |
| 68611 | +#if 0 /* local variables moved into u.ca */ | |
| 68576 | 68612 | int iSet; |
| 68577 | 68613 | int exists; |
| 68578 | -#endif /* local variables moved into u.bx */ | |
| 68614 | +#endif /* local variables moved into u.ca */ | |
| 68579 | 68615 | |
| 68580 | 68616 | pIn1 = &aMem[pOp->p1]; |
| 68581 | 68617 | pIn3 = &aMem[pOp->p3]; |
| 68582 | - u.bx.iSet = pOp->p4.i; | |
| 68618 | + u.ca.iSet = pOp->p4.i; | |
| 68583 | 68619 | assert( pIn3->flags&MEM_Int ); |
| 68584 | 68620 | |
| 68585 | 68621 | /* If there is anything other than a rowset object in memory cell P1, |
| 68586 | 68622 | ** delete it now and initialize P1 with an empty rowset |
| 68587 | 68623 | */ |
| @@ -68589,21 +68625,21 @@ | ||
| 68589 | 68625 | sqlite3VdbeMemSetRowSet(pIn1); |
| 68590 | 68626 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 68591 | 68627 | } |
| 68592 | 68628 | |
| 68593 | 68629 | assert( pOp->p4type==P4_INT32 ); |
| 68594 | - assert( u.bx.iSet==-1 || u.bx.iSet>=0 ); | |
| 68595 | - if( u.bx.iSet ){ | |
| 68596 | - u.bx.exists = sqlite3RowSetTest(pIn1->u.pRowSet, | |
| 68597 | - (u8)(u.bx.iSet>=0 ? u.bx.iSet & 0xf : 0xff), | |
| 68630 | + assert( u.ca.iSet==-1 || u.ca.iSet>=0 ); | |
| 68631 | + if( u.ca.iSet ){ | |
| 68632 | + u.ca.exists = sqlite3RowSetTest(pIn1->u.pRowSet, | |
| 68633 | + (u8)(u.ca.iSet>=0 ? u.ca.iSet & 0xf : 0xff), | |
| 68598 | 68634 | pIn3->u.i); |
| 68599 | - if( u.bx.exists ){ | |
| 68635 | + if( u.ca.exists ){ | |
| 68600 | 68636 | pc = pOp->p2 - 1; |
| 68601 | 68637 | break; |
| 68602 | 68638 | } |
| 68603 | 68639 | } |
| 68604 | - if( u.bx.iSet>=0 ){ | |
| 68640 | + if( u.ca.iSet>=0 ){ | |
| 68605 | 68641 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 68606 | 68642 | } |
| 68607 | 68643 | break; |
| 68608 | 68644 | } |
| 68609 | 68645 | |
| @@ -68622,25 +68658,25 @@ | ||
| 68622 | 68658 | ** memory required by the sub-vdbe at runtime. |
| 68623 | 68659 | ** |
| 68624 | 68660 | ** P4 is a pointer to the VM containing the trigger program. |
| 68625 | 68661 | */ |
| 68626 | 68662 | case OP_Program: { /* jump */ |
| 68627 | -#if 0 /* local variables moved into u.by */ | |
| 68663 | +#if 0 /* local variables moved into u.cb */ | |
| 68628 | 68664 | int nMem; /* Number of memory registers for sub-program */ |
| 68629 | 68665 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 68630 | 68666 | Mem *pRt; /* Register to allocate runtime space */ |
| 68631 | 68667 | Mem *pMem; /* Used to iterate through memory cells */ |
| 68632 | 68668 | Mem *pEnd; /* Last memory cell in new array */ |
| 68633 | 68669 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 68634 | 68670 | SubProgram *pProgram; /* Sub-program to execute */ |
| 68635 | 68671 | void *t; /* Token identifying trigger */ |
| 68636 | -#endif /* local variables moved into u.by */ | |
| 68672 | +#endif /* local variables moved into u.cb */ | |
| 68637 | 68673 | |
| 68638 | - u.by.pProgram = pOp->p4.pProgram; | |
| 68639 | - u.by.pRt = &aMem[pOp->p3]; | |
| 68640 | - assert( memIsValid(u.by.pRt) ); | |
| 68641 | - assert( u.by.pProgram->nOp>0 ); | |
| 68674 | + u.cb.pProgram = pOp->p4.pProgram; | |
| 68675 | + u.cb.pRt = &aMem[pOp->p3]; | |
| 68676 | + assert( memIsValid(u.cb.pRt) ); | |
| 68677 | + assert( u.cb.pProgram->nOp>0 ); | |
| 68642 | 68678 | |
| 68643 | 68679 | /* If the p5 flag is clear, then recursive invocation of triggers is |
| 68644 | 68680 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 68645 | 68681 | ** is really a trigger, not a foreign key action, and the flag set |
| 68646 | 68682 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| @@ -68650,79 +68686,79 @@ | ||
| 68650 | 68686 | ** SubProgram (if the trigger may be executed with more than one different |
| 68651 | 68687 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 68652 | 68688 | ** single trigger all have the same value for the SubProgram.token |
| 68653 | 68689 | ** variable. */ |
| 68654 | 68690 | if( pOp->p5 ){ |
| 68655 | - u.by.t = u.by.pProgram->token; | |
| 68656 | - for(u.by.pFrame=p->pFrame; u.by.pFrame && u.by.pFrame->token!=u.by.t; u.by.pFrame=u.by.pFrame->pParent); | |
| 68657 | - if( u.by.pFrame ) break; | |
| 68691 | + u.cb.t = u.cb.pProgram->token; | |
| 68692 | + for(u.cb.pFrame=p->pFrame; u.cb.pFrame && u.cb.pFrame->token!=u.cb.t; u.cb.pFrame=u.cb.pFrame->pParent); | |
| 68693 | + if( u.cb.pFrame ) break; | |
| 68658 | 68694 | } |
| 68659 | 68695 | |
| 68660 | 68696 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 68661 | 68697 | rc = SQLITE_ERROR; |
| 68662 | 68698 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 68663 | 68699 | break; |
| 68664 | 68700 | } |
| 68665 | 68701 | |
| 68666 | - /* Register u.by.pRt is used to store the memory required to save the state | |
| 68702 | + /* Register u.cb.pRt is used to store the memory required to save the state | |
| 68667 | 68703 | ** of the current program, and the memory required at runtime to execute |
| 68668 | - ** the trigger program. If this trigger has been fired before, then u.by.pRt | |
| 68704 | + ** the trigger program. If this trigger has been fired before, then u.cb.pRt | |
| 68669 | 68705 | ** is already allocated. Otherwise, it must be initialized. */ |
| 68670 | - if( (u.by.pRt->flags&MEM_Frame)==0 ){ | |
| 68706 | + if( (u.cb.pRt->flags&MEM_Frame)==0 ){ | |
| 68671 | 68707 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 68672 | 68708 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 68673 | 68709 | ** cell is required for each cursor used by the program. Set local |
| 68674 | - ** variable u.by.nMem (and later, VdbeFrame.nChildMem) to this value. | |
| 68710 | + ** variable u.cb.nMem (and later, VdbeFrame.nChildMem) to this value. | |
| 68675 | 68711 | */ |
| 68676 | - u.by.nMem = u.by.pProgram->nMem + u.by.pProgram->nCsr; | |
| 68677 | - u.by.nByte = ROUND8(sizeof(VdbeFrame)) | |
| 68678 | - + u.by.nMem * sizeof(Mem) | |
| 68679 | - + u.by.pProgram->nCsr * sizeof(VdbeCursor *); | |
| 68680 | - u.by.pFrame = sqlite3DbMallocZero(db, u.by.nByte); | |
| 68681 | - if( !u.by.pFrame ){ | |
| 68712 | + u.cb.nMem = u.cb.pProgram->nMem + u.cb.pProgram->nCsr; | |
| 68713 | + u.cb.nByte = ROUND8(sizeof(VdbeFrame)) | |
| 68714 | + + u.cb.nMem * sizeof(Mem) | |
| 68715 | + + u.cb.pProgram->nCsr * sizeof(VdbeCursor *); | |
| 68716 | + u.cb.pFrame = sqlite3DbMallocZero(db, u.cb.nByte); | |
| 68717 | + if( !u.cb.pFrame ){ | |
| 68682 | 68718 | goto no_mem; |
| 68683 | 68719 | } |
| 68684 | - sqlite3VdbeMemRelease(u.by.pRt); | |
| 68685 | - u.by.pRt->flags = MEM_Frame; | |
| 68686 | - u.by.pRt->u.pFrame = u.by.pFrame; | |
| 68687 | - | |
| 68688 | - u.by.pFrame->v = p; | |
| 68689 | - u.by.pFrame->nChildMem = u.by.nMem; | |
| 68690 | - u.by.pFrame->nChildCsr = u.by.pProgram->nCsr; | |
| 68691 | - u.by.pFrame->pc = pc; | |
| 68692 | - u.by.pFrame->aMem = p->aMem; | |
| 68693 | - u.by.pFrame->nMem = p->nMem; | |
| 68694 | - u.by.pFrame->apCsr = p->apCsr; | |
| 68695 | - u.by.pFrame->nCursor = p->nCursor; | |
| 68696 | - u.by.pFrame->aOp = p->aOp; | |
| 68697 | - u.by.pFrame->nOp = p->nOp; | |
| 68698 | - u.by.pFrame->token = u.by.pProgram->token; | |
| 68699 | - | |
| 68700 | - u.by.pEnd = &VdbeFrameMem(u.by.pFrame)[u.by.pFrame->nChildMem]; | |
| 68701 | - for(u.by.pMem=VdbeFrameMem(u.by.pFrame); u.by.pMem!=u.by.pEnd; u.by.pMem++){ | |
| 68702 | - u.by.pMem->flags = MEM_Null; | |
| 68703 | - u.by.pMem->db = db; | |
| 68720 | + sqlite3VdbeMemRelease(u.cb.pRt); | |
| 68721 | + u.cb.pRt->flags = MEM_Frame; | |
| 68722 | + u.cb.pRt->u.pFrame = u.cb.pFrame; | |
| 68723 | + | |
| 68724 | + u.cb.pFrame->v = p; | |
| 68725 | + u.cb.pFrame->nChildMem = u.cb.nMem; | |
| 68726 | + u.cb.pFrame->nChildCsr = u.cb.pProgram->nCsr; | |
| 68727 | + u.cb.pFrame->pc = pc; | |
| 68728 | + u.cb.pFrame->aMem = p->aMem; | |
| 68729 | + u.cb.pFrame->nMem = p->nMem; | |
| 68730 | + u.cb.pFrame->apCsr = p->apCsr; | |
| 68731 | + u.cb.pFrame->nCursor = p->nCursor; | |
| 68732 | + u.cb.pFrame->aOp = p->aOp; | |
| 68733 | + u.cb.pFrame->nOp = p->nOp; | |
| 68734 | + u.cb.pFrame->token = u.cb.pProgram->token; | |
| 68735 | + | |
| 68736 | + u.cb.pEnd = &VdbeFrameMem(u.cb.pFrame)[u.cb.pFrame->nChildMem]; | |
| 68737 | + for(u.cb.pMem=VdbeFrameMem(u.cb.pFrame); u.cb.pMem!=u.cb.pEnd; u.cb.pMem++){ | |
| 68738 | + u.cb.pMem->flags = MEM_Null; | |
| 68739 | + u.cb.pMem->db = db; | |
| 68704 | 68740 | } |
| 68705 | 68741 | }else{ |
| 68706 | - u.by.pFrame = u.by.pRt->u.pFrame; | |
| 68707 | - assert( u.by.pProgram->nMem+u.by.pProgram->nCsr==u.by.pFrame->nChildMem ); | |
| 68708 | - assert( u.by.pProgram->nCsr==u.by.pFrame->nChildCsr ); | |
| 68709 | - assert( pc==u.by.pFrame->pc ); | |
| 68742 | + u.cb.pFrame = u.cb.pRt->u.pFrame; | |
| 68743 | + assert( u.cb.pProgram->nMem+u.cb.pProgram->nCsr==u.cb.pFrame->nChildMem ); | |
| 68744 | + assert( u.cb.pProgram->nCsr==u.cb.pFrame->nChildCsr ); | |
| 68745 | + assert( pc==u.cb.pFrame->pc ); | |
| 68710 | 68746 | } |
| 68711 | 68747 | |
| 68712 | 68748 | p->nFrame++; |
| 68713 | - u.by.pFrame->pParent = p->pFrame; | |
| 68714 | - u.by.pFrame->lastRowid = lastRowid; | |
| 68715 | - u.by.pFrame->nChange = p->nChange; | |
| 68749 | + u.cb.pFrame->pParent = p->pFrame; | |
| 68750 | + u.cb.pFrame->lastRowid = lastRowid; | |
| 68751 | + u.cb.pFrame->nChange = p->nChange; | |
| 68716 | 68752 | p->nChange = 0; |
| 68717 | - p->pFrame = u.by.pFrame; | |
| 68718 | - p->aMem = aMem = &VdbeFrameMem(u.by.pFrame)[-1]; | |
| 68719 | - p->nMem = u.by.pFrame->nChildMem; | |
| 68720 | - p->nCursor = (u16)u.by.pFrame->nChildCsr; | |
| 68753 | + p->pFrame = u.cb.pFrame; | |
| 68754 | + p->aMem = aMem = &VdbeFrameMem(u.cb.pFrame)[-1]; | |
| 68755 | + p->nMem = u.cb.pFrame->nChildMem; | |
| 68756 | + p->nCursor = (u16)u.cb.pFrame->nChildCsr; | |
| 68721 | 68757 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 68722 | - p->aOp = aOp = u.by.pProgram->aOp; | |
| 68723 | - p->nOp = u.by.pProgram->nOp; | |
| 68758 | + p->aOp = aOp = u.cb.pProgram->aOp; | |
| 68759 | + p->nOp = u.cb.pProgram->nOp; | |
| 68724 | 68760 | pc = -1; |
| 68725 | 68761 | |
| 68726 | 68762 | break; |
| 68727 | 68763 | } |
| 68728 | 68764 | |
| @@ -68737,17 +68773,17 @@ | ||
| 68737 | 68773 | ** The address of the cell in the parent frame is determined by adding |
| 68738 | 68774 | ** the value of the P1 argument to the value of the P1 argument to the |
| 68739 | 68775 | ** calling OP_Program instruction. |
| 68740 | 68776 | */ |
| 68741 | 68777 | case OP_Param: { /* out2-prerelease */ |
| 68742 | -#if 0 /* local variables moved into u.bz */ | |
| 68778 | +#if 0 /* local variables moved into u.cc */ | |
| 68743 | 68779 | VdbeFrame *pFrame; |
| 68744 | 68780 | Mem *pIn; |
| 68745 | -#endif /* local variables moved into u.bz */ | |
| 68746 | - u.bz.pFrame = p->pFrame; | |
| 68747 | - u.bz.pIn = &u.bz.pFrame->aMem[pOp->p1 + u.bz.pFrame->aOp[u.bz.pFrame->pc].p1]; | |
| 68748 | - sqlite3VdbeMemShallowCopy(pOut, u.bz.pIn, MEM_Ephem); | |
| 68781 | +#endif /* local variables moved into u.cc */ | |
| 68782 | + u.cc.pFrame = p->pFrame; | |
| 68783 | + u.cc.pIn = &u.cc.pFrame->aMem[pOp->p1 + u.cc.pFrame->aOp[u.cc.pFrame->pc].p1]; | |
| 68784 | + sqlite3VdbeMemShallowCopy(pOut, u.cc.pIn, MEM_Ephem); | |
| 68749 | 68785 | break; |
| 68750 | 68786 | } |
| 68751 | 68787 | |
| 68752 | 68788 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 68753 | 68789 | |
| @@ -68799,26 +68835,26 @@ | ||
| 68799 | 68835 | ** |
| 68800 | 68836 | ** This instruction throws an error if the memory cell is not initially |
| 68801 | 68837 | ** an integer. |
| 68802 | 68838 | */ |
| 68803 | 68839 | case OP_MemMax: { /* in2 */ |
| 68804 | -#if 0 /* local variables moved into u.ca */ | |
| 68840 | +#if 0 /* local variables moved into u.cd */ | |
| 68805 | 68841 | Mem *pIn1; |
| 68806 | 68842 | VdbeFrame *pFrame; |
| 68807 | -#endif /* local variables moved into u.ca */ | |
| 68843 | +#endif /* local variables moved into u.cd */ | |
| 68808 | 68844 | if( p->pFrame ){ |
| 68809 | - for(u.ca.pFrame=p->pFrame; u.ca.pFrame->pParent; u.ca.pFrame=u.ca.pFrame->pParent); | |
| 68810 | - u.ca.pIn1 = &u.ca.pFrame->aMem[pOp->p1]; | |
| 68845 | + for(u.cd.pFrame=p->pFrame; u.cd.pFrame->pParent; u.cd.pFrame=u.cd.pFrame->pParent); | |
| 68846 | + u.cd.pIn1 = &u.cd.pFrame->aMem[pOp->p1]; | |
| 68811 | 68847 | }else{ |
| 68812 | - u.ca.pIn1 = &aMem[pOp->p1]; | |
| 68848 | + u.cd.pIn1 = &aMem[pOp->p1]; | |
| 68813 | 68849 | } |
| 68814 | - assert( memIsValid(u.ca.pIn1) ); | |
| 68815 | - sqlite3VdbeMemIntegerify(u.ca.pIn1); | |
| 68850 | + assert( memIsValid(u.cd.pIn1) ); | |
| 68851 | + sqlite3VdbeMemIntegerify(u.cd.pIn1); | |
| 68816 | 68852 | pIn2 = &aMem[pOp->p2]; |
| 68817 | 68853 | sqlite3VdbeMemIntegerify(pIn2); |
| 68818 | - if( u.ca.pIn1->u.i<pIn2->u.i){ | |
| 68819 | - u.ca.pIn1->u.i = pIn2->u.i; | |
| 68854 | + if( u.cd.pIn1->u.i<pIn2->u.i){ | |
| 68855 | + u.cd.pIn1->u.i = pIn2->u.i; | |
| 68820 | 68856 | } |
| 68821 | 68857 | break; |
| 68822 | 68858 | } |
| 68823 | 68859 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 68824 | 68860 | |
| @@ -68881,54 +68917,54 @@ | ||
| 68881 | 68917 | ** |
| 68882 | 68918 | ** The P5 arguments are taken from register P2 and its |
| 68883 | 68919 | ** successors. |
| 68884 | 68920 | */ |
| 68885 | 68921 | case OP_AggStep: { |
| 68886 | -#if 0 /* local variables moved into u.cb */ | |
| 68922 | +#if 0 /* local variables moved into u.ce */ | |
| 68887 | 68923 | int n; |
| 68888 | 68924 | int i; |
| 68889 | 68925 | Mem *pMem; |
| 68890 | 68926 | Mem *pRec; |
| 68891 | 68927 | sqlite3_context ctx; |
| 68892 | 68928 | sqlite3_value **apVal; |
| 68893 | -#endif /* local variables moved into u.cb */ | |
| 68894 | - | |
| 68895 | - u.cb.n = pOp->p5; | |
| 68896 | - assert( u.cb.n>=0 ); | |
| 68897 | - u.cb.pRec = &aMem[pOp->p2]; | |
| 68898 | - u.cb.apVal = p->apArg; | |
| 68899 | - assert( u.cb.apVal || u.cb.n==0 ); | |
| 68900 | - for(u.cb.i=0; u.cb.i<u.cb.n; u.cb.i++, u.cb.pRec++){ | |
| 68901 | - assert( memIsValid(u.cb.pRec) ); | |
| 68902 | - u.cb.apVal[u.cb.i] = u.cb.pRec; | |
| 68903 | - memAboutToChange(p, u.cb.pRec); | |
| 68904 | - sqlite3VdbeMemStoreType(u.cb.pRec); | |
| 68905 | - } | |
| 68906 | - u.cb.ctx.pFunc = pOp->p4.pFunc; | |
| 68929 | +#endif /* local variables moved into u.ce */ | |
| 68930 | + | |
| 68931 | + u.ce.n = pOp->p5; | |
| 68932 | + assert( u.ce.n>=0 ); | |
| 68933 | + u.ce.pRec = &aMem[pOp->p2]; | |
| 68934 | + u.ce.apVal = p->apArg; | |
| 68935 | + assert( u.ce.apVal || u.ce.n==0 ); | |
| 68936 | + for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ | |
| 68937 | + assert( memIsValid(u.ce.pRec) ); | |
| 68938 | + u.ce.apVal[u.ce.i] = u.ce.pRec; | |
| 68939 | + memAboutToChange(p, u.ce.pRec); | |
| 68940 | + sqlite3VdbeMemStoreType(u.ce.pRec); | |
| 68941 | + } | |
| 68942 | + u.ce.ctx.pFunc = pOp->p4.pFunc; | |
| 68907 | 68943 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68908 | - u.cb.ctx.pMem = u.cb.pMem = &aMem[pOp->p3]; | |
| 68909 | - u.cb.pMem->n++; | |
| 68910 | - u.cb.ctx.s.flags = MEM_Null; | |
| 68911 | - u.cb.ctx.s.z = 0; | |
| 68912 | - u.cb.ctx.s.zMalloc = 0; | |
| 68913 | - u.cb.ctx.s.xDel = 0; | |
| 68914 | - u.cb.ctx.s.db = db; | |
| 68915 | - u.cb.ctx.isError = 0; | |
| 68916 | - u.cb.ctx.pColl = 0; | |
| 68917 | - if( u.cb.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ | |
| 68944 | + u.ce.ctx.pMem = u.ce.pMem = &aMem[pOp->p3]; | |
| 68945 | + u.ce.pMem->n++; | |
| 68946 | + u.ce.ctx.s.flags = MEM_Null; | |
| 68947 | + u.ce.ctx.s.z = 0; | |
| 68948 | + u.ce.ctx.s.zMalloc = 0; | |
| 68949 | + u.ce.ctx.s.xDel = 0; | |
| 68950 | + u.ce.ctx.s.db = db; | |
| 68951 | + u.ce.ctx.isError = 0; | |
| 68952 | + u.ce.ctx.pColl = 0; | |
| 68953 | + if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ | |
| 68918 | 68954 | assert( pOp>p->aOp ); |
| 68919 | 68955 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 68920 | 68956 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 68921 | - u.cb.ctx.pColl = pOp[-1].p4.pColl; | |
| 68957 | + u.ce.ctx.pColl = pOp[-1].p4.pColl; | |
| 68922 | 68958 | } |
| 68923 | - (u.cb.ctx.pFunc->xStep)(&u.cb.ctx, u.cb.n, u.cb.apVal); /* IMP: R-24505-23230 */ | |
| 68924 | - if( u.cb.ctx.isError ){ | |
| 68925 | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cb.ctx.s)); | |
| 68926 | - rc = u.cb.ctx.isError; | |
| 68959 | + (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); /* IMP: R-24505-23230 */ | |
| 68960 | + if( u.ce.ctx.isError ){ | |
| 68961 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); | |
| 68962 | + rc = u.ce.ctx.isError; | |
| 68927 | 68963 | } |
| 68928 | 68964 | |
| 68929 | - sqlite3VdbeMemRelease(&u.cb.ctx.s); | |
| 68965 | + sqlite3VdbeMemRelease(&u.ce.ctx.s); | |
| 68930 | 68966 | |
| 68931 | 68967 | break; |
| 68932 | 68968 | } |
| 68933 | 68969 | |
| 68934 | 68970 | /* Opcode: AggFinal P1 P2 * P4 * |
| @@ -68942,23 +68978,23 @@ | ||
| 68942 | 68978 | ** functions that can take varying numbers of arguments. The |
| 68943 | 68979 | ** P4 argument is only needed for the degenerate case where |
| 68944 | 68980 | ** the step function was not previously called. |
| 68945 | 68981 | */ |
| 68946 | 68982 | case OP_AggFinal: { |
| 68947 | -#if 0 /* local variables moved into u.cc */ | |
| 68983 | +#if 0 /* local variables moved into u.cf */ | |
| 68948 | 68984 | Mem *pMem; |
| 68949 | -#endif /* local variables moved into u.cc */ | |
| 68985 | +#endif /* local variables moved into u.cf */ | |
| 68950 | 68986 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 68951 | - u.cc.pMem = &aMem[pOp->p1]; | |
| 68952 | - assert( (u.cc.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); | |
| 68953 | - rc = sqlite3VdbeMemFinalize(u.cc.pMem, pOp->p4.pFunc); | |
| 68987 | + u.cf.pMem = &aMem[pOp->p1]; | |
| 68988 | + assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); | |
| 68989 | + rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); | |
| 68954 | 68990 | if( rc ){ |
| 68955 | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cc.pMem)); | |
| 68991 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); | |
| 68956 | 68992 | } |
| 68957 | - sqlite3VdbeChangeEncoding(u.cc.pMem, encoding); | |
| 68958 | - UPDATE_MAX_BLOBSIZE(u.cc.pMem); | |
| 68959 | - if( sqlite3VdbeMemTooBig(u.cc.pMem) ){ | |
| 68993 | + sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); | |
| 68994 | + UPDATE_MAX_BLOBSIZE(u.cf.pMem); | |
| 68995 | + if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ | |
| 68960 | 68996 | goto too_big; |
| 68961 | 68997 | } |
| 68962 | 68998 | break; |
| 68963 | 68999 | } |
| 68964 | 69000 | |
| @@ -68973,29 +69009,29 @@ | ||
| 68973 | 69009 | ** in the WAL that have been checkpointed after the checkpoint |
| 68974 | 69010 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 68975 | 69011 | ** mem[P3+2] are initialized to -1. |
| 68976 | 69012 | */ |
| 68977 | 69013 | case OP_Checkpoint: { |
| 68978 | -#if 0 /* local variables moved into u.cd */ | |
| 69014 | +#if 0 /* local variables moved into u.cg */ | |
| 68979 | 69015 | int i; /* Loop counter */ |
| 68980 | 69016 | int aRes[3]; /* Results */ |
| 68981 | 69017 | Mem *pMem; /* Write results here */ |
| 68982 | -#endif /* local variables moved into u.cd */ | |
| 69018 | +#endif /* local variables moved into u.cg */ | |
| 68983 | 69019 | |
| 68984 | - u.cd.aRes[0] = 0; | |
| 68985 | - u.cd.aRes[1] = u.cd.aRes[2] = -1; | |
| 69020 | + u.cg.aRes[0] = 0; | |
| 69021 | + u.cg.aRes[1] = u.cg.aRes[2] = -1; | |
| 68986 | 69022 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 68987 | 69023 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 68988 | 69024 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 68989 | 69025 | ); |
| 68990 | - rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cd.aRes[1], &u.cd.aRes[2]); | |
| 69026 | + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cg.aRes[1], &u.cg.aRes[2]); | |
| 68991 | 69027 | if( rc==SQLITE_BUSY ){ |
| 68992 | 69028 | rc = SQLITE_OK; |
| 68993 | - u.cd.aRes[0] = 1; | |
| 69029 | + u.cg.aRes[0] = 1; | |
| 68994 | 69030 | } |
| 68995 | - for(u.cd.i=0, u.cd.pMem = &aMem[pOp->p3]; u.cd.i<3; u.cd.i++, u.cd.pMem++){ | |
| 68996 | - sqlite3VdbeMemSetInt64(u.cd.pMem, (i64)u.cd.aRes[u.cd.i]); | |
| 69031 | + for(u.cg.i=0, u.cg.pMem = &aMem[pOp->p3]; u.cg.i<3; u.cg.i++, u.cg.pMem++){ | |
| 69032 | + sqlite3VdbeMemSetInt64(u.cg.pMem, (i64)u.cg.aRes[u.cg.i]); | |
| 68997 | 69033 | } |
| 68998 | 69034 | break; |
| 68999 | 69035 | }; |
| 69000 | 69036 | #endif |
| 69001 | 69037 | |
| @@ -69010,95 +69046,95 @@ | ||
| 69010 | 69046 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 69011 | 69047 | ** |
| 69012 | 69048 | ** Write a string containing the final journal-mode to register P2. |
| 69013 | 69049 | */ |
| 69014 | 69050 | case OP_JournalMode: { /* out2-prerelease */ |
| 69015 | -#if 0 /* local variables moved into u.ce */ | |
| 69051 | +#if 0 /* local variables moved into u.ch */ | |
| 69016 | 69052 | Btree *pBt; /* Btree to change journal mode of */ |
| 69017 | 69053 | Pager *pPager; /* Pager associated with pBt */ |
| 69018 | 69054 | int eNew; /* New journal mode */ |
| 69019 | 69055 | int eOld; /* The old journal mode */ |
| 69020 | 69056 | const char *zFilename; /* Name of database file for pPager */ |
| 69021 | -#endif /* local variables moved into u.ce */ | |
| 69022 | - | |
| 69023 | - u.ce.eNew = pOp->p3; | |
| 69024 | - assert( u.ce.eNew==PAGER_JOURNALMODE_DELETE | |
| 69025 | - || u.ce.eNew==PAGER_JOURNALMODE_TRUNCATE | |
| 69026 | - || u.ce.eNew==PAGER_JOURNALMODE_PERSIST | |
| 69027 | - || u.ce.eNew==PAGER_JOURNALMODE_OFF | |
| 69028 | - || u.ce.eNew==PAGER_JOURNALMODE_MEMORY | |
| 69029 | - || u.ce.eNew==PAGER_JOURNALMODE_WAL | |
| 69030 | - || u.ce.eNew==PAGER_JOURNALMODE_QUERY | |
| 69057 | +#endif /* local variables moved into u.ch */ | |
| 69058 | + | |
| 69059 | + u.ch.eNew = pOp->p3; | |
| 69060 | + assert( u.ch.eNew==PAGER_JOURNALMODE_DELETE | |
| 69061 | + || u.ch.eNew==PAGER_JOURNALMODE_TRUNCATE | |
| 69062 | + || u.ch.eNew==PAGER_JOURNALMODE_PERSIST | |
| 69063 | + || u.ch.eNew==PAGER_JOURNALMODE_OFF | |
| 69064 | + || u.ch.eNew==PAGER_JOURNALMODE_MEMORY | |
| 69065 | + || u.ch.eNew==PAGER_JOURNALMODE_WAL | |
| 69066 | + || u.ch.eNew==PAGER_JOURNALMODE_QUERY | |
| 69031 | 69067 | ); |
| 69032 | 69068 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69033 | 69069 | |
| 69034 | - u.ce.pBt = db->aDb[pOp->p1].pBt; | |
| 69035 | - u.ce.pPager = sqlite3BtreePager(u.ce.pBt); | |
| 69036 | - u.ce.eOld = sqlite3PagerGetJournalMode(u.ce.pPager); | |
| 69037 | - if( u.ce.eNew==PAGER_JOURNALMODE_QUERY ) u.ce.eNew = u.ce.eOld; | |
| 69038 | - if( !sqlite3PagerOkToChangeJournalMode(u.ce.pPager) ) u.ce.eNew = u.ce.eOld; | |
| 69070 | + u.ch.pBt = db->aDb[pOp->p1].pBt; | |
| 69071 | + u.ch.pPager = sqlite3BtreePager(u.ch.pBt); | |
| 69072 | + u.ch.eOld = sqlite3PagerGetJournalMode(u.ch.pPager); | |
| 69073 | + if( u.ch.eNew==PAGER_JOURNALMODE_QUERY ) u.ch.eNew = u.ch.eOld; | |
| 69074 | + if( !sqlite3PagerOkToChangeJournalMode(u.ch.pPager) ) u.ch.eNew = u.ch.eOld; | |
| 69039 | 69075 | |
| 69040 | 69076 | #ifndef SQLITE_OMIT_WAL |
| 69041 | - u.ce.zFilename = sqlite3PagerFilename(u.ce.pPager); | |
| 69077 | + u.ch.zFilename = sqlite3PagerFilename(u.ch.pPager); | |
| 69042 | 69078 | |
| 69043 | 69079 | /* Do not allow a transition to journal_mode=WAL for a database |
| 69044 | 69080 | ** in temporary storage or if the VFS does not support shared memory |
| 69045 | 69081 | */ |
| 69046 | - if( u.ce.eNew==PAGER_JOURNALMODE_WAL | |
| 69047 | - && (u.ce.zFilename[0]==0 /* Temp file */ | |
| 69048 | - || !sqlite3PagerWalSupported(u.ce.pPager)) /* No shared-memory support */ | |
| 69082 | + if( u.ch.eNew==PAGER_JOURNALMODE_WAL | |
| 69083 | + && (u.ch.zFilename[0]==0 /* Temp file */ | |
| 69084 | + || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */ | |
| 69049 | 69085 | ){ |
| 69050 | - u.ce.eNew = u.ce.eOld; | |
| 69086 | + u.ch.eNew = u.ch.eOld; | |
| 69051 | 69087 | } |
| 69052 | 69088 | |
| 69053 | - if( (u.ce.eNew!=u.ce.eOld) | |
| 69054 | - && (u.ce.eOld==PAGER_JOURNALMODE_WAL || u.ce.eNew==PAGER_JOURNALMODE_WAL) | |
| 69089 | + if( (u.ch.eNew!=u.ch.eOld) | |
| 69090 | + && (u.ch.eOld==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_WAL) | |
| 69055 | 69091 | ){ |
| 69056 | 69092 | if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 69057 | 69093 | rc = SQLITE_ERROR; |
| 69058 | 69094 | sqlite3SetString(&p->zErrMsg, db, |
| 69059 | 69095 | "cannot change %s wal mode from within a transaction", |
| 69060 | - (u.ce.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") | |
| 69096 | + (u.ch.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") | |
| 69061 | 69097 | ); |
| 69062 | 69098 | break; |
| 69063 | 69099 | }else{ |
| 69064 | 69100 | |
| 69065 | - if( u.ce.eOld==PAGER_JOURNALMODE_WAL ){ | |
| 69101 | + if( u.ch.eOld==PAGER_JOURNALMODE_WAL ){ | |
| 69066 | 69102 | /* If leaving WAL mode, close the log file. If successful, the call |
| 69067 | 69103 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 69068 | 69104 | ** file. An EXCLUSIVE lock may still be held on the database file |
| 69069 | 69105 | ** after a successful return. |
| 69070 | 69106 | */ |
| 69071 | - rc = sqlite3PagerCloseWal(u.ce.pPager); | |
| 69107 | + rc = sqlite3PagerCloseWal(u.ch.pPager); | |
| 69072 | 69108 | if( rc==SQLITE_OK ){ |
| 69073 | - sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); | |
| 69109 | + sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); | |
| 69074 | 69110 | } |
| 69075 | - }else if( u.ce.eOld==PAGER_JOURNALMODE_MEMORY ){ | |
| 69111 | + }else if( u.ch.eOld==PAGER_JOURNALMODE_MEMORY ){ | |
| 69076 | 69112 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 69077 | 69113 | ** as an intermediate */ |
| 69078 | - sqlite3PagerSetJournalMode(u.ce.pPager, PAGER_JOURNALMODE_OFF); | |
| 69114 | + sqlite3PagerSetJournalMode(u.ch.pPager, PAGER_JOURNALMODE_OFF); | |
| 69079 | 69115 | } |
| 69080 | 69116 | |
| 69081 | 69117 | /* Open a transaction on the database file. Regardless of the journal |
| 69082 | 69118 | ** mode, this transaction always uses a rollback journal. |
| 69083 | 69119 | */ |
| 69084 | - assert( sqlite3BtreeIsInTrans(u.ce.pBt)==0 ); | |
| 69120 | + assert( sqlite3BtreeIsInTrans(u.ch.pBt)==0 ); | |
| 69085 | 69121 | if( rc==SQLITE_OK ){ |
| 69086 | - rc = sqlite3BtreeSetVersion(u.ce.pBt, (u.ce.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); | |
| 69122 | + rc = sqlite3BtreeSetVersion(u.ch.pBt, (u.ch.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); | |
| 69087 | 69123 | } |
| 69088 | 69124 | } |
| 69089 | 69125 | } |
| 69090 | 69126 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 69091 | 69127 | |
| 69092 | 69128 | if( rc ){ |
| 69093 | - u.ce.eNew = u.ce.eOld; | |
| 69129 | + u.ch.eNew = u.ch.eOld; | |
| 69094 | 69130 | } |
| 69095 | - u.ce.eNew = sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); | |
| 69131 | + u.ch.eNew = sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); | |
| 69096 | 69132 | |
| 69097 | 69133 | pOut = &aMem[pOp->p2]; |
| 69098 | 69134 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 69099 | - pOut->z = (char *)sqlite3JournalModename(u.ce.eNew); | |
| 69135 | + pOut->z = (char *)sqlite3JournalModename(u.ch.eNew); | |
| 69100 | 69136 | pOut->n = sqlite3Strlen30(pOut->z); |
| 69101 | 69137 | pOut->enc = SQLITE_UTF8; |
| 69102 | 69138 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 69103 | 69139 | break; |
| 69104 | 69140 | }; |
| @@ -69123,18 +69159,18 @@ | ||
| 69123 | 69159 | ** Perform a single step of the incremental vacuum procedure on |
| 69124 | 69160 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 69125 | 69161 | ** P2. Otherwise, fall through to the next instruction. |
| 69126 | 69162 | */ |
| 69127 | 69163 | case OP_IncrVacuum: { /* jump */ |
| 69128 | -#if 0 /* local variables moved into u.cf */ | |
| 69164 | +#if 0 /* local variables moved into u.ci */ | |
| 69129 | 69165 | Btree *pBt; |
| 69130 | -#endif /* local variables moved into u.cf */ | |
| 69166 | +#endif /* local variables moved into u.ci */ | |
| 69131 | 69167 | |
| 69132 | 69168 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69133 | 69169 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69134 | - u.cf.pBt = db->aDb[pOp->p1].pBt; | |
| 69135 | - rc = sqlite3BtreeIncrVacuum(u.cf.pBt); | |
| 69170 | + u.ci.pBt = db->aDb[pOp->p1].pBt; | |
| 69171 | + rc = sqlite3BtreeIncrVacuum(u.ci.pBt); | |
| 69136 | 69172 | if( rc==SQLITE_DONE ){ |
| 69137 | 69173 | pc = pOp->p2 - 1; |
| 69138 | 69174 | rc = SQLITE_OK; |
| 69139 | 69175 | } |
| 69140 | 69176 | break; |
| @@ -69200,16 +69236,16 @@ | ||
| 69200 | 69236 | ** Also, whether or not P4 is set, check that this is not being called from |
| 69201 | 69237 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 69202 | 69238 | ** code will be set to SQLITE_LOCKED. |
| 69203 | 69239 | */ |
| 69204 | 69240 | case OP_VBegin: { |
| 69205 | -#if 0 /* local variables moved into u.cg */ | |
| 69241 | +#if 0 /* local variables moved into u.cj */ | |
| 69206 | 69242 | VTable *pVTab; |
| 69207 | -#endif /* local variables moved into u.cg */ | |
| 69208 | - u.cg.pVTab = pOp->p4.pVtab; | |
| 69209 | - rc = sqlite3VtabBegin(db, u.cg.pVTab); | |
| 69210 | - if( u.cg.pVTab ) importVtabErrMsg(p, u.cg.pVTab->pVtab); | |
| 69243 | +#endif /* local variables moved into u.cj */ | |
| 69244 | + u.cj.pVTab = pOp->p4.pVtab; | |
| 69245 | + rc = sqlite3VtabBegin(db, u.cj.pVTab); | |
| 69246 | + if( u.cj.pVTab ) importVtabErrMsg(p, u.cj.pVTab->pVtab); | |
| 69211 | 69247 | break; |
| 69212 | 69248 | } |
| 69213 | 69249 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69214 | 69250 | |
| 69215 | 69251 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| @@ -69244,36 +69280,36 @@ | ||
| 69244 | 69280 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69245 | 69281 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 69246 | 69282 | ** table and stores that cursor in P1. |
| 69247 | 69283 | */ |
| 69248 | 69284 | case OP_VOpen: { |
| 69249 | -#if 0 /* local variables moved into u.ch */ | |
| 69285 | +#if 0 /* local variables moved into u.ck */ | |
| 69250 | 69286 | VdbeCursor *pCur; |
| 69251 | 69287 | sqlite3_vtab_cursor *pVtabCursor; |
| 69252 | 69288 | sqlite3_vtab *pVtab; |
| 69253 | 69289 | sqlite3_module *pModule; |
| 69254 | -#endif /* local variables moved into u.ch */ | |
| 69255 | - | |
| 69256 | - u.ch.pCur = 0; | |
| 69257 | - u.ch.pVtabCursor = 0; | |
| 69258 | - u.ch.pVtab = pOp->p4.pVtab->pVtab; | |
| 69259 | - u.ch.pModule = (sqlite3_module *)u.ch.pVtab->pModule; | |
| 69260 | - assert(u.ch.pVtab && u.ch.pModule); | |
| 69261 | - rc = u.ch.pModule->xOpen(u.ch.pVtab, &u.ch.pVtabCursor); | |
| 69262 | - importVtabErrMsg(p, u.ch.pVtab); | |
| 69290 | +#endif /* local variables moved into u.ck */ | |
| 69291 | + | |
| 69292 | + u.ck.pCur = 0; | |
| 69293 | + u.ck.pVtabCursor = 0; | |
| 69294 | + u.ck.pVtab = pOp->p4.pVtab->pVtab; | |
| 69295 | + u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; | |
| 69296 | + assert(u.ck.pVtab && u.ck.pModule); | |
| 69297 | + rc = u.ck.pModule->xOpen(u.ck.pVtab, &u.ck.pVtabCursor); | |
| 69298 | + importVtabErrMsg(p, u.ck.pVtab); | |
| 69263 | 69299 | if( SQLITE_OK==rc ){ |
| 69264 | 69300 | /* Initialize sqlite3_vtab_cursor base class */ |
| 69265 | - u.ch.pVtabCursor->pVtab = u.ch.pVtab; | |
| 69301 | + u.ck.pVtabCursor->pVtab = u.ck.pVtab; | |
| 69266 | 69302 | |
| 69267 | 69303 | /* Initialise vdbe cursor object */ |
| 69268 | - u.ch.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); | |
| 69269 | - if( u.ch.pCur ){ | |
| 69270 | - u.ch.pCur->pVtabCursor = u.ch.pVtabCursor; | |
| 69271 | - u.ch.pCur->pModule = u.ch.pVtabCursor->pVtab->pModule; | |
| 69304 | + u.ck.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); | |
| 69305 | + if( u.ck.pCur ){ | |
| 69306 | + u.ck.pCur->pVtabCursor = u.ck.pVtabCursor; | |
| 69307 | + u.ck.pCur->pModule = u.ck.pVtabCursor->pVtab->pModule; | |
| 69272 | 69308 | }else{ |
| 69273 | 69309 | db->mallocFailed = 1; |
| 69274 | - u.ch.pModule->xClose(u.ch.pVtabCursor); | |
| 69310 | + u.ck.pModule->xClose(u.ck.pVtabCursor); | |
| 69275 | 69311 | } |
| 69276 | 69312 | } |
| 69277 | 69313 | break; |
| 69278 | 69314 | } |
| 69279 | 69315 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69296,11 +69332,11 @@ | ||
| 69296 | 69332 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 69297 | 69333 | ** |
| 69298 | 69334 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 69299 | 69335 | */ |
| 69300 | 69336 | case OP_VFilter: { /* jump */ |
| 69301 | -#if 0 /* local variables moved into u.ci */ | |
| 69337 | +#if 0 /* local variables moved into u.cl */ | |
| 69302 | 69338 | int nArg; |
| 69303 | 69339 | int iQuery; |
| 69304 | 69340 | const sqlite3_module *pModule; |
| 69305 | 69341 | Mem *pQuery; |
| 69306 | 69342 | Mem *pArgc; |
| @@ -69308,49 +69344,49 @@ | ||
| 69308 | 69344 | sqlite3_vtab *pVtab; |
| 69309 | 69345 | VdbeCursor *pCur; |
| 69310 | 69346 | int res; |
| 69311 | 69347 | int i; |
| 69312 | 69348 | Mem **apArg; |
| 69313 | -#endif /* local variables moved into u.ci */ | |
| 69314 | - | |
| 69315 | - u.ci.pQuery = &aMem[pOp->p3]; | |
| 69316 | - u.ci.pArgc = &u.ci.pQuery[1]; | |
| 69317 | - u.ci.pCur = p->apCsr[pOp->p1]; | |
| 69318 | - assert( memIsValid(u.ci.pQuery) ); | |
| 69319 | - REGISTER_TRACE(pOp->p3, u.ci.pQuery); | |
| 69320 | - assert( u.ci.pCur->pVtabCursor ); | |
| 69321 | - u.ci.pVtabCursor = u.ci.pCur->pVtabCursor; | |
| 69322 | - u.ci.pVtab = u.ci.pVtabCursor->pVtab; | |
| 69323 | - u.ci.pModule = u.ci.pVtab->pModule; | |
| 69349 | +#endif /* local variables moved into u.cl */ | |
| 69350 | + | |
| 69351 | + u.cl.pQuery = &aMem[pOp->p3]; | |
| 69352 | + u.cl.pArgc = &u.cl.pQuery[1]; | |
| 69353 | + u.cl.pCur = p->apCsr[pOp->p1]; | |
| 69354 | + assert( memIsValid(u.cl.pQuery) ); | |
| 69355 | + REGISTER_TRACE(pOp->p3, u.cl.pQuery); | |
| 69356 | + assert( u.cl.pCur->pVtabCursor ); | |
| 69357 | + u.cl.pVtabCursor = u.cl.pCur->pVtabCursor; | |
| 69358 | + u.cl.pVtab = u.cl.pVtabCursor->pVtab; | |
| 69359 | + u.cl.pModule = u.cl.pVtab->pModule; | |
| 69324 | 69360 | |
| 69325 | 69361 | /* Grab the index number and argc parameters */ |
| 69326 | - assert( (u.ci.pQuery->flags&MEM_Int)!=0 && u.ci.pArgc->flags==MEM_Int ); | |
| 69327 | - u.ci.nArg = (int)u.ci.pArgc->u.i; | |
| 69328 | - u.ci.iQuery = (int)u.ci.pQuery->u.i; | |
| 69362 | + assert( (u.cl.pQuery->flags&MEM_Int)!=0 && u.cl.pArgc->flags==MEM_Int ); | |
| 69363 | + u.cl.nArg = (int)u.cl.pArgc->u.i; | |
| 69364 | + u.cl.iQuery = (int)u.cl.pQuery->u.i; | |
| 69329 | 69365 | |
| 69330 | 69366 | /* Invoke the xFilter method */ |
| 69331 | 69367 | { |
| 69332 | - u.ci.res = 0; | |
| 69333 | - u.ci.apArg = p->apArg; | |
| 69334 | - for(u.ci.i = 0; u.ci.i<u.ci.nArg; u.ci.i++){ | |
| 69335 | - u.ci.apArg[u.ci.i] = &u.ci.pArgc[u.ci.i+1]; | |
| 69336 | - sqlite3VdbeMemStoreType(u.ci.apArg[u.ci.i]); | |
| 69368 | + u.cl.res = 0; | |
| 69369 | + u.cl.apArg = p->apArg; | |
| 69370 | + for(u.cl.i = 0; u.cl.i<u.cl.nArg; u.cl.i++){ | |
| 69371 | + u.cl.apArg[u.cl.i] = &u.cl.pArgc[u.cl.i+1]; | |
| 69372 | + sqlite3VdbeMemStoreType(u.cl.apArg[u.cl.i]); | |
| 69337 | 69373 | } |
| 69338 | 69374 | |
| 69339 | 69375 | p->inVtabMethod = 1; |
| 69340 | - rc = u.ci.pModule->xFilter(u.ci.pVtabCursor, u.ci.iQuery, pOp->p4.z, u.ci.nArg, u.ci.apArg); | |
| 69376 | + rc = u.cl.pModule->xFilter(u.cl.pVtabCursor, u.cl.iQuery, pOp->p4.z, u.cl.nArg, u.cl.apArg); | |
| 69341 | 69377 | p->inVtabMethod = 0; |
| 69342 | - importVtabErrMsg(p, u.ci.pVtab); | |
| 69378 | + importVtabErrMsg(p, u.cl.pVtab); | |
| 69343 | 69379 | if( rc==SQLITE_OK ){ |
| 69344 | - u.ci.res = u.ci.pModule->xEof(u.ci.pVtabCursor); | |
| 69380 | + u.cl.res = u.cl.pModule->xEof(u.cl.pVtabCursor); | |
| 69345 | 69381 | } |
| 69346 | 69382 | |
| 69347 | - if( u.ci.res ){ | |
| 69383 | + if( u.cl.res ){ | |
| 69348 | 69384 | pc = pOp->p2 - 1; |
| 69349 | 69385 | } |
| 69350 | 69386 | } |
| 69351 | - u.ci.pCur->nullRow = 0; | |
| 69387 | + u.cl.pCur->nullRow = 0; | |
| 69352 | 69388 | |
| 69353 | 69389 | break; |
| 69354 | 69390 | } |
| 69355 | 69391 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69356 | 69392 | |
| @@ -69360,55 +69396,55 @@ | ||
| 69360 | 69396 | ** Store the value of the P2-th column of |
| 69361 | 69397 | ** the row of the virtual-table that the |
| 69362 | 69398 | ** P1 cursor is pointing to into register P3. |
| 69363 | 69399 | */ |
| 69364 | 69400 | case OP_VColumn: { |
| 69365 | -#if 0 /* local variables moved into u.cj */ | |
| 69401 | +#if 0 /* local variables moved into u.cm */ | |
| 69366 | 69402 | sqlite3_vtab *pVtab; |
| 69367 | 69403 | const sqlite3_module *pModule; |
| 69368 | 69404 | Mem *pDest; |
| 69369 | 69405 | sqlite3_context sContext; |
| 69370 | -#endif /* local variables moved into u.cj */ | |
| 69406 | +#endif /* local variables moved into u.cm */ | |
| 69371 | 69407 | |
| 69372 | 69408 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 69373 | 69409 | assert( pCur->pVtabCursor ); |
| 69374 | 69410 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69375 | - u.cj.pDest = &aMem[pOp->p3]; | |
| 69376 | - memAboutToChange(p, u.cj.pDest); | |
| 69411 | + u.cm.pDest = &aMem[pOp->p3]; | |
| 69412 | + memAboutToChange(p, u.cm.pDest); | |
| 69377 | 69413 | if( pCur->nullRow ){ |
| 69378 | - sqlite3VdbeMemSetNull(u.cj.pDest); | |
| 69414 | + sqlite3VdbeMemSetNull(u.cm.pDest); | |
| 69379 | 69415 | break; |
| 69380 | 69416 | } |
| 69381 | - u.cj.pVtab = pCur->pVtabCursor->pVtab; | |
| 69382 | - u.cj.pModule = u.cj.pVtab->pModule; | |
| 69383 | - assert( u.cj.pModule->xColumn ); | |
| 69384 | - memset(&u.cj.sContext, 0, sizeof(u.cj.sContext)); | |
| 69417 | + u.cm.pVtab = pCur->pVtabCursor->pVtab; | |
| 69418 | + u.cm.pModule = u.cm.pVtab->pModule; | |
| 69419 | + assert( u.cm.pModule->xColumn ); | |
| 69420 | + memset(&u.cm.sContext, 0, sizeof(u.cm.sContext)); | |
| 69385 | 69421 | |
| 69386 | 69422 | /* The output cell may already have a buffer allocated. Move |
| 69387 | - ** the current contents to u.cj.sContext.s so in case the user-function | |
| 69423 | + ** the current contents to u.cm.sContext.s so in case the user-function | |
| 69388 | 69424 | ** can use the already allocated buffer instead of allocating a |
| 69389 | 69425 | ** new one. |
| 69390 | 69426 | */ |
| 69391 | - sqlite3VdbeMemMove(&u.cj.sContext.s, u.cj.pDest); | |
| 69392 | - MemSetTypeFlag(&u.cj.sContext.s, MEM_Null); | |
| 69427 | + sqlite3VdbeMemMove(&u.cm.sContext.s, u.cm.pDest); | |
| 69428 | + MemSetTypeFlag(&u.cm.sContext.s, MEM_Null); | |
| 69393 | 69429 | |
| 69394 | - rc = u.cj.pModule->xColumn(pCur->pVtabCursor, &u.cj.sContext, pOp->p2); | |
| 69395 | - importVtabErrMsg(p, u.cj.pVtab); | |
| 69396 | - if( u.cj.sContext.isError ){ | |
| 69397 | - rc = u.cj.sContext.isError; | |
| 69430 | + rc = u.cm.pModule->xColumn(pCur->pVtabCursor, &u.cm.sContext, pOp->p2); | |
| 69431 | + importVtabErrMsg(p, u.cm.pVtab); | |
| 69432 | + if( u.cm.sContext.isError ){ | |
| 69433 | + rc = u.cm.sContext.isError; | |
| 69398 | 69434 | } |
| 69399 | 69435 | |
| 69400 | 69436 | /* Copy the result of the function to the P3 register. We |
| 69401 | 69437 | ** do this regardless of whether or not an error occurred to ensure any |
| 69402 | - ** dynamic allocation in u.cj.sContext.s (a Mem struct) is released. | |
| 69438 | + ** dynamic allocation in u.cm.sContext.s (a Mem struct) is released. | |
| 69403 | 69439 | */ |
| 69404 | - sqlite3VdbeChangeEncoding(&u.cj.sContext.s, encoding); | |
| 69405 | - sqlite3VdbeMemMove(u.cj.pDest, &u.cj.sContext.s); | |
| 69406 | - REGISTER_TRACE(pOp->p3, u.cj.pDest); | |
| 69407 | - UPDATE_MAX_BLOBSIZE(u.cj.pDest); | |
| 69440 | + sqlite3VdbeChangeEncoding(&u.cm.sContext.s, encoding); | |
| 69441 | + sqlite3VdbeMemMove(u.cm.pDest, &u.cm.sContext.s); | |
| 69442 | + REGISTER_TRACE(pOp->p3, u.cm.pDest); | |
| 69443 | + UPDATE_MAX_BLOBSIZE(u.cm.pDest); | |
| 69408 | 69444 | |
| 69409 | - if( sqlite3VdbeMemTooBig(u.cj.pDest) ){ | |
| 69445 | + if( sqlite3VdbeMemTooBig(u.cm.pDest) ){ | |
| 69410 | 69446 | goto too_big; |
| 69411 | 69447 | } |
| 69412 | 69448 | break; |
| 69413 | 69449 | } |
| 69414 | 69450 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69419,42 +69455,42 @@ | ||
| 69419 | 69455 | ** Advance virtual table P1 to the next row in its result set and |
| 69420 | 69456 | ** jump to instruction P2. Or, if the virtual table has reached |
| 69421 | 69457 | ** the end of its result set, then fall through to the next instruction. |
| 69422 | 69458 | */ |
| 69423 | 69459 | case OP_VNext: { /* jump */ |
| 69424 | -#if 0 /* local variables moved into u.ck */ | |
| 69460 | +#if 0 /* local variables moved into u.cn */ | |
| 69425 | 69461 | sqlite3_vtab *pVtab; |
| 69426 | 69462 | const sqlite3_module *pModule; |
| 69427 | 69463 | int res; |
| 69428 | 69464 | VdbeCursor *pCur; |
| 69429 | -#endif /* local variables moved into u.ck */ | |
| 69465 | +#endif /* local variables moved into u.cn */ | |
| 69430 | 69466 | |
| 69431 | - u.ck.res = 0; | |
| 69432 | - u.ck.pCur = p->apCsr[pOp->p1]; | |
| 69433 | - assert( u.ck.pCur->pVtabCursor ); | |
| 69434 | - if( u.ck.pCur->nullRow ){ | |
| 69467 | + u.cn.res = 0; | |
| 69468 | + u.cn.pCur = p->apCsr[pOp->p1]; | |
| 69469 | + assert( u.cn.pCur->pVtabCursor ); | |
| 69470 | + if( u.cn.pCur->nullRow ){ | |
| 69435 | 69471 | break; |
| 69436 | 69472 | } |
| 69437 | - u.ck.pVtab = u.ck.pCur->pVtabCursor->pVtab; | |
| 69438 | - u.ck.pModule = u.ck.pVtab->pModule; | |
| 69439 | - assert( u.ck.pModule->xNext ); | |
| 69473 | + u.cn.pVtab = u.cn.pCur->pVtabCursor->pVtab; | |
| 69474 | + u.cn.pModule = u.cn.pVtab->pModule; | |
| 69475 | + assert( u.cn.pModule->xNext ); | |
| 69440 | 69476 | |
| 69441 | 69477 | /* Invoke the xNext() method of the module. There is no way for the |
| 69442 | 69478 | ** underlying implementation to return an error if one occurs during |
| 69443 | 69479 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 69444 | 69480 | ** data is available) and the error code returned when xColumn or |
| 69445 | 69481 | ** some other method is next invoked on the save virtual table cursor. |
| 69446 | 69482 | */ |
| 69447 | 69483 | p->inVtabMethod = 1; |
| 69448 | - rc = u.ck.pModule->xNext(u.ck.pCur->pVtabCursor); | |
| 69484 | + rc = u.cn.pModule->xNext(u.cn.pCur->pVtabCursor); | |
| 69449 | 69485 | p->inVtabMethod = 0; |
| 69450 | - importVtabErrMsg(p, u.ck.pVtab); | |
| 69486 | + importVtabErrMsg(p, u.cn.pVtab); | |
| 69451 | 69487 | if( rc==SQLITE_OK ){ |
| 69452 | - u.ck.res = u.ck.pModule->xEof(u.ck.pCur->pVtabCursor); | |
| 69488 | + u.cn.res = u.cn.pModule->xEof(u.cn.pCur->pVtabCursor); | |
| 69453 | 69489 | } |
| 69454 | 69490 | |
| 69455 | - if( !u.ck.res ){ | |
| 69491 | + if( !u.cn.res ){ | |
| 69456 | 69492 | /* If there is data, jump to P2 */ |
| 69457 | 69493 | pc = pOp->p2 - 1; |
| 69458 | 69494 | } |
| 69459 | 69495 | break; |
| 69460 | 69496 | } |
| @@ -69466,23 +69502,23 @@ | ||
| 69466 | 69502 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69467 | 69503 | ** This opcode invokes the corresponding xRename method. The value |
| 69468 | 69504 | ** in register P1 is passed as the zName argument to the xRename method. |
| 69469 | 69505 | */ |
| 69470 | 69506 | case OP_VRename: { |
| 69471 | -#if 0 /* local variables moved into u.cl */ | |
| 69507 | +#if 0 /* local variables moved into u.co */ | |
| 69472 | 69508 | sqlite3_vtab *pVtab; |
| 69473 | 69509 | Mem *pName; |
| 69474 | -#endif /* local variables moved into u.cl */ | |
| 69475 | - | |
| 69476 | - u.cl.pVtab = pOp->p4.pVtab->pVtab; | |
| 69477 | - u.cl.pName = &aMem[pOp->p1]; | |
| 69478 | - assert( u.cl.pVtab->pModule->xRename ); | |
| 69479 | - assert( memIsValid(u.cl.pName) ); | |
| 69480 | - REGISTER_TRACE(pOp->p1, u.cl.pName); | |
| 69481 | - assert( u.cl.pName->flags & MEM_Str ); | |
| 69482 | - rc = u.cl.pVtab->pModule->xRename(u.cl.pVtab, u.cl.pName->z); | |
| 69483 | - importVtabErrMsg(p, u.cl.pVtab); | |
| 69510 | +#endif /* local variables moved into u.co */ | |
| 69511 | + | |
| 69512 | + u.co.pVtab = pOp->p4.pVtab->pVtab; | |
| 69513 | + u.co.pName = &aMem[pOp->p1]; | |
| 69514 | + assert( u.co.pVtab->pModule->xRename ); | |
| 69515 | + assert( memIsValid(u.co.pName) ); | |
| 69516 | + REGISTER_TRACE(pOp->p1, u.co.pName); | |
| 69517 | + assert( u.co.pName->flags & MEM_Str ); | |
| 69518 | + rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z); | |
| 69519 | + importVtabErrMsg(p, u.co.pVtab); | |
| 69484 | 69520 | p->expired = 0; |
| 69485 | 69521 | |
| 69486 | 69522 | break; |
| 69487 | 69523 | } |
| 69488 | 69524 | #endif |
| @@ -69510,45 +69546,45 @@ | ||
| 69510 | 69546 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 69511 | 69547 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 69512 | 69548 | ** is set to the value of the rowid for the row just inserted. |
| 69513 | 69549 | */ |
| 69514 | 69550 | case OP_VUpdate: { |
| 69515 | -#if 0 /* local variables moved into u.cm */ | |
| 69551 | +#if 0 /* local variables moved into u.cp */ | |
| 69516 | 69552 | sqlite3_vtab *pVtab; |
| 69517 | 69553 | sqlite3_module *pModule; |
| 69518 | 69554 | int nArg; |
| 69519 | 69555 | int i; |
| 69520 | 69556 | sqlite_int64 rowid; |
| 69521 | 69557 | Mem **apArg; |
| 69522 | 69558 | Mem *pX; |
| 69523 | -#endif /* local variables moved into u.cm */ | |
| 69559 | +#endif /* local variables moved into u.cp */ | |
| 69524 | 69560 | |
| 69525 | 69561 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 69526 | 69562 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 69527 | 69563 | ); |
| 69528 | - u.cm.pVtab = pOp->p4.pVtab->pVtab; | |
| 69529 | - u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; | |
| 69530 | - u.cm.nArg = pOp->p2; | |
| 69564 | + u.cp.pVtab = pOp->p4.pVtab->pVtab; | |
| 69565 | + u.cp.pModule = (sqlite3_module *)u.cp.pVtab->pModule; | |
| 69566 | + u.cp.nArg = pOp->p2; | |
| 69531 | 69567 | assert( pOp->p4type==P4_VTAB ); |
| 69532 | - if( ALWAYS(u.cm.pModule->xUpdate) ){ | |
| 69568 | + if( ALWAYS(u.cp.pModule->xUpdate) ){ | |
| 69533 | 69569 | u8 vtabOnConflict = db->vtabOnConflict; |
| 69534 | - u.cm.apArg = p->apArg; | |
| 69535 | - u.cm.pX = &aMem[pOp->p3]; | |
| 69536 | - for(u.cm.i=0; u.cm.i<u.cm.nArg; u.cm.i++){ | |
| 69537 | - assert( memIsValid(u.cm.pX) ); | |
| 69538 | - memAboutToChange(p, u.cm.pX); | |
| 69539 | - sqlite3VdbeMemStoreType(u.cm.pX); | |
| 69540 | - u.cm.apArg[u.cm.i] = u.cm.pX; | |
| 69541 | - u.cm.pX++; | |
| 69570 | + u.cp.apArg = p->apArg; | |
| 69571 | + u.cp.pX = &aMem[pOp->p3]; | |
| 69572 | + for(u.cp.i=0; u.cp.i<u.cp.nArg; u.cp.i++){ | |
| 69573 | + assert( memIsValid(u.cp.pX) ); | |
| 69574 | + memAboutToChange(p, u.cp.pX); | |
| 69575 | + sqlite3VdbeMemStoreType(u.cp.pX); | |
| 69576 | + u.cp.apArg[u.cp.i] = u.cp.pX; | |
| 69577 | + u.cp.pX++; | |
| 69542 | 69578 | } |
| 69543 | 69579 | db->vtabOnConflict = pOp->p5; |
| 69544 | - rc = u.cm.pModule->xUpdate(u.cm.pVtab, u.cm.nArg, u.cm.apArg, &u.cm.rowid); | |
| 69580 | + rc = u.cp.pModule->xUpdate(u.cp.pVtab, u.cp.nArg, u.cp.apArg, &u.cp.rowid); | |
| 69545 | 69581 | db->vtabOnConflict = vtabOnConflict; |
| 69546 | - importVtabErrMsg(p, u.cm.pVtab); | |
| 69582 | + importVtabErrMsg(p, u.cp.pVtab); | |
| 69547 | 69583 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 69548 | - assert( u.cm.nArg>1 && u.cm.apArg[0] && (u.cm.apArg[0]->flags&MEM_Null) ); | |
| 69549 | - db->lastRowid = lastRowid = u.cm.rowid; | |
| 69584 | + assert( u.cp.nArg>1 && u.cp.apArg[0] && (u.cp.apArg[0]->flags&MEM_Null) ); | |
| 69585 | + db->lastRowid = lastRowid = u.cp.rowid; | |
| 69550 | 69586 | } |
| 69551 | 69587 | if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 69552 | 69588 | if( pOp->p5==OE_Ignore ){ |
| 69553 | 69589 | rc = SQLITE_OK; |
| 69554 | 69590 | }else{ |
| @@ -69604,25 +69640,25 @@ | ||
| 69604 | 69640 | ** |
| 69605 | 69641 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 69606 | 69642 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 69607 | 69643 | */ |
| 69608 | 69644 | case OP_Trace: { |
| 69609 | -#if 0 /* local variables moved into u.cn */ | |
| 69645 | +#if 0 /* local variables moved into u.cq */ | |
| 69610 | 69646 | char *zTrace; |
| 69611 | 69647 | char *z; |
| 69612 | -#endif /* local variables moved into u.cn */ | |
| 69648 | +#endif /* local variables moved into u.cq */ | |
| 69613 | 69649 | |
| 69614 | - if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ | |
| 69615 | - u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); | |
| 69616 | - db->xTrace(db->pTraceArg, u.cn.z); | |
| 69617 | - sqlite3DbFree(db, u.cn.z); | |
| 69650 | + if( db->xTrace && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ | |
| 69651 | + u.cq.z = sqlite3VdbeExpandSql(p, u.cq.zTrace); | |
| 69652 | + db->xTrace(db->pTraceArg, u.cq.z); | |
| 69653 | + sqlite3DbFree(db, u.cq.z); | |
| 69618 | 69654 | } |
| 69619 | 69655 | #ifdef SQLITE_DEBUG |
| 69620 | 69656 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 69621 | - && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 | |
| 69657 | + && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 | |
| 69622 | 69658 | ){ |
| 69623 | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); | |
| 69659 | + sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); | |
| 69624 | 69660 | } |
| 69625 | 69661 | #endif /* SQLITE_DEBUG */ |
| 69626 | 69662 | break; |
| 69627 | 69663 | } |
| 69628 | 69664 | #endif |
| @@ -70239,10 +70275,11 @@ | ||
| 70239 | 70275 | |
| 70240 | 70276 | |
| 70241 | 70277 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70242 | 70278 | |
| 70243 | 70279 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70280 | +typedef struct SorterRecord SorterRecord; | |
| 70244 | 70281 | |
| 70245 | 70282 | /* |
| 70246 | 70283 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70247 | 70284 | ** |
| 70248 | 70285 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70310,19 +70347,23 @@ | ||
| 70310 | 70347 | ** In other words, each time we advance to the next sorter element, log2(N) |
| 70311 | 70348 | ** key comparison operations are required, where N is the number of segments |
| 70312 | 70349 | ** being merged (rounded up to the next power of 2). |
| 70313 | 70350 | */ |
| 70314 | 70351 | struct VdbeSorter { |
| 70315 | - int nWorking; /* Start a new b-tree after this many pages */ | |
| 70316 | - int nBtree; /* Current size of b-tree contents as PMA */ | |
| 70352 | + int nInMemory; /* Current size of pRecord list as PMA */ | |
| 70317 | 70353 | int nTree; /* Used size of aTree/aIter (power of 2) */ |
| 70318 | 70354 | VdbeSorterIter *aIter; /* Array of iterators to merge */ |
| 70319 | 70355 | int *aTree; /* Current state of incremental merge */ |
| 70320 | 70356 | i64 iWriteOff; /* Current write offset within file pTemp1 */ |
| 70321 | 70357 | i64 iReadOff; /* Current read offset within file pTemp1 */ |
| 70322 | 70358 | sqlite3_file *pTemp1; /* PMA file 1 */ |
| 70323 | 70359 | int nPMA; /* Number of PMAs stored in pTemp1 */ |
| 70360 | + SorterRecord *pRecord; /* Head of in-memory record list */ | |
| 70361 | + int mnPmaSize; /* Minimum PMA size, in bytes */ | |
| 70362 | + int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ | |
| 70363 | + char *aSpace; /* Space for UnpackRecord() */ | |
| 70364 | + int nSpace; /* Size of aSpace in bytes */ | |
| 70324 | 70365 | }; |
| 70325 | 70366 | |
| 70326 | 70367 | /* |
| 70327 | 70368 | ** The following type is an iterator for a PMA. It caches the current key in |
| 70328 | 70369 | ** variables nKey/aKey. If the iterator is at EOF, pFile==0. |
| @@ -70334,10 +70375,21 @@ | ||
| 70334 | 70375 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70335 | 70376 | u8 *aAlloc; /* Allocated space */ |
| 70336 | 70377 | int nKey; /* Number of bytes in key */ |
| 70337 | 70378 | u8 *aKey; /* Pointer to current key */ |
| 70338 | 70379 | }; |
| 70380 | + | |
| 70381 | +/* | |
| 70382 | +** A structure to store a single record. All in-memory records are connected | |
| 70383 | +** together into a linked list headed at VdbeSorter.pRecord using the | |
| 70384 | +** SorterRecord.pNext pointer. | |
| 70385 | +*/ | |
| 70386 | +struct SorterRecord { | |
| 70387 | + void *pVal; | |
| 70388 | + int nVal; | |
| 70389 | + SorterRecord *pNext; | |
| 70390 | +}; | |
| 70339 | 70391 | |
| 70340 | 70392 | /* Minimum allowable value for the VdbeSorter.nWorking variable */ |
| 70341 | 70393 | #define SORTER_MIN_WORKING 10 |
| 70342 | 70394 | |
| 70343 | 70395 | /* Maximum number of segments to merge in a single pass. */ |
| @@ -70360,12 +70412,12 @@ | ||
| 70360 | 70412 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70361 | 70413 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70362 | 70414 | ){ |
| 70363 | 70415 | int rc; /* Return Code */ |
| 70364 | 70416 | int nRead; /* Number of bytes read */ |
| 70365 | - int nRec; /* Size of record in bytes */ | |
| 70366 | - int iOff; /* Size of serialized size varint in bytes */ | |
| 70417 | + int nRec = 0; /* Size of record in bytes */ | |
| 70418 | + int iOff = 0; /* Size of serialized size varint in bytes */ | |
| 70367 | 70419 | |
| 70368 | 70420 | nRead = pIter->iEof - pIter->iReadOff; |
| 70369 | 70421 | if( nRead>5 ) nRead = 5; |
| 70370 | 70422 | if( nRead<=0 ){ |
| 70371 | 70423 | /* This is an EOF condition */ |
| @@ -70372,29 +70424,30 @@ | ||
| 70372 | 70424 | vdbeSorterIterZero(db, pIter); |
| 70373 | 70425 | return SQLITE_OK; |
| 70374 | 70426 | } |
| 70375 | 70427 | |
| 70376 | 70428 | rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); |
| 70377 | - iOff = getVarint32(pIter->aAlloc, nRec); | |
| 70378 | - | |
| 70379 | - if( rc==SQLITE_OK && (iOff+nRec)>nRead ){ | |
| 70380 | - int nRead2; /* Number of extra bytes to read */ | |
| 70381 | - if( (iOff+nRec)>pIter->nAlloc ){ | |
| 70382 | - int nNew = pIter->nAlloc*2; | |
| 70383 | - while( (iOff+nRec)>nNew ) nNew = nNew*2; | |
| 70384 | - pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); | |
| 70385 | - if( !pIter->aAlloc ) return SQLITE_NOMEM; | |
| 70386 | - pIter->nAlloc = nNew; | |
| 70387 | - } | |
| 70388 | - | |
| 70389 | - nRead2 = iOff + nRec - nRead; | |
| 70390 | - rc = sqlite3OsRead( | |
| 70391 | - pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead | |
| 70392 | - ); | |
| 70393 | - } | |
| 70394 | - | |
| 70395 | - assert( nRec>0 || rc!=SQLITE_OK ); | |
| 70429 | + if( rc==SQLITE_OK ){ | |
| 70430 | + iOff = getVarint32(pIter->aAlloc, nRec); | |
| 70431 | + if( (iOff+nRec)>nRead ){ | |
| 70432 | + int nRead2; /* Number of extra bytes to read */ | |
| 70433 | + if( (iOff+nRec)>pIter->nAlloc ){ | |
| 70434 | + int nNew = pIter->nAlloc*2; | |
| 70435 | + while( (iOff+nRec)>nNew ) nNew = nNew*2; | |
| 70436 | + pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); | |
| 70437 | + if( !pIter->aAlloc ) return SQLITE_NOMEM; | |
| 70438 | + pIter->nAlloc = nNew; | |
| 70439 | + } | |
| 70440 | + | |
| 70441 | + nRead2 = iOff + nRec - nRead; | |
| 70442 | + rc = sqlite3OsRead( | |
| 70443 | + pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead | |
| 70444 | + ); | |
| 70445 | + } | |
| 70446 | + } | |
| 70447 | + | |
| 70448 | + assert( rc!=SQLITE_OK || nRec>0 ); | |
| 70396 | 70449 | pIter->iReadOff += iOff+nRec; |
| 70397 | 70450 | pIter->nKey = nRec; |
| 70398 | 70451 | pIter->aKey = &pIter->aAlloc[iOff]; |
| 70399 | 70452 | return rc; |
| 70400 | 70453 | } |
| @@ -70434,25 +70487,18 @@ | ||
| 70434 | 70487 | ** set to the integer value read. If an error occurs, the final values of |
| 70435 | 70488 | ** both *piOffset and *piVal are undefined. |
| 70436 | 70489 | */ |
| 70437 | 70490 | static int vdbeSorterReadVarint( |
| 70438 | 70491 | sqlite3_file *pFile, /* File to read from */ |
| 70439 | - i64 iEof, /* Total number of bytes in file */ | |
| 70440 | 70492 | i64 *piOffset, /* IN/OUT: Read offset in pFile */ |
| 70441 | 70493 | i64 *piVal /* OUT: Value read from file */ |
| 70442 | 70494 | ){ |
| 70443 | 70495 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70444 | 70496 | i64 iOff = *piOffset; /* Offset in file to read from */ |
| 70445 | - int nRead = 9; /* Number of bytes to read from file */ | |
| 70446 | 70497 | int rc; /* Return code */ |
| 70447 | 70498 | |
| 70448 | - assert( iEof>iOff ); | |
| 70449 | - if( (iEof-iOff)<nRead ){ | |
| 70450 | - nRead = iEof-iOff; | |
| 70451 | - } | |
| 70452 | - | |
| 70453 | - rc = sqlite3OsRead(pFile, aVarint, nRead, iOff); | |
| 70499 | + rc = sqlite3OsRead(pFile, aVarint, 9, iOff); | |
| 70454 | 70500 | if( rc==SQLITE_OK ){ |
| 70455 | 70501 | *piOffset += getVarint(aVarint, (u64 *)piVal); |
| 70456 | 70502 | } |
| 70457 | 70503 | |
| 70458 | 70504 | return rc; |
| @@ -70480,22 +70526,85 @@ | ||
| 70480 | 70526 | pIter->nAlloc = 128; |
| 70481 | 70527 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70482 | 70528 | if( !pIter->aAlloc ){ |
| 70483 | 70529 | rc = SQLITE_NOMEM; |
| 70484 | 70530 | }else{ |
| 70485 | - i64 iEof = pSorter->iWriteOff; /* EOF of file pSorter->pTemp1 */ | |
| 70486 | 70531 | i64 nByte; /* Total size of PMA in bytes */ |
| 70487 | - rc = vdbeSorterReadVarint(pSorter->pTemp1, iEof, &pIter->iReadOff, &nByte); | |
| 70532 | + rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); | |
| 70488 | 70533 | *pnByte += nByte; |
| 70489 | 70534 | pIter->iEof = pIter->iReadOff + nByte; |
| 70490 | 70535 | } |
| 70491 | 70536 | if( rc==SQLITE_OK ){ |
| 70492 | 70537 | rc = vdbeSorterIterNext(db, pIter); |
| 70493 | 70538 | } |
| 70494 | 70539 | return rc; |
| 70495 | 70540 | } |
| 70496 | 70541 | |
| 70542 | + | |
| 70543 | +/* | |
| 70544 | +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, | |
| 70545 | +** size nKey2 bytes). Argument pKeyInfo supplies the collation functions | |
| 70546 | +** used by the comparison. If an error occurs, return an SQLite error code. | |
| 70547 | +** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive | |
| 70548 | +** value, depending on whether key1 is smaller, equal to or larger than key2. | |
| 70549 | +** | |
| 70550 | +** If the bOmitRowid argument is non-zero, assume both keys end in a rowid | |
| 70551 | +** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid | |
| 70552 | +** is true and key1 contains even a single NULL value, it is considered to | |
| 70553 | +** be less than key2. Even if key2 also contains NULL values. | |
| 70554 | +** | |
| 70555 | +** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace | |
| 70556 | +** has been allocated and contains an unpacked record that is used as key2. | |
| 70557 | +*/ | |
| 70558 | +static int vdbeSorterCompare( | |
| 70559 | + VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ | |
| 70560 | + int bOmitRowid, /* Ignore rowid field at end of keys */ | |
| 70561 | + void *pKey1, int nKey1, /* Left side of comparison */ | |
| 70562 | + void *pKey2, int nKey2, /* Right side of comparison */ | |
| 70563 | + int *pRes /* OUT: Result of comparison */ | |
| 70564 | +){ | |
| 70565 | + KeyInfo *pKeyInfo = pCsr->pKeyInfo; | |
| 70566 | + VdbeSorter *pSorter = pCsr->pSorter; | |
| 70567 | + char *aSpace = pSorter->aSpace; | |
| 70568 | + int nSpace = pSorter->nSpace; | |
| 70569 | + UnpackedRecord *r2; | |
| 70570 | + int i; | |
| 70571 | + | |
| 70572 | + if( aSpace==0 ){ | |
| 70573 | + nSpace = ROUND8(sizeof(UnpackedRecord))+(pKeyInfo->nField+1)*sizeof(Mem); | |
| 70574 | + aSpace = (char *)sqlite3Malloc(nSpace); | |
| 70575 | + if( aSpace==0 ) return SQLITE_NOMEM; | |
| 70576 | + pSorter->aSpace = aSpace; | |
| 70577 | + pSorter->nSpace = nSpace; | |
| 70578 | + } | |
| 70579 | + | |
| 70580 | + if( pKey2 ){ | |
| 70581 | + /* This call cannot fail. As the memory is already allocated. */ | |
| 70582 | + r2 = sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, aSpace, nSpace); | |
| 70583 | + assert( r2 && (r2->flags & UNPACKED_NEED_FREE)==0 ); | |
| 70584 | + assert( r2==(UnpackedRecord*)aSpace ); | |
| 70585 | + }else{ | |
| 70586 | + r2 = (UnpackedRecord *)aSpace; | |
| 70587 | + assert( !bOmitRowid ); | |
| 70588 | + } | |
| 70589 | + | |
| 70590 | + if( bOmitRowid ){ | |
| 70591 | + for(i=0; i<r2->nField-1; i++){ | |
| 70592 | + if( r2->aMem[i].flags & MEM_Null ){ | |
| 70593 | + *pRes = -1; | |
| 70594 | + return SQLITE_OK; | |
| 70595 | + } | |
| 70596 | + } | |
| 70597 | + r2->flags |= UNPACKED_PREFIX_MATCH; | |
| 70598 | + r2->nField--; | |
| 70599 | + assert( r2->nField>0 ); | |
| 70600 | + } | |
| 70601 | + | |
| 70602 | + *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); | |
| 70603 | + return SQLITE_OK; | |
| 70604 | +} | |
| 70605 | + | |
| 70497 | 70606 | /* |
| 70498 | 70607 | ** This function is called to compare two iterator keys when merging |
| 70499 | 70608 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70500 | 70609 | ** value to recalculate. |
| 70501 | 70610 | */ |
| @@ -70523,24 +70632,25 @@ | ||
| 70523 | 70632 | if( p1->pFile==0 ){ |
| 70524 | 70633 | iRes = i2; |
| 70525 | 70634 | }else if( p2->pFile==0 ){ |
| 70526 | 70635 | iRes = i1; |
| 70527 | 70636 | }else{ |
| 70528 | - char aSpace[150]; | |
| 70529 | - UnpackedRecord *r1; | |
| 70530 | - | |
| 70531 | - r1 = sqlite3VdbeRecordUnpack( | |
| 70532 | - pCsr->pKeyInfo, p1->nKey, p1->aKey, aSpace, sizeof(aSpace) | |
| 70637 | + int res; | |
| 70638 | + int rc; | |
| 70639 | + assert( pCsr->pSorter->aSpace!=0 ); /* allocated in vdbeSorterMerge() */ | |
| 70640 | + rc = vdbeSorterCompare( | |
| 70641 | + pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res | |
| 70533 | 70642 | ); |
| 70534 | - if( r1==0 ) return SQLITE_NOMEM; | |
| 70643 | + /* The vdbeSorterCompare() call cannot fail since pCsr->pSorter->aSpace | |
| 70644 | + ** has already been allocated. */ | |
| 70645 | + assert( rc==SQLITE_OK ); | |
| 70535 | 70646 | |
| 70536 | - if( sqlite3VdbeRecordCompare(p2->nKey, p2->aKey, r1)>=0 ){ | |
| 70647 | + if( res<=0 ){ | |
| 70537 | 70648 | iRes = i1; |
| 70538 | 70649 | }else{ |
| 70539 | 70650 | iRes = i2; |
| 70540 | 70651 | } |
| 70541 | - sqlite3VdbeDeleteUnpackedRecord(r1); | |
| 70542 | 70652 | } |
| 70543 | 70653 | |
| 70544 | 70654 | pSorter->aTree[iOut] = iRes; |
| 70545 | 70655 | return SQLITE_OK; |
| 70546 | 70656 | } |
| @@ -70547,13 +70657,41 @@ | ||
| 70547 | 70657 | |
| 70548 | 70658 | /* |
| 70549 | 70659 | ** Initialize the temporary index cursor just opened as a sorter cursor. |
| 70550 | 70660 | */ |
| 70551 | 70661 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ |
| 70552 | - assert( pCsr->pKeyInfo && pCsr->pBt ); | |
| 70553 | - pCsr->pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); | |
| 70554 | - return (pCsr->pSorter ? SQLITE_OK : SQLITE_NOMEM); | |
| 70662 | + int pgsz; /* Page size of main database */ | |
| 70663 | + int mxCache; /* Cache size */ | |
| 70664 | + VdbeSorter *pSorter; /* The new sorter */ | |
| 70665 | + | |
| 70666 | + assert( pCsr->pKeyInfo && pCsr->pBt==0 ); | |
| 70667 | + pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); | |
| 70668 | + if( pSorter==0 ){ | |
| 70669 | + return SQLITE_NOMEM; | |
| 70670 | + } | |
| 70671 | + | |
| 70672 | + if( !sqlite3TempInMemory(db) ){ | |
| 70673 | + pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); | |
| 70674 | + pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; | |
| 70675 | + mxCache = db->aDb[0].pSchema->cache_size; | |
| 70676 | + if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; | |
| 70677 | + pSorter->mxPmaSize = mxCache * pgsz; | |
| 70678 | + } | |
| 70679 | + | |
| 70680 | + return SQLITE_OK; | |
| 70681 | +} | |
| 70682 | + | |
| 70683 | +/* | |
| 70684 | +** Free the list of sorted records starting at pRecord. | |
| 70685 | +*/ | |
| 70686 | +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ | |
| 70687 | + SorterRecord *p; | |
| 70688 | + SorterRecord *pNext; | |
| 70689 | + for(p=pRecord; p; p=pNext){ | |
| 70690 | + pNext = p->pNext; | |
| 70691 | + sqlite3DbFree(db, p); | |
| 70692 | + } | |
| 70555 | 70693 | } |
| 70556 | 70694 | |
| 70557 | 70695 | /* |
| 70558 | 70696 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 70559 | 70697 | */ |
| @@ -70568,10 +70706,12 @@ | ||
| 70568 | 70706 | sqlite3DbFree(db, pSorter->aIter); |
| 70569 | 70707 | } |
| 70570 | 70708 | if( pSorter->pTemp1 ){ |
| 70571 | 70709 | sqlite3OsCloseFree(pSorter->pTemp1); |
| 70572 | 70710 | } |
| 70711 | + vdbeSorterRecordFree(db, pSorter->pRecord); | |
| 70712 | + sqlite3_free(pSorter->aSpace); | |
| 70573 | 70713 | sqlite3DbFree(db, pSorter); |
| 70574 | 70714 | pCsr->pSorter = 0; |
| 70575 | 70715 | } |
| 70576 | 70716 | } |
| 70577 | 70717 | |
| @@ -70587,14 +70727,107 @@ | ||
| 70587 | 70727 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| 70588 | 70728 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy |
| 70589 | 70729 | ); |
| 70590 | 70730 | } |
| 70591 | 70731 | |
| 70732 | +/* | |
| 70733 | +** Attemp to merge the two sorted lists p1 and p2 into a single list. If no | |
| 70734 | +** error occurs set *ppOut to the head of the new list and return SQLITE_OK. | |
| 70735 | +*/ | |
| 70736 | +static int vdbeSorterMerge( | |
| 70737 | + sqlite3 *db, /* Database handle */ | |
| 70738 | + VdbeCursor *pCsr, /* For pKeyInfo */ | |
| 70739 | + SorterRecord *p1, /* First list to merge */ | |
| 70740 | + SorterRecord *p2, /* Second list to merge */ | |
| 70741 | + SorterRecord **ppOut /* OUT: Head of merged list */ | |
| 70742 | +){ | |
| 70743 | + int rc = SQLITE_OK; | |
| 70744 | + SorterRecord *pFinal = 0; | |
| 70745 | + SorterRecord **pp = &pFinal; | |
| 70746 | + void *pVal2 = p2 ? p2->pVal : 0; | |
| 70747 | + | |
| 70748 | + while( p1 && p2 ){ | |
| 70749 | + int res; | |
| 70750 | + rc = vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); | |
| 70751 | + if( rc!=SQLITE_OK ){ | |
| 70752 | + *pp = 0; | |
| 70753 | + vdbeSorterRecordFree(db, p1); | |
| 70754 | + vdbeSorterRecordFree(db, p2); | |
| 70755 | + vdbeSorterRecordFree(db, pFinal); | |
| 70756 | + *ppOut = 0; | |
| 70757 | + return rc; | |
| 70758 | + } | |
| 70759 | + if( res<=0 ){ | |
| 70760 | + *pp = p1; | |
| 70761 | + pp = &p1->pNext; | |
| 70762 | + p1 = p1->pNext; | |
| 70763 | + pVal2 = 0; | |
| 70764 | + }else{ | |
| 70765 | + *pp = p2; | |
| 70766 | + pp = &p2->pNext; | |
| 70767 | + p2 = p2->pNext; | |
| 70768 | + if( p2==0 ) break; | |
| 70769 | + pVal2 = p2->pVal; | |
| 70770 | + } | |
| 70771 | + } | |
| 70772 | + *pp = p1 ? p1 : p2; | |
| 70773 | + | |
| 70774 | + *ppOut = pFinal; | |
| 70775 | + return SQLITE_OK; | |
| 70776 | +} | |
| 70592 | 70777 | |
| 70593 | 70778 | /* |
| 70594 | -** Write the current contents of the b-tree to a PMA. Return SQLITE_OK | |
| 70595 | -** if successful, or an SQLite error code otherwise. | |
| 70779 | +** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK | |
| 70780 | +** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error | |
| 70781 | +** occurs. | |
| 70782 | +*/ | |
| 70783 | +static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ | |
| 70784 | + int rc = SQLITE_OK; | |
| 70785 | + int i; | |
| 70786 | + SorterRecord **aSlot; | |
| 70787 | + SorterRecord *p; | |
| 70788 | + VdbeSorter *pSorter = pCsr->pSorter; | |
| 70789 | + | |
| 70790 | + aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); | |
| 70791 | + if( !aSlot ){ | |
| 70792 | + return SQLITE_NOMEM; | |
| 70793 | + } | |
| 70794 | + | |
| 70795 | + p = pSorter->pRecord; | |
| 70796 | + while( p ){ | |
| 70797 | + SorterRecord *pNext = p->pNext; | |
| 70798 | + p->pNext = 0; | |
| 70799 | + for(i=0; rc==SQLITE_OK && aSlot[i]; i++){ | |
| 70800 | + rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); | |
| 70801 | + aSlot[i] = 0; | |
| 70802 | + } | |
| 70803 | + if( rc!=SQLITE_OK ){ | |
| 70804 | + vdbeSorterRecordFree(db, pNext); | |
| 70805 | + break; | |
| 70806 | + } | |
| 70807 | + aSlot[i] = p; | |
| 70808 | + p = pNext; | |
| 70809 | + } | |
| 70810 | + | |
| 70811 | + p = 0; | |
| 70812 | + for(i=0; i<64; i++){ | |
| 70813 | + if( rc==SQLITE_OK ){ | |
| 70814 | + rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); | |
| 70815 | + }else{ | |
| 70816 | + vdbeSorterRecordFree(db, aSlot[i]); | |
| 70817 | + } | |
| 70818 | + } | |
| 70819 | + pSorter->pRecord = p; | |
| 70820 | + | |
| 70821 | + sqlite3_free(aSlot); | |
| 70822 | + return rc; | |
| 70823 | +} | |
| 70824 | + | |
| 70825 | + | |
| 70826 | +/* | |
| 70827 | +** Write the current contents of the in-memory linked-list to a PMA. Return | |
| 70828 | +** SQLITE_OK if successful, or an SQLite error code otherwise. | |
| 70596 | 70829 | ** |
| 70597 | 70830 | ** The format of a PMA is: |
| 70598 | 70831 | ** |
| 70599 | 70832 | ** * A varint. This varint contains the total number of bytes of content |
| 70600 | 70833 | ** in the PMA (not including the varint itself). |
| @@ -70601,153 +70834,111 @@ | ||
| 70601 | 70834 | ** |
| 70602 | 70835 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70603 | 70836 | ** Each record consists of a varint followed by a blob of data (the |
| 70604 | 70837 | ** key). The varint is the number of bytes in the blob of data. |
| 70605 | 70838 | */ |
| 70606 | -static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){ | |
| 70839 | +static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ | |
| 70607 | 70840 | int rc = SQLITE_OK; /* Return code */ |
| 70608 | 70841 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70609 | - int res = 0; | |
| 70610 | 70842 | |
| 70611 | - /* sqlite3BtreeFirst() cannot fail because sorter btrees are always held | |
| 70612 | - ** in memory and so an I/O error is not possible. */ | |
| 70613 | - rc = sqlite3BtreeFirst(pCsr->pCursor, &res); | |
| 70614 | - if( NEVER(rc!=SQLITE_OK) || res ) return rc; | |
| 70615 | - assert( pSorter->nBtree>0 ); | |
| 70843 | + if( pSorter->nInMemory==0 ){ | |
| 70844 | + assert( pSorter->pRecord==0 ); | |
| 70845 | + return rc; | |
| 70846 | + } | |
| 70847 | + | |
| 70848 | + rc = vdbeSorterSort(db, pCsr); | |
| 70616 | 70849 | |
| 70617 | 70850 | /* If the first temporary PMA file has not been opened, open it now. */ |
| 70618 | - if( pSorter->pTemp1==0 ){ | |
| 70851 | + if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ | |
| 70619 | 70852 | rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); |
| 70620 | 70853 | assert( rc!=SQLITE_OK || pSorter->pTemp1 ); |
| 70621 | 70854 | assert( pSorter->iWriteOff==0 ); |
| 70622 | 70855 | assert( pSorter->nPMA==0 ); |
| 70623 | 70856 | } |
| 70624 | 70857 | |
| 70625 | 70858 | if( rc==SQLITE_OK ){ |
| 70626 | - i64 iWriteOff = pSorter->iWriteOff; | |
| 70627 | - void *aMalloc = 0; /* Array used to hold a single record */ | |
| 70628 | - int nMalloc = 0; /* Allocated size of aMalloc[] in bytes */ | |
| 70859 | + i64 iOff = pSorter->iWriteOff; | |
| 70860 | + SorterRecord *p; | |
| 70861 | + SorterRecord *pNext = 0; | |
| 70862 | + static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
| 70629 | 70863 | |
| 70630 | 70864 | pSorter->nPMA++; |
| 70631 | - for( | |
| 70632 | - rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nBtree, &iWriteOff); | |
| 70633 | - rc==SQLITE_OK && res==0; | |
| 70634 | - rc = sqlite3BtreeNext(pCsr->pCursor, &res) | |
| 70635 | - ){ | |
| 70636 | - i64 nKey; /* Size of this key in bytes */ | |
| 70637 | - | |
| 70638 | - /* Write the size of the record in bytes to the output file */ | |
| 70639 | - (void)sqlite3BtreeKeySize(pCsr->pCursor, &nKey); | |
| 70640 | - rc = vdbeSorterWriteVarint(pSorter->pTemp1, nKey, &iWriteOff); | |
| 70641 | - | |
| 70642 | - /* Make sure the aMalloc[] buffer is large enough for the record */ | |
| 70643 | - if( rc==SQLITE_OK && nKey>nMalloc ){ | |
| 70644 | - aMalloc = sqlite3DbReallocOrFree(db, aMalloc, nKey); | |
| 70645 | - if( !aMalloc ){ | |
| 70646 | - rc = SQLITE_NOMEM; | |
| 70647 | - }else{ | |
| 70648 | - nMalloc = nKey; | |
| 70649 | - } | |
| 70650 | - } | |
| 70651 | - | |
| 70652 | - /* Write the record itself to the output file */ | |
| 70865 | + rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); | |
| 70866 | + for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ | |
| 70867 | + pNext = p->pNext; | |
| 70868 | + rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); | |
| 70869 | + | |
| 70653 | 70870 | if( rc==SQLITE_OK ){ |
| 70654 | - /* sqlite3BtreeKey() cannot fail because sorter btrees held in memory */ | |
| 70655 | - rc = sqlite3BtreeKey(pCsr->pCursor, 0, nKey, aMalloc); | |
| 70656 | - if( ALWAYS(rc==SQLITE_OK) ){ | |
| 70657 | - rc = sqlite3OsWrite(pSorter->pTemp1, aMalloc, nKey, iWriteOff); | |
| 70658 | - iWriteOff += nKey; | |
| 70659 | - } | |
| 70871 | + rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); | |
| 70872 | + iOff += p->nVal; | |
| 70660 | 70873 | } |
| 70661 | 70874 | |
| 70662 | - if( rc!=SQLITE_OK ) break; | |
| 70875 | + sqlite3DbFree(db, p); | |
| 70663 | 70876 | } |
| 70664 | 70877 | |
| 70665 | 70878 | /* This assert verifies that unless an error has occurred, the size of |
| 70666 | 70879 | ** the PMA on disk is the same as the expected size stored in |
| 70667 | - ** pSorter->nBtree. */ | |
| 70668 | - assert( rc!=SQLITE_OK || pSorter->nBtree==( | |
| 70669 | - iWriteOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nBtree) | |
| 70880 | + ** pSorter->nInMemory. */ | |
| 70881 | + assert( rc!=SQLITE_OK || pSorter->nInMemory==( | |
| 70882 | + iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) | |
| 70670 | 70883 | )); |
| 70671 | 70884 | |
| 70672 | - pSorter->iWriteOff = iWriteOff; | |
| 70673 | - sqlite3DbFree(db, aMalloc); | |
| 70885 | + pSorter->iWriteOff = iOff; | |
| 70886 | + if( rc==SQLITE_OK ){ | |
| 70887 | + /* Terminate each file with 8 extra bytes so that from any offset | |
| 70888 | + ** in the file we can always read 9 bytes without a SHORT_READ error */ | |
| 70889 | + rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); | |
| 70890 | + } | |
| 70891 | + pSorter->pRecord = p; | |
| 70674 | 70892 | } |
| 70675 | 70893 | |
| 70676 | - pSorter->nBtree = 0; | |
| 70677 | 70894 | return rc; |
| 70678 | 70895 | } |
| 70679 | 70896 | |
| 70680 | 70897 | /* |
| 70681 | -** This function is called on a sorter cursor by the VDBE before each row | |
| 70682 | -** is inserted into VdbeCursor.pCsr. Argument nKey is the size of the key, in | |
| 70683 | -** bytes, about to be inserted. | |
| 70684 | -** | |
| 70685 | -** If it is determined that the temporary b-tree accessed via VdbeCursor.pCsr | |
| 70686 | -** is large enough, its contents are written to a sorted PMA on disk and the | |
| 70687 | -** tree emptied. This prevents the b-tree (which must be small enough to | |
| 70688 | -** fit entirely in the cache in order to support efficient inserts) from | |
| 70689 | -** growing too large. | |
| 70690 | -** | |
| 70691 | -** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. | |
| 70898 | +** Add a record to the sorter. | |
| 70692 | 70899 | */ |
| 70693 | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *db, VdbeCursor *pCsr, int nKey){ | |
| 70694 | - int rc = SQLITE_OK; /* Return code */ | |
| 70900 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( | |
| 70901 | + sqlite3 *db, /* Database handle */ | |
| 70902 | + VdbeCursor *pCsr, /* Sorter cursor */ | |
| 70903 | + Mem *pVal /* Memory cell containing record */ | |
| 70904 | +){ | |
| 70695 | 70905 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70696 | - if( pSorter ){ | |
| 70697 | - Pager *pPager = sqlite3BtreePager(pCsr->pBt); | |
| 70698 | - int nPage; /* Current size of temporary file in pages */ | |
| 70699 | - | |
| 70700 | - /* Sorters never spill to disk */ | |
| 70701 | - assert( sqlite3PagerFile(pPager)->pMethods==0 ); | |
| 70702 | - | |
| 70703 | - /* Determine how many pages the temporary b-tree has grown to */ | |
| 70704 | - sqlite3PagerPagecount(pPager, &nPage); | |
| 70705 | - | |
| 70706 | - /* If pSorter->nWorking is still zero, but the temporary file has been | |
| 70707 | - ** created in the file-system, then the most recent insert into the | |
| 70708 | - ** current b-tree segment probably caused the cache to overflow (it is | |
| 70709 | - ** also possible that sqlite3_release_memory() was called). So set the | |
| 70710 | - ** size of the working set to a little less than the current size of the | |
| 70711 | - ** file in pages. */ | |
| 70712 | - if( pSorter->nWorking==0 && sqlite3PagerUnderStress(pPager) ){ | |
| 70713 | - pSorter->nWorking = nPage-5; | |
| 70714 | - if( pSorter->nWorking<SORTER_MIN_WORKING ){ | |
| 70715 | - pSorter->nWorking = SORTER_MIN_WORKING; | |
| 70716 | - } | |
| 70717 | - } | |
| 70718 | - | |
| 70719 | - /* If the number of pages used by the current b-tree segment is greater | |
| 70720 | - ** than the size of the working set (VdbeSorter.nWorking), start a new | |
| 70721 | - ** segment b-tree. */ | |
| 70722 | - if( pSorter->nWorking && nPage>=pSorter->nWorking ){ | |
| 70723 | - BtCursor *p = pCsr->pCursor;/* Cursor structure to close and reopen */ | |
| 70724 | - int iRoot; /* Root page of new tree */ | |
| 70725 | - | |
| 70726 | - /* Copy the current contents of the b-tree into a PMA in sorted order. | |
| 70727 | - ** Close the currently open b-tree cursor. */ | |
| 70728 | - rc = vdbeSorterBtreeToPMA(db, pCsr); | |
| 70729 | - sqlite3BtreeCloseCursor(p); | |
| 70730 | - | |
| 70731 | - if( rc==SQLITE_OK ){ | |
| 70732 | - rc = sqlite3BtreeDropTable(pCsr->pBt, 2, 0); | |
| 70733 | -#ifdef SQLITE_DEBUG | |
| 70734 | - sqlite3PagerPagecount(pPager, &nPage); | |
| 70735 | - assert( rc!=SQLITE_OK || nPage==1 ); | |
| 70736 | -#endif | |
| 70737 | - } | |
| 70738 | - if( rc==SQLITE_OK ){ | |
| 70739 | - rc = sqlite3BtreeCreateTable(pCsr->pBt, &iRoot, BTREE_BLOBKEY); | |
| 70740 | - } | |
| 70741 | - if( rc==SQLITE_OK ){ | |
| 70742 | - assert( iRoot==2 ); | |
| 70743 | - rc = sqlite3BtreeCursor(pCsr->pBt, iRoot, 1, pCsr->pKeyInfo, p); | |
| 70744 | - } | |
| 70745 | - } | |
| 70746 | - | |
| 70747 | - pSorter->nBtree += sqlite3VarintLen(nKey) + nKey; | |
| 70748 | - } | |
| 70906 | + int rc = SQLITE_OK; /* Return Code */ | |
| 70907 | + SorterRecord *pNew; /* New list element */ | |
| 70908 | + | |
| 70909 | + assert( pSorter ); | |
| 70910 | + pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; | |
| 70911 | + | |
| 70912 | + pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); | |
| 70913 | + if( pNew==0 ){ | |
| 70914 | + rc = SQLITE_NOMEM; | |
| 70915 | + }else{ | |
| 70916 | + pNew->pVal = (void *)&pNew[1]; | |
| 70917 | + memcpy(pNew->pVal, pVal->z, pVal->n); | |
| 70918 | + pNew->nVal = pVal->n; | |
| 70919 | + pNew->pNext = pSorter->pRecord; | |
| 70920 | + pSorter->pRecord = pNew; | |
| 70921 | + } | |
| 70922 | + | |
| 70923 | + /* See if the contents of the sorter should now be written out. They | |
| 70924 | + ** are written out when either of the following are true: | |
| 70925 | + ** | |
| 70926 | + ** * The total memory allocated for the in-memory list is greater | |
| 70927 | + ** than (page-size * cache-size), or | |
| 70928 | + ** | |
| 70929 | + ** * The total memory allocated for the in-memory list is greater | |
| 70930 | + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. | |
| 70931 | + */ | |
| 70932 | + if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( | |
| 70933 | + (pSorter->nInMemory>pSorter->mxPmaSize) | |
| 70934 | + || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) | |
| 70935 | + )){ | |
| 70936 | + rc = vdbeSorterListToPMA(db, pCsr); | |
| 70937 | + pSorter->nInMemory = 0; | |
| 70938 | + } | |
| 70939 | + | |
| 70749 | 70940 | return rc; |
| 70750 | 70941 | } |
| 70751 | 70942 | |
| 70752 | 70943 | /* |
| 70753 | 70944 | ** Helper function for sqlite3VdbeSorterRewind(). |
| @@ -70761,16 +70952,16 @@ | ||
| 70761 | 70952 | int rc = SQLITE_OK; /* Return code */ |
| 70762 | 70953 | int i; /* Used to iterator through aIter[] */ |
| 70763 | 70954 | i64 nByte = 0; /* Total bytes in all opened PMAs */ |
| 70764 | 70955 | |
| 70765 | 70956 | /* Initialize the iterators. */ |
| 70766 | - for(i=0; rc==SQLITE_OK && i<SORTER_MAX_MERGE_COUNT; i++){ | |
| 70957 | + for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){ | |
| 70767 | 70958 | VdbeSorterIter *pIter = &pSorter->aIter[i]; |
| 70768 | 70959 | rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); |
| 70769 | 70960 | pSorter->iReadOff = pIter->iEof; |
| 70770 | - assert( pSorter->iReadOff<=pSorter->iWriteOff || rc!=SQLITE_OK ); | |
| 70771 | - if( pSorter->iReadOff>=pSorter->iWriteOff ) break; | |
| 70961 | + assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff ); | |
| 70962 | + if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break; | |
| 70772 | 70963 | } |
| 70773 | 70964 | |
| 70774 | 70965 | /* Initialize the aTree[] array. */ |
| 70775 | 70966 | for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ |
| 70776 | 70967 | rc = vdbeSorterDoCompare(pCsr, i); |
| @@ -70793,18 +70984,22 @@ | ||
| 70793 | 70984 | int nByte; /* Bytes of space required for aIter/aTree */ |
| 70794 | 70985 | int N = 2; /* Power of 2 >= nIter */ |
| 70795 | 70986 | |
| 70796 | 70987 | assert( pSorter ); |
| 70797 | 70988 | |
| 70798 | - /* Write the current b-tree to a PMA. Close the b-tree cursor. */ | |
| 70799 | - rc = vdbeSorterBtreeToPMA(db, pCsr); | |
| 70800 | - sqlite3BtreeCloseCursor(pCsr->pCursor); | |
| 70801 | - if( rc!=SQLITE_OK ) return rc; | |
| 70989 | + /* If no data has been written to disk, then do not do so now. Instead, | |
| 70990 | + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly | |
| 70991 | + ** from the in-memory list. */ | |
| 70802 | 70992 | if( pSorter->nPMA==0 ){ |
| 70803 | - *pbEof = 1; | |
| 70804 | - return SQLITE_OK; | |
| 70993 | + *pbEof = !pSorter->pRecord; | |
| 70994 | + assert( pSorter->aTree==0 ); | |
| 70995 | + return vdbeSorterSort(db, pCsr); | |
| 70805 | 70996 | } |
| 70997 | + | |
| 70998 | + /* Write the current b-tree to a PMA. Close the b-tree cursor. */ | |
| 70999 | + rc = vdbeSorterListToPMA(db, pCsr); | |
| 71000 | + if( rc!=SQLITE_OK ) return rc; | |
| 70806 | 71001 | |
| 70807 | 71002 | /* Allocate space for aIter[] and aTree[]. */ |
| 70808 | 71003 | nIter = pSorter->nPMA; |
| 70809 | 71004 | if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; |
| 70810 | 71005 | assert( nIter>0 ); |
| @@ -70888,47 +71083,96 @@ | ||
| 70888 | 71083 | /* |
| 70889 | 71084 | ** Advance to the next element in the sorter. |
| 70890 | 71085 | */ |
| 70891 | 71086 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 70892 | 71087 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70893 | - int iPrev = pSorter->aTree[1]; /* Index of iterator to advance */ | |
| 70894 | - int i; /* Index of aTree[] to recalculate */ | |
| 70895 | 71088 | int rc; /* Return code */ |
| 70896 | 71089 | |
| 70897 | - rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); | |
| 70898 | - for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ | |
| 70899 | - rc = vdbeSorterDoCompare(pCsr, i); | |
| 71090 | + if( pSorter->aTree ){ | |
| 71091 | + int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ | |
| 71092 | + int i; /* Index of aTree[] to recalculate */ | |
| 71093 | + | |
| 71094 | + rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); | |
| 71095 | + for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ | |
| 71096 | + rc = vdbeSorterDoCompare(pCsr, i); | |
| 71097 | + } | |
| 71098 | + | |
| 71099 | + *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); | |
| 71100 | + }else{ | |
| 71101 | + SorterRecord *pFree = pSorter->pRecord; | |
| 71102 | + pSorter->pRecord = pFree->pNext; | |
| 71103 | + pFree->pNext = 0; | |
| 71104 | + vdbeSorterRecordFree(db, pFree); | |
| 71105 | + *pbEof = !pSorter->pRecord; | |
| 71106 | + rc = SQLITE_OK; | |
| 70900 | 71107 | } |
| 71108 | + return rc; | |
| 71109 | +} | |
| 70901 | 71110 | |
| 70902 | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); | |
| 70903 | - return rc; | |
| 71111 | +/* | |
| 71112 | +** Return a pointer to a buffer owned by the sorter that contains the | |
| 71113 | +** current key. | |
| 71114 | +*/ | |
| 71115 | +static void *vdbeSorterRowkey( | |
| 71116 | + VdbeSorter *pSorter, /* Sorter object */ | |
| 71117 | + int *pnKey /* OUT: Size of current key in bytes */ | |
| 71118 | +){ | |
| 71119 | + void *pKey; | |
| 71120 | + if( pSorter->aTree ){ | |
| 71121 | + VdbeSorterIter *pIter; | |
| 71122 | + pIter = &pSorter->aIter[ pSorter->aTree[1] ]; | |
| 71123 | + *pnKey = pIter->nKey; | |
| 71124 | + pKey = pIter->aKey; | |
| 71125 | + }else{ | |
| 71126 | + *pnKey = pSorter->pRecord->nVal; | |
| 71127 | + pKey = pSorter->pRecord->pVal; | |
| 71128 | + } | |
| 71129 | + return pKey; | |
| 70904 | 71130 | } |
| 70905 | 71131 | |
| 70906 | 71132 | /* |
| 70907 | 71133 | ** Copy the current sorter key into the memory cell pOut. |
| 70908 | 71134 | */ |
| 70909 | 71135 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ |
| 70910 | 71136 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70911 | - VdbeSorterIter *pIter; | |
| 70912 | - | |
| 70913 | - pIter = &pSorter->aIter[ pSorter->aTree[1] ]; | |
| 70914 | - | |
| 70915 | - /* Coverage testing note: As things are currently, this call will always | |
| 70916 | - ** succeed. This is because the memory cell passed by the VDBE layer | |
| 70917 | - ** happens to be the same one as was used to assemble the keys before they | |
| 70918 | - ** were passed to the sorter - meaning it is always large enough for the | |
| 70919 | - ** largest key. But this could change very easily, so we leave the call | |
| 70920 | - ** to sqlite3VdbeMemGrow() in. */ | |
| 70921 | - if( NEVER(sqlite3VdbeMemGrow(pOut, pIter->nKey, 0)) ){ | |
| 71137 | + void *pKey; int nKey; /* Sorter key to copy into pOut */ | |
| 71138 | + | |
| 71139 | + pKey = vdbeSorterRowkey(pSorter, &nKey); | |
| 71140 | + if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ | |
| 70922 | 71141 | return SQLITE_NOMEM; |
| 70923 | 71142 | } |
| 70924 | - pOut->n = pIter->nKey; | |
| 71143 | + pOut->n = nKey; | |
| 70925 | 71144 | MemSetTypeFlag(pOut, MEM_Blob); |
| 70926 | - memcpy(pOut->z, pIter->aKey, pIter->nKey); | |
| 71145 | + memcpy(pOut->z, pKey, nKey); | |
| 70927 | 71146 | |
| 70928 | 71147 | return SQLITE_OK; |
| 70929 | 71148 | } |
| 71149 | + | |
| 71150 | +/* | |
| 71151 | +** Compare the key in memory cell pVal with the key that the sorter cursor | |
| 71152 | +** passed as the first argument currently points to. For the purposes of | |
| 71153 | +** the comparison, ignore the rowid field at the end of each record. | |
| 71154 | +** | |
| 71155 | +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). | |
| 71156 | +** Otherwise, set *pRes to a negative, zero or positive value if the | |
| 71157 | +** key in pVal is smaller than, equal to or larger than the current sorter | |
| 71158 | +** key. | |
| 71159 | +*/ | |
| 71160 | +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( | |
| 71161 | + VdbeCursor *pCsr, /* Sorter cursor */ | |
| 71162 | + Mem *pVal, /* Value to compare to current sorter key */ | |
| 71163 | + int *pRes /* OUT: Result of comparison */ | |
| 71164 | +){ | |
| 71165 | + int rc; | |
| 71166 | + VdbeSorter *pSorter = pCsr->pSorter; | |
| 71167 | + void *pKey; int nKey; /* Sorter key to compare pVal with */ | |
| 71168 | + | |
| 71169 | + pKey = vdbeSorterRowkey(pSorter, &nKey); | |
| 71170 | + rc = vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); | |
| 71171 | + assert( rc!=SQLITE_OK || pVal->db->mallocFailed || (*pRes)<=0 ); | |
| 71172 | + return rc; | |
| 71173 | +} | |
| 70930 | 71174 | |
| 70931 | 71175 | #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ |
| 70932 | 71176 | |
| 70933 | 71177 | /************** End of vdbesort.c ********************************************/ |
| 70934 | 71178 | /************** Begin file journal.c *****************************************/ |
| @@ -75077,11 +75321,11 @@ | ||
| 75077 | 75321 | if( !pAggInfo->directMode ){ |
| 75078 | 75322 | assert( pCol->iMem>0 ); |
| 75079 | 75323 | inReg = pCol->iMem; |
| 75080 | 75324 | break; |
| 75081 | 75325 | }else if( pAggInfo->useSortingIdx ){ |
| 75082 | - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, | |
| 75326 | + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, | |
| 75083 | 75327 | pCol->iSorterColumn, target); |
| 75084 | 75328 | break; |
| 75085 | 75329 | } |
| 75086 | 75330 | /* Otherwise, fall thru into the TK_COLUMN case */ |
| 75087 | 75331 | } |
| @@ -81235,27 +81479,19 @@ | ||
| 81235 | 81479 | Table *pTab = pIndex->pTable; /* The table that is indexed */ |
| 81236 | 81480 | int iTab = pParse->nTab++; /* Btree cursor used for pTab */ |
| 81237 | 81481 | int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ |
| 81238 | 81482 | int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ |
| 81239 | 81483 | int addr1; /* Address of top of loop */ |
| 81484 | + int addr2; /* Address to jump to for next iteration */ | |
| 81240 | 81485 | int tnum; /* Root page of index */ |
| 81241 | 81486 | Vdbe *v; /* Generate code into this virtual machine */ |
| 81242 | 81487 | KeyInfo *pKey; /* KeyInfo for index */ |
| 81243 | 81488 | int regIdxKey; /* Registers containing the index key */ |
| 81244 | 81489 | int regRecord; /* Register holding assemblied index record */ |
| 81245 | 81490 | sqlite3 *db = pParse->db; /* The database connection */ |
| 81246 | 81491 | int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); |
| 81247 | 81492 | |
| 81248 | - /* Set bUseSorter to use OP_OpenSorter, or clear it to insert directly | |
| 81249 | - ** into the index. The sorter is used unless either OMIT_MERGE_SORT is | |
| 81250 | - ** defined or the system is configured to store temp files in-memory. */ | |
| 81251 | -#ifdef SQLITE_OMIT_MERGE_SORT | |
| 81252 | - static const int bUseSorter = 0; | |
| 81253 | -#else | |
| 81254 | - const int bUseSorter = !sqlite3TempInMemory(pParse->db); | |
| 81255 | -#endif | |
| 81256 | - | |
| 81257 | 81493 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 81258 | 81494 | if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, |
| 81259 | 81495 | db->aDb[iDb].zName ) ){ |
| 81260 | 81496 | return; |
| 81261 | 81497 | } |
| @@ -81277,32 +81513,44 @@ | ||
| 81277 | 81513 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81278 | 81514 | if( memRootPage>=0 ){ |
| 81279 | 81515 | sqlite3VdbeChangeP5(v, 1); |
| 81280 | 81516 | } |
| 81281 | 81517 | |
| 81518 | +#ifndef SQLITE_OMIT_MERGE_SORT | |
| 81282 | 81519 | /* Open the sorter cursor if we are to use one. */ |
| 81283 | - if( bUseSorter ){ | |
| 81284 | - iSorter = pParse->nTab++; | |
| 81285 | - sqlite3VdbeAddOp4(v, OP_OpenSorter, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); | |
| 81286 | - sqlite3VdbeChangeP5(v, BTREE_SORTER); | |
| 81287 | - } | |
| 81520 | + iSorter = pParse->nTab++; | |
| 81521 | + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); | |
| 81522 | +#endif | |
| 81288 | 81523 | |
| 81289 | 81524 | /* Open the table. Loop through all rows of the table, inserting index |
| 81290 | 81525 | ** records into the sorter. */ |
| 81291 | 81526 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| 81292 | 81527 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); |
| 81528 | + addr2 = addr1 + 1; | |
| 81293 | 81529 | regRecord = sqlite3GetTempReg(pParse); |
| 81294 | 81530 | regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); |
| 81295 | 81531 | |
| 81296 | - if( bUseSorter ){ | |
| 81297 | - sqlite3VdbeAddOp2(v, OP_IdxInsert, iSorter, regRecord); | |
| 81298 | - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); | |
| 81299 | - sqlite3VdbeJumpHere(v, addr1); | |
| 81300 | - addr1 = sqlite3VdbeAddOp2(v, OP_Sort, iSorter, 0); | |
| 81301 | - sqlite3VdbeAddOp2(v, OP_RowKey, iSorter, regRecord); | |
| 81302 | - } | |
| 81303 | - | |
| 81532 | +#ifndef SQLITE_OMIT_MERGE_SORT | |
| 81533 | + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); | |
| 81534 | + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); | |
| 81535 | + sqlite3VdbeJumpHere(v, addr1); | |
| 81536 | + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); | |
| 81537 | + if( pIndex->onError!=OE_None ){ | |
| 81538 | + int j2 = sqlite3VdbeCurrentAddr(v) + 3; | |
| 81539 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); | |
| 81540 | + addr2 = sqlite3VdbeCurrentAddr(v); | |
| 81541 | + sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); | |
| 81542 | + sqlite3HaltConstraint( | |
| 81543 | + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC | |
| 81544 | + ); | |
| 81545 | + }else{ | |
| 81546 | + addr2 = sqlite3VdbeCurrentAddr(v); | |
| 81547 | + } | |
| 81548 | + sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); | |
| 81549 | + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); | |
| 81550 | + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); | |
| 81551 | +#else | |
| 81304 | 81552 | if( pIndex->onError!=OE_None ){ |
| 81305 | 81553 | const int regRowid = regIdxKey + pIndex->nColumn; |
| 81306 | 81554 | const int j2 = sqlite3VdbeCurrentAddr(v) + 2; |
| 81307 | 81555 | void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); |
| 81308 | 81556 | |
| @@ -81317,14 +81565,15 @@ | ||
| 81317 | 81565 | */ |
| 81318 | 81566 | sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); |
| 81319 | 81567 | sqlite3HaltConstraint( |
| 81320 | 81568 | pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); |
| 81321 | 81569 | } |
| 81322 | - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, bUseSorter); | |
| 81570 | + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); | |
| 81323 | 81571 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81572 | +#endif | |
| 81324 | 81573 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 81325 | - sqlite3VdbeAddOp2(v, OP_Next, iSorter, addr1+1); | |
| 81574 | + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); | |
| 81326 | 81575 | sqlite3VdbeJumpHere(v, addr1); |
| 81327 | 81576 | |
| 81328 | 81577 | sqlite3VdbeAddOp1(v, OP_Close, iTab); |
| 81329 | 81578 | sqlite3VdbeAddOp1(v, OP_Close, iIdx); |
| 81330 | 81579 | sqlite3VdbeAddOp1(v, OP_Close, iSorter); |
| @@ -92534,16 +92783,22 @@ | ||
| 92534 | 92783 | ){ |
| 92535 | 92784 | Vdbe *v = pParse->pVdbe; |
| 92536 | 92785 | int nExpr = pOrderBy->nExpr; |
| 92537 | 92786 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 92538 | 92787 | int regRecord = sqlite3GetTempReg(pParse); |
| 92788 | + int op; | |
| 92539 | 92789 | sqlite3ExprCacheClear(pParse); |
| 92540 | 92790 | sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 92541 | 92791 | sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 92542 | 92792 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 92543 | 92793 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 92544 | - sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); | |
| 92794 | + if( pSelect->selFlags & SF_UseSorter ){ | |
| 92795 | + op = OP_SorterInsert; | |
| 92796 | + }else{ | |
| 92797 | + op = OP_IdxInsert; | |
| 92798 | + } | |
| 92799 | + sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); | |
| 92545 | 92800 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 92546 | 92801 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 92547 | 92802 | if( pSelect->iLimit ){ |
| 92548 | 92803 | int addr1, addr2; |
| 92549 | 92804 | int iLimit; |
| @@ -93008,13 +93263,24 @@ | ||
| 93008 | 93263 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 93009 | 93264 | regRowid = 0; |
| 93010 | 93265 | }else{ |
| 93011 | 93266 | regRowid = sqlite3GetTempReg(pParse); |
| 93012 | 93267 | } |
| 93013 | - addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); | |
| 93014 | - codeOffset(v, p, addrContinue); | |
| 93015 | - sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); | |
| 93268 | + if( p->selFlags & SF_UseSorter ){ | |
| 93269 | + int regSortOut = ++pParse->nMem; | |
| 93270 | + int ptab2 = pParse->nTab++; | |
| 93271 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); | |
| 93272 | + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); | |
| 93273 | + codeOffset(v, p, addrContinue); | |
| 93274 | + sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); | |
| 93275 | + sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); | |
| 93276 | + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); | |
| 93277 | + }else{ | |
| 93278 | + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); | |
| 93279 | + codeOffset(v, p, addrContinue); | |
| 93280 | + sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); | |
| 93281 | + } | |
| 93016 | 93282 | switch( eDest ){ |
| 93017 | 93283 | case SRT_Table: |
| 93018 | 93284 | case SRT_EphemTab: { |
| 93019 | 93285 | testcase( eDest==SRT_Table ); |
| 93020 | 93286 | testcase( eDest==SRT_EphemTab ); |
| @@ -93063,11 +93329,15 @@ | ||
| 93063 | 93329 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 93064 | 93330 | |
| 93065 | 93331 | /* The bottom of the loop |
| 93066 | 93332 | */ |
| 93067 | 93333 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 93068 | - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); | |
| 93334 | + if( p->selFlags & SF_UseSorter ){ | |
| 93335 | + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); | |
| 93336 | + }else{ | |
| 93337 | + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); | |
| 93338 | + } | |
| 93069 | 93339 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 93070 | 93340 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 93071 | 93341 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 93072 | 93342 | } |
| 93073 | 93343 | } |
| @@ -96029,10 +96299,14 @@ | ||
| 96029 | 96299 | /* Set the limiter. |
| 96030 | 96300 | */ |
| 96031 | 96301 | iEnd = sqlite3VdbeMakeLabel(v); |
| 96032 | 96302 | p->nSelectRow = (double)LARGEST_INT64; |
| 96033 | 96303 | computeLimitRegisters(pParse, p, iEnd); |
| 96304 | + if( p->iLimit==0 && addrSortIndex>=0 ){ | |
| 96305 | + sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; | |
| 96306 | + p->selFlags |= SF_UseSorter; | |
| 96307 | + } | |
| 96034 | 96308 | |
| 96035 | 96309 | /* Open a virtual index to use for the distinct set. |
| 96036 | 96310 | */ |
| 96037 | 96311 | if( p->selFlags & SF_Distinct ){ |
| 96038 | 96312 | KeyInfo *pKeyInfo; |
| @@ -96064,11 +96338,11 @@ | ||
| 96064 | 96338 | } |
| 96065 | 96339 | |
| 96066 | 96340 | if( pWInfo->eDistinct ){ |
| 96067 | 96341 | VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 96068 | 96342 | |
| 96069 | - assert( addrDistinctIndex>0 ); | |
| 96343 | + assert( addrDistinctIndex>=0 ); | |
| 96070 | 96344 | pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); |
| 96071 | 96345 | |
| 96072 | 96346 | assert( isDistinct ); |
| 96073 | 96347 | assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED |
| 96074 | 96348 | || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE |
| @@ -96123,10 +96397,12 @@ | ||
| 96123 | 96397 | ** one row of the input to the aggregator has been |
| 96124 | 96398 | ** processed */ |
| 96125 | 96399 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 96126 | 96400 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 96127 | 96401 | int addrEnd; /* End of processing for this SELECT */ |
| 96402 | + int sortPTab = 0; /* Pseudotable used to decode sorting results */ | |
| 96403 | + int sortOut = 0; /* Output register from the sorter */ | |
| 96128 | 96404 | |
| 96129 | 96405 | /* Remove any and all aliases between the result set and the |
| 96130 | 96406 | ** GROUP BY clause. |
| 96131 | 96407 | */ |
| 96132 | 96408 | if( pGroupBy ){ |
| @@ -96184,16 +96460,16 @@ | ||
| 96184 | 96460 | int addrReset; /* Subroutine for resetting the accumulator */ |
| 96185 | 96461 | int regReset; /* Return address register for reset subroutine */ |
| 96186 | 96462 | |
| 96187 | 96463 | /* If there is a GROUP BY clause we might need a sorting index to |
| 96188 | 96464 | ** implement it. Allocate that sorting index now. If it turns out |
| 96189 | - ** that we do not need it after all, the OpenEphemeral instruction | |
| 96465 | + ** that we do not need it after all, the OP_SorterOpen instruction | |
| 96190 | 96466 | ** will be converted into a Noop. |
| 96191 | 96467 | */ |
| 96192 | 96468 | sAggInfo.sortingIdx = pParse->nTab++; |
| 96193 | 96469 | pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); |
| 96194 | - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, | |
| 96470 | + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, | |
| 96195 | 96471 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 96196 | 96472 | 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); |
| 96197 | 96473 | |
| 96198 | 96474 | /* Initialize memory locations used by GROUP BY aggregate processing |
| 96199 | 96475 | */ |
| @@ -96270,15 +96546,18 @@ | ||
| 96270 | 96546 | j++; |
| 96271 | 96547 | } |
| 96272 | 96548 | } |
| 96273 | 96549 | regRecord = sqlite3GetTempReg(pParse); |
| 96274 | 96550 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); |
| 96275 | - sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); | |
| 96551 | + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); | |
| 96276 | 96552 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 96277 | 96553 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 96278 | 96554 | sqlite3WhereEnd(pWInfo); |
| 96279 | - sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); | |
| 96555 | + sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; | |
| 96556 | + sortOut = sqlite3GetTempReg(pParse); | |
| 96557 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); | |
| 96558 | + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); | |
| 96280 | 96559 | VdbeComment((v, "GROUP BY sort")); |
| 96281 | 96560 | sAggInfo.useSortingIdx = 1; |
| 96282 | 96561 | sqlite3ExprCacheClear(pParse); |
| 96283 | 96562 | } |
| 96284 | 96563 | |
| @@ -96287,13 +96566,17 @@ | ||
| 96287 | 96566 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| 96288 | 96567 | ** from the previous row currently stored in a0, a1, a2... |
| 96289 | 96568 | */ |
| 96290 | 96569 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 96291 | 96570 | sqlite3ExprCacheClear(pParse); |
| 96571 | + if( groupBySort ){ | |
| 96572 | + sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); | |
| 96573 | + } | |
| 96292 | 96574 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 96293 | 96575 | if( groupBySort ){ |
| 96294 | - sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j); | |
| 96576 | + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); | |
| 96577 | + if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); | |
| 96295 | 96578 | }else{ |
| 96296 | 96579 | sAggInfo.directMode = 1; |
| 96297 | 96580 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 96298 | 96581 | } |
| 96299 | 96582 | } |
| @@ -96328,11 +96611,11 @@ | ||
| 96328 | 96611 | VdbeComment((v, "indicate data in accumulator")); |
| 96329 | 96612 | |
| 96330 | 96613 | /* End of the loop |
| 96331 | 96614 | */ |
| 96332 | 96615 | if( groupBySort ){ |
| 96333 | - sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); | |
| 96616 | + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); | |
| 96334 | 96617 | }else{ |
| 96335 | 96618 | sqlite3WhereEnd(pWInfo); |
| 96336 | 96619 | sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); |
| 96337 | 96620 | } |
| 96338 | 96621 | |
| 96339 | 96622 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -656,11 +656,11 @@ | |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | */ |
| 659 | #define SQLITE_VERSION "3.7.8" |
| 660 | #define SQLITE_VERSION_NUMBER 3007008 |
| 661 | #define SQLITE_SOURCE_ID "2011-08-29 11:56:14 639cc85a911454bffdcccb33f2976c683953ae64" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -7632,18 +7632,10 @@ | |
| 7632 | */ |
| 7633 | #ifndef SQLITE_TEMP_STORE |
| 7634 | # define SQLITE_TEMP_STORE 1 |
| 7635 | #endif |
| 7636 | |
| 7637 | /* |
| 7638 | ** If all temporary storage is in-memory, then omit the external merge-sort |
| 7639 | ** logic since it is superfluous. |
| 7640 | */ |
| 7641 | #if SQLITE_TEMP_STORE==3 && !defined(SQLITE_OMIT_MERGE_SORT) |
| 7642 | # define SQLITE_OMIT_MERGE_SORT |
| 7643 | #endif |
| 7644 | |
| 7645 | /* |
| 7646 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 7647 | ** ourselves. |
| 7648 | */ |
| 7649 | #ifndef offsetof |
| @@ -7982,11 +7974,10 @@ | |
| 7982 | #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ |
| 7983 | #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ |
| 7984 | #define BTREE_MEMORY 4 /* This is an in-memory DB */ |
| 7985 | #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ |
| 7986 | #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ |
| 7987 | #define BTREE_SORTER 32 /* Used as accumulator in external merge sort */ |
| 7988 | |
| 7989 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 7990 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 7991 | SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); |
| 7992 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| @@ -8399,13 +8390,13 @@ | |
| 8399 | #define OP_ReadCookie 35 |
| 8400 | #define OP_SetCookie 36 |
| 8401 | #define OP_VerifyCookie 37 |
| 8402 | #define OP_OpenRead 38 |
| 8403 | #define OP_OpenWrite 39 |
| 8404 | #define OP_OpenSorter 40 |
| 8405 | #define OP_OpenAutoindex 41 |
| 8406 | #define OP_OpenEphemeral 42 |
| 8407 | #define OP_OpenPseudo 43 |
| 8408 | #define OP_Close 44 |
| 8409 | #define OP_SeekLt 45 |
| 8410 | #define OP_SeekLe 46 |
| 8411 | #define OP_SeekGe 47 |
| @@ -8419,70 +8410,72 @@ | |
| 8419 | #define OP_NewRowid 55 |
| 8420 | #define OP_Insert 56 |
| 8421 | #define OP_InsertInt 57 |
| 8422 | #define OP_Delete 58 |
| 8423 | #define OP_ResetCount 59 |
| 8424 | #define OP_RowKey 60 |
| 8425 | #define OP_RowData 61 |
| 8426 | #define OP_Rowid 62 |
| 8427 | #define OP_NullRow 63 |
| 8428 | #define OP_Last 64 |
| 8429 | #define OP_Sort 65 |
| 8430 | #define OP_Rewind 66 |
| 8431 | #define OP_Prev 67 |
| 8432 | #define OP_Next 70 |
| 8433 | #define OP_IdxInsert 71 |
| 8434 | #define OP_IdxDelete 72 |
| 8435 | #define OP_IdxRowid 81 |
| 8436 | #define OP_IdxLT 92 |
| 8437 | #define OP_IdxGE 95 |
| 8438 | #define OP_Destroy 96 |
| 8439 | #define OP_Clear 97 |
| 8440 | #define OP_CreateIndex 98 |
| 8441 | #define OP_CreateTable 99 |
| 8442 | #define OP_ParseSchema 100 |
| 8443 | #define OP_LoadAnalysis 101 |
| 8444 | #define OP_DropTable 102 |
| 8445 | #define OP_DropIndex 103 |
| 8446 | #define OP_DropTrigger 104 |
| 8447 | #define OP_IntegrityCk 105 |
| 8448 | #define OP_RowSetAdd 106 |
| 8449 | #define OP_RowSetRead 107 |
| 8450 | #define OP_RowSetTest 108 |
| 8451 | #define OP_Program 109 |
| 8452 | #define OP_Param 110 |
| 8453 | #define OP_FkCounter 111 |
| 8454 | #define OP_FkIfZero 112 |
| 8455 | #define OP_MemMax 113 |
| 8456 | #define OP_IfPos 114 |
| 8457 | #define OP_IfNeg 115 |
| 8458 | #define OP_IfZero 116 |
| 8459 | #define OP_AggStep 117 |
| 8460 | #define OP_AggFinal 118 |
| 8461 | #define OP_Checkpoint 119 |
| 8462 | #define OP_JournalMode 120 |
| 8463 | #define OP_Vacuum 121 |
| 8464 | #define OP_IncrVacuum 122 |
| 8465 | #define OP_Expire 123 |
| 8466 | #define OP_TableLock 124 |
| 8467 | #define OP_VBegin 125 |
| 8468 | #define OP_VCreate 126 |
| 8469 | #define OP_VDestroy 127 |
| 8470 | #define OP_VOpen 128 |
| 8471 | #define OP_VFilter 129 |
| 8472 | #define OP_VColumn 131 |
| 8473 | #define OP_VNext 132 |
| 8474 | #define OP_VRename 133 |
| 8475 | #define OP_VUpdate 134 |
| 8476 | #define OP_Pagecount 135 |
| 8477 | #define OP_MaxPgcnt 136 |
| 8478 | #define OP_Trace 137 |
| 8479 | #define OP_Noop 138 |
| 8480 | #define OP_Explain 139 |
| 8481 | |
| 8482 | /* The following opcode values are never used */ |
| 8483 | #define OP_NotUsed_140 140 |
| 8484 | |
| 8485 | |
| 8486 | /* Properties such as "out2" or "jump" that are specified in |
| 8487 | ** comments following the "case" for each opcode in the vdbe.c |
| 8488 | ** are encoded into bitvectors as follows: |
| @@ -8500,22 +8493,22 @@ | |
| 8500 | /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ |
| 8501 | /* 24 */ 0x00, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\ |
| 8502 | /* 32 */ 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00,\ |
| 8503 | /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,\ |
| 8504 | /* 48 */ 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02,\ |
| 8505 | /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,\ |
| 8506 | /* 64 */ 0x01, 0x01, 0x01, 0x01, 0x4c, 0x4c, 0x01, 0x08,\ |
| 8507 | /* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ |
| 8508 | /* 80 */ 0x15, 0x02, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ |
| 8509 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ |
| 8510 | /* 96 */ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,\ |
| 8511 | /* 104 */ 0x00, 0x00, 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00,\ |
| 8512 | /* 112 */ 0x01, 0x08, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ |
| 8513 | /* 120 */ 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 8514 | /* 128 */ 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02,\ |
| 8515 | /* 136 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,\ |
| 8516 | /* 144 */ 0x04, 0x04,} |
| 8517 | |
| 8518 | /************** End of opcodes.h *********************************************/ |
| 8519 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 8520 | |
| 8521 | /* |
| @@ -8749,13 +8742,10 @@ | |
| 8749 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); |
| 8750 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); |
| 8751 | SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); |
| 8752 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); |
| 8753 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); |
| 8754 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 8755 | SQLITE_PRIVATE int sqlite3PagerUnderStress(Pager*); |
| 8756 | #endif |
| 8757 | |
| 8758 | /* Functions used to truncate the database file. */ |
| 8759 | SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); |
| 8760 | |
| 8761 | #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) |
| @@ -10186,10 +10176,11 @@ | |
| 10186 | u8 directMode; /* Direct rendering mode means take data directly |
| 10187 | ** from source tables rather than from accumulators */ |
| 10188 | u8 useSortingIdx; /* In direct mode, reference the sorting index rather |
| 10189 | ** than the source table */ |
| 10190 | int sortingIdx; /* Cursor number of the sorting index */ |
| 10191 | ExprList *pGroupBy; /* The group by clause */ |
| 10192 | int nSortingColumn; /* Number of columns in the sorting index */ |
| 10193 | struct AggInfo_col { /* For each column used in source tables */ |
| 10194 | Table *pTab; /* Source table */ |
| 10195 | int iTable; /* Cursor number of the source table */ |
| @@ -10718,10 +10709,11 @@ | |
| 10718 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 10719 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 10720 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 10721 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 10722 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 10723 | |
| 10724 | |
| 10725 | /* |
| 10726 | ** The results of a select can be distributed in several ways. The |
| 10727 | ** "SRT" prefix means "SELECT Result Type". |
| @@ -12267,10 +12259,13 @@ | |
| 12267 | "INT64_TYPE", |
| 12268 | #endif |
| 12269 | #ifdef SQLITE_LOCK_TRACE |
| 12270 | "LOCK_TRACE", |
| 12271 | #endif |
| 12272 | #ifdef SQLITE_MEMDEBUG |
| 12273 | "MEMDEBUG", |
| 12274 | #endif |
| 12275 | #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 12276 | "MIXED_ENDIAN_64BIT_FLOAT", |
| @@ -12601,16 +12596,17 @@ | |
| 12601 | Bool nullRow; /* True if pointing to a row with no data */ |
| 12602 | Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 12603 | Bool isTable; /* True if a table requiring integer keys */ |
| 12604 | Bool isIndex; /* True if an index containing keys only - no data */ |
| 12605 | Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ |
| 12606 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 12607 | const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ |
| 12608 | i64 seqCount; /* Sequence counter */ |
| 12609 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 12610 | i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ |
| 12611 | VdbeSorter *pSorter; /* Sorter object for OP_OpenSorter cursors */ |
| 12612 | |
| 12613 | /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or |
| 12614 | ** OP_IsUnique opcode on this cursor. */ |
| 12615 | int seekResult; |
| 12616 | |
| @@ -12944,17 +12940,19 @@ | |
| 12944 | # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK |
| 12945 | # define sqlite3VdbeSorterClose(Y,Z) |
| 12946 | # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK |
| 12947 | # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK |
| 12948 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 12949 | #else |
| 12950 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 12951 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, int); |
| 12952 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 12953 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); |
| 12954 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); |
| 12955 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); |
| 12956 | #endif |
| 12957 | |
| 12958 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 12959 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 12960 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22114,13 +22112,13 @@ | |
| 22114 | /* 35 */ "ReadCookie", |
| 22115 | /* 36 */ "SetCookie", |
| 22116 | /* 37 */ "VerifyCookie", |
| 22117 | /* 38 */ "OpenRead", |
| 22118 | /* 39 */ "OpenWrite", |
| 22119 | /* 40 */ "OpenSorter", |
| 22120 | /* 41 */ "OpenAutoindex", |
| 22121 | /* 42 */ "OpenEphemeral", |
| 22122 | /* 43 */ "OpenPseudo", |
| 22123 | /* 44 */ "Close", |
| 22124 | /* 45 */ "SeekLt", |
| 22125 | /* 46 */ "SeekLe", |
| 22126 | /* 47 */ "SeekGe", |
| @@ -22134,32 +22132,32 @@ | |
| 22134 | /* 55 */ "NewRowid", |
| 22135 | /* 56 */ "Insert", |
| 22136 | /* 57 */ "InsertInt", |
| 22137 | /* 58 */ "Delete", |
| 22138 | /* 59 */ "ResetCount", |
| 22139 | /* 60 */ "RowKey", |
| 22140 | /* 61 */ "RowData", |
| 22141 | /* 62 */ "Rowid", |
| 22142 | /* 63 */ "NullRow", |
| 22143 | /* 64 */ "Last", |
| 22144 | /* 65 */ "Sort", |
| 22145 | /* 66 */ "Rewind", |
| 22146 | /* 67 */ "Prev", |
| 22147 | /* 68 */ "Or", |
| 22148 | /* 69 */ "And", |
| 22149 | /* 70 */ "Next", |
| 22150 | /* 71 */ "IdxInsert", |
| 22151 | /* 72 */ "IdxDelete", |
| 22152 | /* 73 */ "IsNull", |
| 22153 | /* 74 */ "NotNull", |
| 22154 | /* 75 */ "Ne", |
| 22155 | /* 76 */ "Eq", |
| 22156 | /* 77 */ "Gt", |
| 22157 | /* 78 */ "Le", |
| 22158 | /* 79 */ "Lt", |
| 22159 | /* 80 */ "Ge", |
| 22160 | /* 81 */ "IdxRowid", |
| 22161 | /* 82 */ "BitAnd", |
| 22162 | /* 83 */ "BitOr", |
| 22163 | /* 84 */ "ShiftLeft", |
| 22164 | /* 85 */ "ShiftRight", |
| 22165 | /* 86 */ "Add", |
| @@ -22166,64 +22164,68 @@ | |
| 22166 | /* 87 */ "Subtract", |
| 22167 | /* 88 */ "Multiply", |
| 22168 | /* 89 */ "Divide", |
| 22169 | /* 90 */ "Remainder", |
| 22170 | /* 91 */ "Concat", |
| 22171 | /* 92 */ "IdxLT", |
| 22172 | /* 93 */ "BitNot", |
| 22173 | /* 94 */ "String8", |
| 22174 | /* 95 */ "IdxGE", |
| 22175 | /* 96 */ "Destroy", |
| 22176 | /* 97 */ "Clear", |
| 22177 | /* 98 */ "CreateIndex", |
| 22178 | /* 99 */ "CreateTable", |
| 22179 | /* 100 */ "ParseSchema", |
| 22180 | /* 101 */ "LoadAnalysis", |
| 22181 | /* 102 */ "DropTable", |
| 22182 | /* 103 */ "DropIndex", |
| 22183 | /* 104 */ "DropTrigger", |
| 22184 | /* 105 */ "IntegrityCk", |
| 22185 | /* 106 */ "RowSetAdd", |
| 22186 | /* 107 */ "RowSetRead", |
| 22187 | /* 108 */ "RowSetTest", |
| 22188 | /* 109 */ "Program", |
| 22189 | /* 110 */ "Param", |
| 22190 | /* 111 */ "FkCounter", |
| 22191 | /* 112 */ "FkIfZero", |
| 22192 | /* 113 */ "MemMax", |
| 22193 | /* 114 */ "IfPos", |
| 22194 | /* 115 */ "IfNeg", |
| 22195 | /* 116 */ "IfZero", |
| 22196 | /* 117 */ "AggStep", |
| 22197 | /* 118 */ "AggFinal", |
| 22198 | /* 119 */ "Checkpoint", |
| 22199 | /* 120 */ "JournalMode", |
| 22200 | /* 121 */ "Vacuum", |
| 22201 | /* 122 */ "IncrVacuum", |
| 22202 | /* 123 */ "Expire", |
| 22203 | /* 124 */ "TableLock", |
| 22204 | /* 125 */ "VBegin", |
| 22205 | /* 126 */ "VCreate", |
| 22206 | /* 127 */ "VDestroy", |
| 22207 | /* 128 */ "VOpen", |
| 22208 | /* 129 */ "VFilter", |
| 22209 | /* 130 */ "Real", |
| 22210 | /* 131 */ "VColumn", |
| 22211 | /* 132 */ "VNext", |
| 22212 | /* 133 */ "VRename", |
| 22213 | /* 134 */ "VUpdate", |
| 22214 | /* 135 */ "Pagecount", |
| 22215 | /* 136 */ "MaxPgcnt", |
| 22216 | /* 137 */ "Trace", |
| 22217 | /* 138 */ "Noop", |
| 22218 | /* 139 */ "Explain", |
| 22219 | /* 140 */ "NotUsed_140", |
| 22220 | /* 141 */ "ToText", |
| 22221 | /* 142 */ "ToBlob", |
| 22222 | /* 143 */ "ToNumeric", |
| 22223 | /* 144 */ "ToInt", |
| 22224 | /* 145 */ "ToReal", |
| 22225 | }; |
| 22226 | return azName[i]; |
| 22227 | } |
| 22228 | #endif |
| 22229 | |
| @@ -22314,11 +22316,11 @@ | |
| 22314 | */ |
| 22315 | #ifdef MEMORY_DEBUG |
| 22316 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 22317 | #endif |
| 22318 | |
| 22319 | #ifdef SQLITE_DEBUG |
| 22320 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 22321 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 22322 | # endif |
| 22323 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 22324 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -24656,11 +24658,11 @@ | |
| 24656 | */ |
| 24657 | #ifdef MEMORY_DEBUG |
| 24658 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 24659 | #endif |
| 24660 | |
| 24661 | #ifdef SQLITE_DEBUG |
| 24662 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 24663 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 24664 | # endif |
| 24665 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 24666 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -27716,15 +27718,15 @@ | |
| 27716 | SQLITE_API int sqlite3_fullsync_count = 0; |
| 27717 | #endif |
| 27718 | |
| 27719 | /* |
| 27720 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 27721 | ** Others do no. To be safe, we will stick with the (slower) fsync(). |
| 27722 | ** If you know that your system does support fdatasync() correctly, |
| 27723 | ** then simply compile with -Dfdatasync=fdatasync |
| 27724 | */ |
| 27725 | #if !defined(fdatasync) && !defined(__linux__) |
| 27726 | # define fdatasync fsync |
| 27727 | #endif |
| 27728 | |
| 27729 | /* |
| 27730 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28015,11 +28017,11 @@ | |
| 28015 | ** file-control operation. Enlarge the database to nBytes in size |
| 28016 | ** (rounded up to the next chunk-size). If the database is already |
| 28017 | ** nBytes or larger, this routine is a no-op. |
| 28018 | */ |
| 28019 | static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
| 28020 | if( pFile->szChunk ){ |
| 28021 | i64 nSize; /* Required file size */ |
| 28022 | struct stat buf; /* Used to hold return values of fstat() */ |
| 28023 | |
| 28024 | if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 28025 | |
| @@ -28210,15 +28212,13 @@ | |
| 28210 | */ |
| 28211 | struct unixShm { |
| 28212 | unixShmNode *pShmNode; /* The underlying unixShmNode object */ |
| 28213 | unixShm *pNext; /* Next unixShm with the same unixShmNode */ |
| 28214 | u8 hasMutex; /* True if holding the unixShmNode mutex */ |
| 28215 | u16 sharedMask; /* Mask of shared locks held */ |
| 28216 | u16 exclMask; /* Mask of exclusive locks held */ |
| 28217 | #ifdef SQLITE_DEBUG |
| 28218 | u8 id; /* Id of this connection within its unixShmNode */ |
| 28219 | #endif |
| 28220 | }; |
| 28221 | |
| 28222 | /* |
| 28223 | ** Constants used for locking |
| 28224 | */ |
| @@ -31435,11 +31435,11 @@ | |
| 31435 | */ |
| 31436 | #ifdef MEMORY_DEBUG |
| 31437 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 31438 | #endif |
| 31439 | |
| 31440 | #ifdef SQLITE_DEBUG |
| 31441 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 31442 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 31443 | # endif |
| 31444 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 31445 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -32768,11 +32768,11 @@ | |
| 32768 | /* If the user has configured a chunk-size for this file, truncate the |
| 32769 | ** file so that it consists of an integer number of chunks (i.e. the |
| 32770 | ** actual file size after the operation may be larger than the requested |
| 32771 | ** size). |
| 32772 | */ |
| 32773 | if( pFile->szChunk ){ |
| 32774 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 32775 | } |
| 32776 | |
| 32777 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 32778 | if( seekWinFile(pFile, nByte) ){ |
| @@ -33155,22 +33155,24 @@ | |
| 33155 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33156 | pFile->szChunk = *(int *)pArg; |
| 33157 | return SQLITE_OK; |
| 33158 | } |
| 33159 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33160 | winFile *pFile = (winFile*)id; |
| 33161 | sqlite3_int64 oldSz; |
| 33162 | int rc = winFileSize(id, &oldSz); |
| 33163 | if( rc==SQLITE_OK ){ |
| 33164 | sqlite3_int64 newSz = *(sqlite3_int64*)pArg; |
| 33165 | if( newSz>oldSz ){ |
| 33166 | SimulateIOErrorBenign(1); |
| 33167 | rc = winTruncate(id, newSz); |
| 33168 | SimulateIOErrorBenign(0); |
| 33169 | } |
| 33170 | } |
| 33171 | return rc; |
| 33172 | } |
| 33173 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33174 | int bPersist = *(int*)pArg; |
| 33175 | if( bPersist<0 ){ |
| 33176 | *(int*)pArg = pFile->bPersistWal; |
| @@ -38137,11 +38139,10 @@ | |
| 38137 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 38138 | u8 tempFile; /* zFilename is a temporary file */ |
| 38139 | u8 readOnly; /* True for a read-only database */ |
| 38140 | u8 memDb; /* True to inhibit all file I/O */ |
| 38141 | u8 hasSeenStress; /* pagerStress() called one or more times */ |
| 38142 | u8 isSorter; /* True for a PAGER_SORTER */ |
| 38143 | |
| 38144 | /************************************************************************** |
| 38145 | ** The following block contains those class members that change during |
| 38146 | ** routine opertion. Class members not in this block are either fixed |
| 38147 | ** when the pager is first created or else only change when there is a |
| @@ -38361,19 +38362,10 @@ | |
| 38361 | ); |
| 38362 | assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); |
| 38363 | assert( pagerUseWal(p)==0 ); |
| 38364 | } |
| 38365 | |
| 38366 | /* A sorter is a temp file that never spills to disk and always has |
| 38367 | ** the doNotSpill flag set |
| 38368 | */ |
| 38369 | if( p->isSorter ){ |
| 38370 | assert( p->tempFile ); |
| 38371 | assert( p->doNotSpill ); |
| 38372 | assert( p->fd->pMethods==0 ); |
| 38373 | } |
| 38374 | |
| 38375 | /* If changeCountDone is set, a RESERVED lock or greater must be held |
| 38376 | ** on the file. |
| 38377 | */ |
| 38378 | assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); |
| 38379 | assert( p->eLock!=PENDING_LOCK ); |
| @@ -42073,16 +42065,10 @@ | |
| 42073 | } |
| 42074 | /* pPager->xBusyHandler = 0; */ |
| 42075 | /* pPager->pBusyHandlerArg = 0; */ |
| 42076 | pPager->xReiniter = xReinit; |
| 42077 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ |
| 42078 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 42079 | if( flags & PAGER_SORTER ){ |
| 42080 | pPager->doNotSpill = 1; |
| 42081 | pPager->isSorter = 1; |
| 42082 | } |
| 42083 | #endif |
| 42084 | |
| 42085 | *ppPager = pPager; |
| 42086 | return SQLITE_OK; |
| 42087 | } |
| 42088 | |
| @@ -43623,21 +43609,10 @@ | |
| 43623 | */ |
| 43624 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ |
| 43625 | return MEMDB; |
| 43626 | } |
| 43627 | |
| 43628 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 43629 | /* |
| 43630 | ** Return true if the pager has seen a pagerStress callback. |
| 43631 | */ |
| 43632 | SQLITE_PRIVATE int sqlite3PagerUnderStress(Pager *pPager){ |
| 43633 | assert( pPager->isSorter ); |
| 43634 | assert( pPager->doNotSpill ); |
| 43635 | return pPager->hasSeenStress; |
| 43636 | } |
| 43637 | #endif |
| 43638 | |
| 43639 | /* |
| 43640 | ** Check that there are at least nSavepoint savepoints open. If there are |
| 43641 | ** currently less than nSavepoints open, then open one or more savepoints |
| 43642 | ** to make up the difference. If the number of savepoints is already |
| 43643 | ** equal to nSavepoint, then this function is a no-op. |
| @@ -50002,26 +49977,15 @@ | |
| 50002 | assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); |
| 50003 | |
| 50004 | /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ |
| 50005 | assert( (flags & BTREE_SINGLE)==0 || isTempDb ); |
| 50006 | |
| 50007 | /* The BTREE_SORTER flag is only used if SQLITE_OMIT_MERGE_SORT is undef */ |
| 50008 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 50009 | assert( (flags & BTREE_SORTER)==0 ); |
| 50010 | #endif |
| 50011 | |
| 50012 | /* BTREE_SORTER is always on a BTREE_SINGLE, BTREE_OMIT_JOURNAL */ |
| 50013 | assert( (flags & BTREE_SORTER)==0 || |
| 50014 | (flags & (BTREE_SINGLE|BTREE_OMIT_JOURNAL)) |
| 50015 | ==(BTREE_SINGLE|BTREE_OMIT_JOURNAL) ); |
| 50016 | |
| 50017 | if( db->flags & SQLITE_NoReadlock ){ |
| 50018 | flags |= BTREE_NO_READLOCK; |
| 50019 | } |
| 50020 | if( isMemdb ){ |
| 50021 | flags |= BTREE_MEMORY; |
| 50022 | flags &= ~BTREE_SORTER; |
| 50023 | } |
| 50024 | if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ |
| 50025 | vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; |
| 50026 | } |
| 50027 | p = sqlite3MallocZero(sizeof(Btree)); |
| @@ -51022,15 +50986,16 @@ | |
| 51022 | for(i=0; i<nCell; i++){ |
| 51023 | u8 *pCell = findCell(pPage, i); |
| 51024 | if( eType==PTRMAP_OVERFLOW1 ){ |
| 51025 | CellInfo info; |
| 51026 | btreeParseCellPtr(pPage, pCell, &info); |
| 51027 | if( info.iOverflow ){ |
| 51028 | if( iFrom==get4byte(&pCell[info.iOverflow]) ){ |
| 51029 | put4byte(&pCell[info.iOverflow], iTo); |
| 51030 | break; |
| 51031 | } |
| 51032 | } |
| 51033 | }else{ |
| 51034 | if( get4byte(pCell)==iFrom ){ |
| 51035 | put4byte(pCell, iTo); |
| 51036 | break; |
| @@ -53458,10 +53423,13 @@ | |
| 53458 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 53459 | btreeParseCellPtr(pPage, pCell, &info); |
| 53460 | if( info.iOverflow==0 ){ |
| 53461 | return SQLITE_OK; /* No overflow pages. Return without doing anything */ |
| 53462 | } |
| 53463 | ovflPgno = get4byte(&pCell[info.iOverflow]); |
| 53464 | assert( pBt->usableSize > 4 ); |
| 53465 | ovflPageSize = pBt->usableSize - 4; |
| 53466 | nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; |
| 53467 | assert( ovflPgno==0 || nOvfl>0 ); |
| @@ -55560,20 +55528,13 @@ | |
| 55560 | releasePage(pPage); |
| 55561 | } |
| 55562 | return rc; |
| 55563 | } |
| 55564 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ |
| 55565 | BtShared *pBt = p->pBt; |
| 55566 | int rc; |
| 55567 | sqlite3BtreeEnter(p); |
| 55568 | if( (pBt->openFlags&BTREE_SINGLE) ){ |
| 55569 | pBt->nPage = 0; |
| 55570 | sqlite3PagerTruncateImage(pBt->pPager, 1); |
| 55571 | rc = newDatabase(pBt); |
| 55572 | }else{ |
| 55573 | rc = btreeDropTable(p, iTable, piMoved); |
| 55574 | } |
| 55575 | sqlite3BtreeLeave(p); |
| 55576 | return rc; |
| 55577 | } |
| 55578 | |
| 55579 | |
| @@ -58758,11 +58719,11 @@ | |
| 58758 | assert( p->nOp - i >= 3 ); |
| 58759 | assert( pOp[-1].opcode==OP_Integer ); |
| 58760 | n = pOp[-1].p1; |
| 58761 | if( n>nMaxArgs ) nMaxArgs = n; |
| 58762 | #endif |
| 58763 | }else if( opcode==OP_Next ){ |
| 58764 | pOp->p4.xAdvance = sqlite3BtreeNext; |
| 58765 | pOp->p4type = P4_ADVANCE; |
| 58766 | }else if( opcode==OP_Prev ){ |
| 58767 | pOp->p4.xAdvance = sqlite3BtreePrevious; |
| 58768 | pOp->p4type = P4_ADVANCE; |
| @@ -63871,55 +63832,58 @@ | |
| 63871 | Db *pDb; |
| 63872 | } aw; |
| 63873 | struct OP_OpenEphemeral_stack_vars { |
| 63874 | VdbeCursor *pCx; |
| 63875 | } ax; |
| 63876 | struct OP_OpenPseudo_stack_vars { |
| 63877 | VdbeCursor *pCx; |
| 63878 | } ay; |
| 63879 | struct OP_SeekGt_stack_vars { |
| 63880 | int res; |
| 63881 | int oc; |
| 63882 | VdbeCursor *pC; |
| 63883 | UnpackedRecord r; |
| 63884 | int nField; |
| 63885 | i64 iKey; /* The rowid we are to seek to */ |
| 63886 | } az; |
| 63887 | struct OP_Seek_stack_vars { |
| 63888 | VdbeCursor *pC; |
| 63889 | } ba; |
| 63890 | struct OP_Found_stack_vars { |
| 63891 | int alreadyExists; |
| 63892 | VdbeCursor *pC; |
| 63893 | int res; |
| 63894 | UnpackedRecord *pIdxKey; |
| 63895 | UnpackedRecord r; |
| 63896 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 63897 | } bb; |
| 63898 | struct OP_IsUnique_stack_vars { |
| 63899 | u16 ii; |
| 63900 | VdbeCursor *pCx; |
| 63901 | BtCursor *pCrsr; |
| 63902 | u16 nField; |
| 63903 | Mem *aMx; |
| 63904 | UnpackedRecord r; /* B-Tree index search key */ |
| 63905 | i64 R; /* Rowid stored in register P3 */ |
| 63906 | } bc; |
| 63907 | struct OP_NotExists_stack_vars { |
| 63908 | VdbeCursor *pC; |
| 63909 | BtCursor *pCrsr; |
| 63910 | int res; |
| 63911 | u64 iKey; |
| 63912 | } bd; |
| 63913 | struct OP_NewRowid_stack_vars { |
| 63914 | i64 v; /* The new rowid */ |
| 63915 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 63916 | int res; /* Result of an sqlite3BtreeLast() */ |
| 63917 | int cnt; /* Counter to limit the number of searches */ |
| 63918 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 63919 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 63920 | } be; |
| 63921 | struct OP_InsertInt_stack_vars { |
| 63922 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 63923 | Mem *pKey; /* MEM cell holding key for the record */ |
| 63924 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 63925 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| @@ -63926,154 +63890,161 @@ | |
| 63926 | int nZero; /* Number of zero-bytes to append */ |
| 63927 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 63928 | const char *zDb; /* database name - used by the update hook */ |
| 63929 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 63930 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 63931 | } bf; |
| 63932 | struct OP_Delete_stack_vars { |
| 63933 | i64 iKey; |
| 63934 | VdbeCursor *pC; |
| 63935 | } bg; |
| 63936 | struct OP_RowData_stack_vars { |
| 63937 | VdbeCursor *pC; |
| 63938 | BtCursor *pCrsr; |
| 63939 | u32 n; |
| 63940 | i64 n64; |
| 63941 | } bh; |
| 63942 | struct OP_Rowid_stack_vars { |
| 63943 | VdbeCursor *pC; |
| 63944 | i64 v; |
| 63945 | sqlite3_vtab *pVtab; |
| 63946 | const sqlite3_module *pModule; |
| 63947 | } bi; |
| 63948 | struct OP_NullRow_stack_vars { |
| 63949 | VdbeCursor *pC; |
| 63950 | } bj; |
| 63951 | struct OP_Last_stack_vars { |
| 63952 | VdbeCursor *pC; |
| 63953 | BtCursor *pCrsr; |
| 63954 | int res; |
| 63955 | } bk; |
| 63956 | struct OP_Rewind_stack_vars { |
| 63957 | VdbeCursor *pC; |
| 63958 | BtCursor *pCrsr; |
| 63959 | int res; |
| 63960 | } bl; |
| 63961 | struct OP_Next_stack_vars { |
| 63962 | VdbeCursor *pC; |
| 63963 | int res; |
| 63964 | } bm; |
| 63965 | struct OP_IdxInsert_stack_vars { |
| 63966 | VdbeCursor *pC; |
| 63967 | BtCursor *pCrsr; |
| 63968 | int nKey; |
| 63969 | const char *zKey; |
| 63970 | } bn; |
| 63971 | struct OP_IdxDelete_stack_vars { |
| 63972 | VdbeCursor *pC; |
| 63973 | BtCursor *pCrsr; |
| 63974 | int res; |
| 63975 | UnpackedRecord r; |
| 63976 | } bo; |
| 63977 | struct OP_IdxRowid_stack_vars { |
| 63978 | BtCursor *pCrsr; |
| 63979 | VdbeCursor *pC; |
| 63980 | i64 rowid; |
| 63981 | } bp; |
| 63982 | struct OP_IdxGE_stack_vars { |
| 63983 | VdbeCursor *pC; |
| 63984 | int res; |
| 63985 | UnpackedRecord r; |
| 63986 | } bq; |
| 63987 | struct OP_Destroy_stack_vars { |
| 63988 | int iMoved; |
| 63989 | int iCnt; |
| 63990 | Vdbe *pVdbe; |
| 63991 | int iDb; |
| 63992 | } br; |
| 63993 | struct OP_Clear_stack_vars { |
| 63994 | int nChange; |
| 63995 | } bs; |
| 63996 | struct OP_CreateTable_stack_vars { |
| 63997 | int pgno; |
| 63998 | int flags; |
| 63999 | Db *pDb; |
| 64000 | } bt; |
| 64001 | struct OP_ParseSchema_stack_vars { |
| 64002 | int iDb; |
| 64003 | const char *zMaster; |
| 64004 | char *zSql; |
| 64005 | InitData initData; |
| 64006 | } bu; |
| 64007 | struct OP_IntegrityCk_stack_vars { |
| 64008 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 64009 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 64010 | int j; /* Loop counter */ |
| 64011 | int nErr; /* Number of errors reported */ |
| 64012 | char *z; /* Text of the error report */ |
| 64013 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 64014 | } bv; |
| 64015 | struct OP_RowSetRead_stack_vars { |
| 64016 | i64 val; |
| 64017 | } bw; |
| 64018 | struct OP_RowSetTest_stack_vars { |
| 64019 | int iSet; |
| 64020 | int exists; |
| 64021 | } bx; |
| 64022 | struct OP_Program_stack_vars { |
| 64023 | int nMem; /* Number of memory registers for sub-program */ |
| 64024 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 64025 | Mem *pRt; /* Register to allocate runtime space */ |
| 64026 | Mem *pMem; /* Used to iterate through memory cells */ |
| 64027 | Mem *pEnd; /* Last memory cell in new array */ |
| 64028 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 64029 | SubProgram *pProgram; /* Sub-program to execute */ |
| 64030 | void *t; /* Token identifying trigger */ |
| 64031 | } by; |
| 64032 | struct OP_Param_stack_vars { |
| 64033 | VdbeFrame *pFrame; |
| 64034 | Mem *pIn; |
| 64035 | } bz; |
| 64036 | struct OP_MemMax_stack_vars { |
| 64037 | Mem *pIn1; |
| 64038 | VdbeFrame *pFrame; |
| 64039 | } ca; |
| 64040 | struct OP_AggStep_stack_vars { |
| 64041 | int n; |
| 64042 | int i; |
| 64043 | Mem *pMem; |
| 64044 | Mem *pRec; |
| 64045 | sqlite3_context ctx; |
| 64046 | sqlite3_value **apVal; |
| 64047 | } cb; |
| 64048 | struct OP_AggFinal_stack_vars { |
| 64049 | Mem *pMem; |
| 64050 | } cc; |
| 64051 | struct OP_Checkpoint_stack_vars { |
| 64052 | int i; /* Loop counter */ |
| 64053 | int aRes[3]; /* Results */ |
| 64054 | Mem *pMem; /* Write results here */ |
| 64055 | } cd; |
| 64056 | struct OP_JournalMode_stack_vars { |
| 64057 | Btree *pBt; /* Btree to change journal mode of */ |
| 64058 | Pager *pPager; /* Pager associated with pBt */ |
| 64059 | int eNew; /* New journal mode */ |
| 64060 | int eOld; /* The old journal mode */ |
| 64061 | const char *zFilename; /* Name of database file for pPager */ |
| 64062 | } ce; |
| 64063 | struct OP_IncrVacuum_stack_vars { |
| 64064 | Btree *pBt; |
| 64065 | } cf; |
| 64066 | struct OP_VBegin_stack_vars { |
| 64067 | VTable *pVTab; |
| 64068 | } cg; |
| 64069 | struct OP_VOpen_stack_vars { |
| 64070 | VdbeCursor *pCur; |
| 64071 | sqlite3_vtab_cursor *pVtabCursor; |
| 64072 | sqlite3_vtab *pVtab; |
| 64073 | sqlite3_module *pModule; |
| 64074 | } ch; |
| 64075 | struct OP_VFilter_stack_vars { |
| 64076 | int nArg; |
| 64077 | int iQuery; |
| 64078 | const sqlite3_module *pModule; |
| 64079 | Mem *pQuery; |
| @@ -64082,40 +64053,40 @@ | |
| 64082 | sqlite3_vtab *pVtab; |
| 64083 | VdbeCursor *pCur; |
| 64084 | int res; |
| 64085 | int i; |
| 64086 | Mem **apArg; |
| 64087 | } ci; |
| 64088 | struct OP_VColumn_stack_vars { |
| 64089 | sqlite3_vtab *pVtab; |
| 64090 | const sqlite3_module *pModule; |
| 64091 | Mem *pDest; |
| 64092 | sqlite3_context sContext; |
| 64093 | } cj; |
| 64094 | struct OP_VNext_stack_vars { |
| 64095 | sqlite3_vtab *pVtab; |
| 64096 | const sqlite3_module *pModule; |
| 64097 | int res; |
| 64098 | VdbeCursor *pCur; |
| 64099 | } ck; |
| 64100 | struct OP_VRename_stack_vars { |
| 64101 | sqlite3_vtab *pVtab; |
| 64102 | Mem *pName; |
| 64103 | } cl; |
| 64104 | struct OP_VUpdate_stack_vars { |
| 64105 | sqlite3_vtab *pVtab; |
| 64106 | sqlite3_module *pModule; |
| 64107 | int nArg; |
| 64108 | int i; |
| 64109 | sqlite_int64 rowid; |
| 64110 | Mem **apArg; |
| 64111 | Mem *pX; |
| 64112 | } cm; |
| 64113 | struct OP_Trace_stack_vars { |
| 64114 | char *zTrace; |
| 64115 | char *z; |
| 64116 | } cn; |
| 64117 | } u; |
| 64118 | /* End automatically generated code |
| 64119 | ********************************************************************/ |
| 64120 | |
| 64121 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| @@ -66746,17 +66717,10 @@ | |
| 66746 | ** This opcode works the same as OP_OpenEphemeral. It has a |
| 66747 | ** different name to distinguish its use. Tables created using |
| 66748 | ** by this opcode will be used for automatically created transient |
| 66749 | ** indices in joins. |
| 66750 | */ |
| 66751 | /* Opcode: OpenSorter P1 P2 * P4 * |
| 66752 | ** |
| 66753 | ** This opcode works like OP_OpenEphemeral except that it opens |
| 66754 | ** a transient index that is specifically designed to sort large |
| 66755 | ** tables using an external merge-sort algorithm. |
| 66756 | */ |
| 66757 | case OP_OpenSorter: |
| 66758 | case OP_OpenAutoindex: |
| 66759 | case OP_OpenEphemeral: { |
| 66760 | #if 0 /* local variables moved into u.ax */ |
| 66761 | VdbeCursor *pCx; |
| 66762 | #endif /* local variables moved into u.ax */ |
| @@ -66766,11 +66730,10 @@ | |
| 66766 | SQLITE_OPEN_EXCLUSIVE | |
| 66767 | SQLITE_OPEN_DELETEONCLOSE | |
| 66768 | SQLITE_OPEN_TRANSIENT_DB; |
| 66769 | |
| 66770 | assert( pOp->p1>=0 ); |
| 66771 | assert( (pOp->opcode==OP_OpenSorter)==((pOp->p5 & BTREE_SORTER)!=0) ); |
| 66772 | u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66773 | if( u.ax.pCx==0 ) goto no_mem; |
| 66774 | u.ax.pCx->nullRow = 1; |
| 66775 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, |
| 66776 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| @@ -66800,14 +66763,33 @@ | |
| 66800 | u.ax.pCx->isTable = 1; |
| 66801 | } |
| 66802 | } |
| 66803 | u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66804 | u.ax.pCx->isIndex = !u.ax.pCx->isTable; |
| 66805 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 66806 | if( rc==SQLITE_OK && pOp->opcode==OP_OpenSorter ){ |
| 66807 | rc = sqlite3VdbeSorterInit(db, u.ax.pCx); |
| 66808 | } |
| 66809 | #endif |
| 66810 | break; |
| 66811 | } |
| 66812 | |
| 66813 | /* Opcode: OpenPseudo P1 P2 P3 * * |
| @@ -66824,21 +66806,21 @@ | |
| 66824 | ** |
| 66825 | ** P3 is the number of fields in the records that will be stored by |
| 66826 | ** the pseudo-table. |
| 66827 | */ |
| 66828 | case OP_OpenPseudo: { |
| 66829 | #if 0 /* local variables moved into u.ay */ |
| 66830 | VdbeCursor *pCx; |
| 66831 | #endif /* local variables moved into u.ay */ |
| 66832 | |
| 66833 | assert( pOp->p1>=0 ); |
| 66834 | u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 66835 | if( u.ay.pCx==0 ) goto no_mem; |
| 66836 | u.ay.pCx->nullRow = 1; |
| 66837 | u.ay.pCx->pseudoTableReg = pOp->p2; |
| 66838 | u.ay.pCx->isTable = 1; |
| 66839 | u.ay.pCx->isIndex = 0; |
| 66840 | break; |
| 66841 | } |
| 66842 | |
| 66843 | /* Opcode: Close P1 * * * * |
| 66844 | ** |
| @@ -66906,39 +66888,39 @@ | |
| 66906 | */ |
| 66907 | case OP_SeekLt: /* jump, in3 */ |
| 66908 | case OP_SeekLe: /* jump, in3 */ |
| 66909 | case OP_SeekGe: /* jump, in3 */ |
| 66910 | case OP_SeekGt: { /* jump, in3 */ |
| 66911 | #if 0 /* local variables moved into u.az */ |
| 66912 | int res; |
| 66913 | int oc; |
| 66914 | VdbeCursor *pC; |
| 66915 | UnpackedRecord r; |
| 66916 | int nField; |
| 66917 | i64 iKey; /* The rowid we are to seek to */ |
| 66918 | #endif /* local variables moved into u.az */ |
| 66919 | |
| 66920 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 66921 | assert( pOp->p2!=0 ); |
| 66922 | u.az.pC = p->apCsr[pOp->p1]; |
| 66923 | assert( u.az.pC!=0 ); |
| 66924 | assert( u.az.pC->pseudoTableReg==0 ); |
| 66925 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 66926 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 66927 | assert( OP_SeekGt == OP_SeekLt+3 ); |
| 66928 | assert( u.az.pC->isOrdered ); |
| 66929 | if( ALWAYS(u.az.pC->pCursor!=0) ){ |
| 66930 | u.az.oc = pOp->opcode; |
| 66931 | u.az.pC->nullRow = 0; |
| 66932 | if( u.az.pC->isTable ){ |
| 66933 | /* The input value in P3 might be of any type: integer, real, string, |
| 66934 | ** blob, or NULL. But it needs to be an integer before we can do |
| 66935 | ** the seek, so covert it. */ |
| 66936 | pIn3 = &aMem[pOp->p3]; |
| 66937 | applyNumericAffinity(pIn3); |
| 66938 | u.az.iKey = sqlite3VdbeIntValue(pIn3); |
| 66939 | u.az.pC->rowidIsValid = 0; |
| 66940 | |
| 66941 | /* If the P3 value could not be converted into an integer without |
| 66942 | ** loss of information, then special processing is required... */ |
| 66943 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 66944 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -66949,105 +66931,105 @@ | |
| 66949 | } |
| 66950 | /* If we reach this point, then the P3 value must be a floating |
| 66951 | ** point number. */ |
| 66952 | assert( (pIn3->flags & MEM_Real)!=0 ); |
| 66953 | |
| 66954 | if( u.az.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.az.iKey || pIn3->r>0) ){ |
| 66955 | /* The P3 value is too large in magnitude to be expressed as an |
| 66956 | ** integer. */ |
| 66957 | u.az.res = 1; |
| 66958 | if( pIn3->r<0 ){ |
| 66959 | if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); |
| 66960 | rc = sqlite3BtreeFirst(u.az.pC->pCursor, &u.az.res); |
| 66961 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66962 | } |
| 66963 | }else{ |
| 66964 | if( u.az.oc<=OP_SeekLe ){ assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); |
| 66965 | rc = sqlite3BtreeLast(u.az.pC->pCursor, &u.az.res); |
| 66966 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66967 | } |
| 66968 | } |
| 66969 | if( u.az.res ){ |
| 66970 | pc = pOp->p2 - 1; |
| 66971 | } |
| 66972 | break; |
| 66973 | }else if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekGe ){ |
| 66974 | /* Use the ceiling() function to convert real->int */ |
| 66975 | if( pIn3->r > (double)u.az.iKey ) u.az.iKey++; |
| 66976 | }else{ |
| 66977 | /* Use the floor() function to convert real->int */ |
| 66978 | assert( u.az.oc==OP_SeekLe || u.az.oc==OP_SeekGt ); |
| 66979 | if( pIn3->r < (double)u.az.iKey ) u.az.iKey--; |
| 66980 | } |
| 66981 | } |
| 66982 | rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, 0, (u64)u.az.iKey, 0, &u.az.res); |
| 66983 | if( rc!=SQLITE_OK ){ |
| 66984 | goto abort_due_to_error; |
| 66985 | } |
| 66986 | if( u.az.res==0 ){ |
| 66987 | u.az.pC->rowidIsValid = 1; |
| 66988 | u.az.pC->lastRowid = u.az.iKey; |
| 66989 | } |
| 66990 | }else{ |
| 66991 | u.az.nField = pOp->p4.i; |
| 66992 | assert( pOp->p4type==P4_INT32 ); |
| 66993 | assert( u.az.nField>0 ); |
| 66994 | u.az.r.pKeyInfo = u.az.pC->pKeyInfo; |
| 66995 | u.az.r.nField = (u16)u.az.nField; |
| 66996 | |
| 66997 | /* The next line of code computes as follows, only faster: |
| 66998 | ** if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekLe ){ |
| 66999 | ** u.az.r.flags = UNPACKED_INCRKEY; |
| 67000 | ** }else{ |
| 67001 | ** u.az.r.flags = 0; |
| 67002 | ** } |
| 67003 | */ |
| 67004 | u.az.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.az.oc - OP_SeekLt))); |
| 67005 | assert( u.az.oc!=OP_SeekGt || u.az.r.flags==UNPACKED_INCRKEY ); |
| 67006 | assert( u.az.oc!=OP_SeekLe || u.az.r.flags==UNPACKED_INCRKEY ); |
| 67007 | assert( u.az.oc!=OP_SeekGe || u.az.r.flags==0 ); |
| 67008 | assert( u.az.oc!=OP_SeekLt || u.az.r.flags==0 ); |
| 67009 | |
| 67010 | u.az.r.aMem = &aMem[pOp->p3]; |
| 67011 | #ifdef SQLITE_DEBUG |
| 67012 | { int i; for(i=0; i<u.az.r.nField; i++) assert( memIsValid(&u.az.r.aMem[i]) ); } |
| 67013 | #endif |
| 67014 | ExpandBlob(u.az.r.aMem); |
| 67015 | rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res); |
| 67016 | if( rc!=SQLITE_OK ){ |
| 67017 | goto abort_due_to_error; |
| 67018 | } |
| 67019 | u.az.pC->rowidIsValid = 0; |
| 67020 | } |
| 67021 | u.az.pC->deferredMoveto = 0; |
| 67022 | u.az.pC->cacheStatus = CACHE_STALE; |
| 67023 | #ifdef SQLITE_TEST |
| 67024 | sqlite3_search_count++; |
| 67025 | #endif |
| 67026 | if( u.az.oc>=OP_SeekGe ){ assert( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ); |
| 67027 | if( u.az.res<0 || (u.az.res==0 && u.az.oc==OP_SeekGt) ){ |
| 67028 | rc = sqlite3BtreeNext(u.az.pC->pCursor, &u.az.res); |
| 67029 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67030 | u.az.pC->rowidIsValid = 0; |
| 67031 | }else{ |
| 67032 | u.az.res = 0; |
| 67033 | } |
| 67034 | }else{ |
| 67035 | assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); |
| 67036 | if( u.az.res>0 || (u.az.res==0 && u.az.oc==OP_SeekLt) ){ |
| 67037 | rc = sqlite3BtreePrevious(u.az.pC->pCursor, &u.az.res); |
| 67038 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67039 | u.az.pC->rowidIsValid = 0; |
| 67040 | }else{ |
| 67041 | /* u.az.res might be negative because the table is empty. Check to |
| 67042 | ** see if this is the case. |
| 67043 | */ |
| 67044 | u.az.res = sqlite3BtreeEof(u.az.pC->pCursor); |
| 67045 | } |
| 67046 | } |
| 67047 | assert( pOp->p2>0 ); |
| 67048 | if( u.az.res ){ |
| 67049 | pc = pOp->p2 - 1; |
| 67050 | } |
| 67051 | }else{ |
| 67052 | /* This happens when attempting to open the sqlite3_master table |
| 67053 | ** for read access returns SQLITE_EMPTY. In this case always |
| @@ -67066,24 +67048,24 @@ | |
| 67066 | ** This is actually a deferred seek. Nothing actually happens until |
| 67067 | ** the cursor is used to read a record. That way, if no reads |
| 67068 | ** occur, no unnecessary I/O happens. |
| 67069 | */ |
| 67070 | case OP_Seek: { /* in2 */ |
| 67071 | #if 0 /* local variables moved into u.ba */ |
| 67072 | VdbeCursor *pC; |
| 67073 | #endif /* local variables moved into u.ba */ |
| 67074 | |
| 67075 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67076 | u.ba.pC = p->apCsr[pOp->p1]; |
| 67077 | assert( u.ba.pC!=0 ); |
| 67078 | if( ALWAYS(u.ba.pC->pCursor!=0) ){ |
| 67079 | assert( u.ba.pC->isTable ); |
| 67080 | u.ba.pC->nullRow = 0; |
| 67081 | pIn2 = &aMem[pOp->p2]; |
| 67082 | u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67083 | u.ba.pC->rowidIsValid = 0; |
| 67084 | u.ba.pC->deferredMoveto = 1; |
| 67085 | } |
| 67086 | break; |
| 67087 | } |
| 67088 | |
| 67089 | |
| @@ -67111,66 +67093,66 @@ | |
| 67111 | ** |
| 67112 | ** See also: Found, NotExists, IsUnique |
| 67113 | */ |
| 67114 | case OP_NotFound: /* jump, in3 */ |
| 67115 | case OP_Found: { /* jump, in3 */ |
| 67116 | #if 0 /* local variables moved into u.bb */ |
| 67117 | int alreadyExists; |
| 67118 | VdbeCursor *pC; |
| 67119 | int res; |
| 67120 | UnpackedRecord *pIdxKey; |
| 67121 | UnpackedRecord r; |
| 67122 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 67123 | #endif /* local variables moved into u.bb */ |
| 67124 | |
| 67125 | #ifdef SQLITE_TEST |
| 67126 | sqlite3_found_count++; |
| 67127 | #endif |
| 67128 | |
| 67129 | u.bb.alreadyExists = 0; |
| 67130 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67131 | assert( pOp->p4type==P4_INT32 ); |
| 67132 | u.bb.pC = p->apCsr[pOp->p1]; |
| 67133 | assert( u.bb.pC!=0 ); |
| 67134 | pIn3 = &aMem[pOp->p3]; |
| 67135 | if( ALWAYS(u.bb.pC->pCursor!=0) ){ |
| 67136 | |
| 67137 | assert( u.bb.pC->isTable==0 ); |
| 67138 | if( pOp->p4.i>0 ){ |
| 67139 | u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo; |
| 67140 | u.bb.r.nField = (u16)pOp->p4.i; |
| 67141 | u.bb.r.aMem = pIn3; |
| 67142 | #ifdef SQLITE_DEBUG |
| 67143 | { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); } |
| 67144 | #endif |
| 67145 | u.bb.r.flags = UNPACKED_PREFIX_MATCH; |
| 67146 | u.bb.pIdxKey = &u.bb.r; |
| 67147 | }else{ |
| 67148 | assert( pIn3->flags & MEM_Blob ); |
| 67149 | assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ |
| 67150 | u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z, |
| 67151 | u.bb.aTempRec, sizeof(u.bb.aTempRec)); |
| 67152 | if( u.bb.pIdxKey==0 ){ |
| 67153 | goto no_mem; |
| 67154 | } |
| 67155 | u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 67156 | } |
| 67157 | rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, u.bb.pIdxKey, 0, 0, &u.bb.res); |
| 67158 | if( pOp->p4.i==0 ){ |
| 67159 | sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey); |
| 67160 | } |
| 67161 | if( rc!=SQLITE_OK ){ |
| 67162 | break; |
| 67163 | } |
| 67164 | u.bb.alreadyExists = (u.bb.res==0); |
| 67165 | u.bb.pC->deferredMoveto = 0; |
| 67166 | u.bb.pC->cacheStatus = CACHE_STALE; |
| 67167 | } |
| 67168 | if( pOp->opcode==OP_Found ){ |
| 67169 | if( u.bb.alreadyExists ) pc = pOp->p2 - 1; |
| 67170 | }else{ |
| 67171 | if( !u.bb.alreadyExists ) pc = pOp->p2 - 1; |
| 67172 | } |
| 67173 | break; |
| 67174 | } |
| 67175 | |
| 67176 | /* Opcode: IsUnique P1 P2 P3 P4 * |
| @@ -67198,67 +67180,67 @@ | |
| 67198 | ** instruction. |
| 67199 | ** |
| 67200 | ** See also: NotFound, NotExists, Found |
| 67201 | */ |
| 67202 | case OP_IsUnique: { /* jump, in3 */ |
| 67203 | #if 0 /* local variables moved into u.bc */ |
| 67204 | u16 ii; |
| 67205 | VdbeCursor *pCx; |
| 67206 | BtCursor *pCrsr; |
| 67207 | u16 nField; |
| 67208 | Mem *aMx; |
| 67209 | UnpackedRecord r; /* B-Tree index search key */ |
| 67210 | i64 R; /* Rowid stored in register P3 */ |
| 67211 | #endif /* local variables moved into u.bc */ |
| 67212 | |
| 67213 | pIn3 = &aMem[pOp->p3]; |
| 67214 | u.bc.aMx = &aMem[pOp->p4.i]; |
| 67215 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 67216 | assert( pOp->p4type==P4_INT32 ); |
| 67217 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 67218 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67219 | |
| 67220 | /* Find the index cursor. */ |
| 67221 | u.bc.pCx = p->apCsr[pOp->p1]; |
| 67222 | assert( u.bc.pCx->deferredMoveto==0 ); |
| 67223 | u.bc.pCx->seekResult = 0; |
| 67224 | u.bc.pCx->cacheStatus = CACHE_STALE; |
| 67225 | u.bc.pCrsr = u.bc.pCx->pCursor; |
| 67226 | |
| 67227 | /* If any of the values are NULL, take the jump. */ |
| 67228 | u.bc.nField = u.bc.pCx->pKeyInfo->nField; |
| 67229 | for(u.bc.ii=0; u.bc.ii<u.bc.nField; u.bc.ii++){ |
| 67230 | if( u.bc.aMx[u.bc.ii].flags & MEM_Null ){ |
| 67231 | pc = pOp->p2 - 1; |
| 67232 | u.bc.pCrsr = 0; |
| 67233 | break; |
| 67234 | } |
| 67235 | } |
| 67236 | assert( (u.bc.aMx[u.bc.nField].flags & MEM_Null)==0 ); |
| 67237 | |
| 67238 | if( u.bc.pCrsr!=0 ){ |
| 67239 | /* Populate the index search key. */ |
| 67240 | u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo; |
| 67241 | u.bc.r.nField = u.bc.nField + 1; |
| 67242 | u.bc.r.flags = UNPACKED_PREFIX_SEARCH; |
| 67243 | u.bc.r.aMem = u.bc.aMx; |
| 67244 | #ifdef SQLITE_DEBUG |
| 67245 | { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } |
| 67246 | #endif |
| 67247 | |
| 67248 | /* Extract the value of u.bc.R from register P3. */ |
| 67249 | sqlite3VdbeMemIntegerify(pIn3); |
| 67250 | u.bc.R = pIn3->u.i; |
| 67251 | |
| 67252 | /* Search the B-Tree index. If no conflicting record is found, jump |
| 67253 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
| 67254 | ** register P3 and fall through to the next instruction. */ |
| 67255 | rc = sqlite3BtreeMovetoUnpacked(u.bc.pCrsr, &u.bc.r, 0, 0, &u.bc.pCx->seekResult); |
| 67256 | if( (u.bc.r.flags & UNPACKED_PREFIX_SEARCH) || u.bc.r.rowid==u.bc.R ){ |
| 67257 | pc = pOp->p2 - 1; |
| 67258 | }else{ |
| 67259 | pIn3->u.i = u.bc.r.rowid; |
| 67260 | } |
| 67261 | } |
| 67262 | break; |
| 67263 | } |
| 67264 | |
| @@ -67275,46 +67257,46 @@ | |
| 67275 | ** P1 is an index. |
| 67276 | ** |
| 67277 | ** See also: Found, NotFound, IsUnique |
| 67278 | */ |
| 67279 | case OP_NotExists: { /* jump, in3 */ |
| 67280 | #if 0 /* local variables moved into u.bd */ |
| 67281 | VdbeCursor *pC; |
| 67282 | BtCursor *pCrsr; |
| 67283 | int res; |
| 67284 | u64 iKey; |
| 67285 | #endif /* local variables moved into u.bd */ |
| 67286 | |
| 67287 | pIn3 = &aMem[pOp->p3]; |
| 67288 | assert( pIn3->flags & MEM_Int ); |
| 67289 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67290 | u.bd.pC = p->apCsr[pOp->p1]; |
| 67291 | assert( u.bd.pC!=0 ); |
| 67292 | assert( u.bd.pC->isTable ); |
| 67293 | assert( u.bd.pC->pseudoTableReg==0 ); |
| 67294 | u.bd.pCrsr = u.bd.pC->pCursor; |
| 67295 | if( ALWAYS(u.bd.pCrsr!=0) ){ |
| 67296 | u.bd.res = 0; |
| 67297 | u.bd.iKey = pIn3->u.i; |
| 67298 | rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, 0, u.bd.iKey, 0, &u.bd.res); |
| 67299 | u.bd.pC->lastRowid = pIn3->u.i; |
| 67300 | u.bd.pC->rowidIsValid = u.bd.res==0 ?1:0; |
| 67301 | u.bd.pC->nullRow = 0; |
| 67302 | u.bd.pC->cacheStatus = CACHE_STALE; |
| 67303 | u.bd.pC->deferredMoveto = 0; |
| 67304 | if( u.bd.res!=0 ){ |
| 67305 | pc = pOp->p2 - 1; |
| 67306 | assert( u.bd.pC->rowidIsValid==0 ); |
| 67307 | } |
| 67308 | u.bd.pC->seekResult = u.bd.res; |
| 67309 | }else{ |
| 67310 | /* This happens when an attempt to open a read cursor on the |
| 67311 | ** sqlite_master table returns SQLITE_EMPTY. |
| 67312 | */ |
| 67313 | pc = pOp->p2 - 1; |
| 67314 | assert( u.bd.pC->rowidIsValid==0 ); |
| 67315 | u.bd.pC->seekResult = 0; |
| 67316 | } |
| 67317 | break; |
| 67318 | } |
| 67319 | |
| 67320 | /* Opcode: Sequence P1 P2 * * * |
| @@ -67345,25 +67327,25 @@ | |
| 67345 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 67346 | ** generated record number. This P3 mechanism is used to help implement the |
| 67347 | ** AUTOINCREMENT feature. |
| 67348 | */ |
| 67349 | case OP_NewRowid: { /* out2-prerelease */ |
| 67350 | #if 0 /* local variables moved into u.be */ |
| 67351 | i64 v; /* The new rowid */ |
| 67352 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 67353 | int res; /* Result of an sqlite3BtreeLast() */ |
| 67354 | int cnt; /* Counter to limit the number of searches */ |
| 67355 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 67356 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 67357 | #endif /* local variables moved into u.be */ |
| 67358 | |
| 67359 | u.be.v = 0; |
| 67360 | u.be.res = 0; |
| 67361 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67362 | u.be.pC = p->apCsr[pOp->p1]; |
| 67363 | assert( u.be.pC!=0 ); |
| 67364 | if( NEVER(u.be.pC->pCursor==0) ){ |
| 67365 | /* The zero initialization above is all that is needed */ |
| 67366 | }else{ |
| 67367 | /* The next rowid or record number (different terms for the same |
| 67368 | ** thing) is obtained in a two-step algorithm. |
| 67369 | ** |
| @@ -67375,11 +67357,11 @@ | |
| 67375 | ** The second algorithm is to select a rowid at random and see if |
| 67376 | ** it already exists in the table. If it does not exist, we have |
| 67377 | ** succeeded. If the random rowid does exist, we select a new one |
| 67378 | ** and try again, up to 100 times. |
| 67379 | */ |
| 67380 | assert( u.be.pC->isTable ); |
| 67381 | |
| 67382 | #ifdef SQLITE_32BIT_ROWID |
| 67383 | # define MAX_ROWID 0x7fffffff |
| 67384 | #else |
| 67385 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| @@ -67387,101 +67369,101 @@ | |
| 67387 | ** to provide the constant while making all compilers happy. |
| 67388 | */ |
| 67389 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 67390 | #endif |
| 67391 | |
| 67392 | if( !u.be.pC->useRandomRowid ){ |
| 67393 | u.be.v = sqlite3BtreeGetCachedRowid(u.be.pC->pCursor); |
| 67394 | if( u.be.v==0 ){ |
| 67395 | rc = sqlite3BtreeLast(u.be.pC->pCursor, &u.be.res); |
| 67396 | if( rc!=SQLITE_OK ){ |
| 67397 | goto abort_due_to_error; |
| 67398 | } |
| 67399 | if( u.be.res ){ |
| 67400 | u.be.v = 1; /* IMP: R-61914-48074 */ |
| 67401 | }else{ |
| 67402 | assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) ); |
| 67403 | rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v); |
| 67404 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 67405 | if( u.be.v==MAX_ROWID ){ |
| 67406 | u.be.pC->useRandomRowid = 1; |
| 67407 | }else{ |
| 67408 | u.be.v++; /* IMP: R-29538-34987 */ |
| 67409 | } |
| 67410 | } |
| 67411 | } |
| 67412 | |
| 67413 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 67414 | if( pOp->p3 ){ |
| 67415 | /* Assert that P3 is a valid memory cell. */ |
| 67416 | assert( pOp->p3>0 ); |
| 67417 | if( p->pFrame ){ |
| 67418 | for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent); |
| 67419 | /* Assert that P3 is a valid memory cell. */ |
| 67420 | assert( pOp->p3<=u.be.pFrame->nMem ); |
| 67421 | u.be.pMem = &u.be.pFrame->aMem[pOp->p3]; |
| 67422 | }else{ |
| 67423 | /* Assert that P3 is a valid memory cell. */ |
| 67424 | assert( pOp->p3<=p->nMem ); |
| 67425 | u.be.pMem = &aMem[pOp->p3]; |
| 67426 | memAboutToChange(p, u.be.pMem); |
| 67427 | } |
| 67428 | assert( memIsValid(u.be.pMem) ); |
| 67429 | |
| 67430 | REGISTER_TRACE(pOp->p3, u.be.pMem); |
| 67431 | sqlite3VdbeMemIntegerify(u.be.pMem); |
| 67432 | assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 67433 | if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){ |
| 67434 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 67435 | goto abort_due_to_error; |
| 67436 | } |
| 67437 | if( u.be.v<u.be.pMem->u.i+1 ){ |
| 67438 | u.be.v = u.be.pMem->u.i + 1; |
| 67439 | } |
| 67440 | u.be.pMem->u.i = u.be.v; |
| 67441 | } |
| 67442 | #endif |
| 67443 | |
| 67444 | sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0); |
| 67445 | } |
| 67446 | if( u.be.pC->useRandomRowid ){ |
| 67447 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 67448 | ** largest possible integer (9223372036854775807) then the database |
| 67449 | ** engine starts picking positive candidate ROWIDs at random until |
| 67450 | ** it finds one that is not previously used. */ |
| 67451 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 67452 | ** an AUTOINCREMENT table. */ |
| 67453 | /* on the first attempt, simply do one more than previous */ |
| 67454 | u.be.v = lastRowid; |
| 67455 | u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67456 | u.be.v++; /* ensure non-zero */ |
| 67457 | u.be.cnt = 0; |
| 67458 | while( ((rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, |
| 67459 | 0, &u.be.res))==SQLITE_OK) |
| 67460 | && (u.be.res==0) |
| 67461 | && (++u.be.cnt<100)){ |
| 67462 | /* collision - try another random rowid */ |
| 67463 | sqlite3_randomness(sizeof(u.be.v), &u.be.v); |
| 67464 | if( u.be.cnt<5 ){ |
| 67465 | /* try "small" random rowids for the initial attempts */ |
| 67466 | u.be.v &= 0xffffff; |
| 67467 | }else{ |
| 67468 | u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67469 | } |
| 67470 | u.be.v++; /* ensure non-zero */ |
| 67471 | } |
| 67472 | if( rc==SQLITE_OK && u.be.res==0 ){ |
| 67473 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 67474 | goto abort_due_to_error; |
| 67475 | } |
| 67476 | assert( u.be.v>0 ); /* EV: R-40812-03570 */ |
| 67477 | } |
| 67478 | u.be.pC->rowidIsValid = 0; |
| 67479 | u.be.pC->deferredMoveto = 0; |
| 67480 | u.be.pC->cacheStatus = CACHE_STALE; |
| 67481 | } |
| 67482 | pOut->u.i = u.be.v; |
| 67483 | break; |
| 67484 | } |
| 67485 | |
| 67486 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 67487 | ** |
| @@ -67527,74 +67509,74 @@ | |
| 67527 | ** This works exactly like OP_Insert except that the key is the |
| 67528 | ** integer value P3, not the value of the integer stored in register P3. |
| 67529 | */ |
| 67530 | case OP_Insert: |
| 67531 | case OP_InsertInt: { |
| 67532 | #if 0 /* local variables moved into u.bf */ |
| 67533 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 67534 | Mem *pKey; /* MEM cell holding key for the record */ |
| 67535 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 67536 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 67537 | int nZero; /* Number of zero-bytes to append */ |
| 67538 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 67539 | const char *zDb; /* database name - used by the update hook */ |
| 67540 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 67541 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 67542 | #endif /* local variables moved into u.bf */ |
| 67543 | |
| 67544 | u.bf.pData = &aMem[pOp->p2]; |
| 67545 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67546 | assert( memIsValid(u.bf.pData) ); |
| 67547 | u.bf.pC = p->apCsr[pOp->p1]; |
| 67548 | assert( u.bf.pC!=0 ); |
| 67549 | assert( u.bf.pC->pCursor!=0 ); |
| 67550 | assert( u.bf.pC->pseudoTableReg==0 ); |
| 67551 | assert( u.bf.pC->isTable ); |
| 67552 | REGISTER_TRACE(pOp->p2, u.bf.pData); |
| 67553 | |
| 67554 | if( pOp->opcode==OP_Insert ){ |
| 67555 | u.bf.pKey = &aMem[pOp->p3]; |
| 67556 | assert( u.bf.pKey->flags & MEM_Int ); |
| 67557 | assert( memIsValid(u.bf.pKey) ); |
| 67558 | REGISTER_TRACE(pOp->p3, u.bf.pKey); |
| 67559 | u.bf.iKey = u.bf.pKey->u.i; |
| 67560 | }else{ |
| 67561 | assert( pOp->opcode==OP_InsertInt ); |
| 67562 | u.bf.iKey = pOp->p3; |
| 67563 | } |
| 67564 | |
| 67565 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 67566 | if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bf.iKey; |
| 67567 | if( u.bf.pData->flags & MEM_Null ){ |
| 67568 | u.bf.pData->z = 0; |
| 67569 | u.bf.pData->n = 0; |
| 67570 | }else{ |
| 67571 | assert( u.bf.pData->flags & (MEM_Blob|MEM_Str) ); |
| 67572 | } |
| 67573 | u.bf.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bf.pC->seekResult : 0); |
| 67574 | if( u.bf.pData->flags & MEM_Zero ){ |
| 67575 | u.bf.nZero = u.bf.pData->u.nZero; |
| 67576 | }else{ |
| 67577 | u.bf.nZero = 0; |
| 67578 | } |
| 67579 | sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, 0); |
| 67580 | rc = sqlite3BtreeInsert(u.bf.pC->pCursor, 0, u.bf.iKey, |
| 67581 | u.bf.pData->z, u.bf.pData->n, u.bf.nZero, |
| 67582 | pOp->p5 & OPFLAG_APPEND, u.bf.seekResult |
| 67583 | ); |
| 67584 | u.bf.pC->rowidIsValid = 0; |
| 67585 | u.bf.pC->deferredMoveto = 0; |
| 67586 | u.bf.pC->cacheStatus = CACHE_STALE; |
| 67587 | |
| 67588 | /* Invoke the update-hook if required. */ |
| 67589 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67590 | u.bf.zDb = db->aDb[u.bf.pC->iDb].zName; |
| 67591 | u.bf.zTbl = pOp->p4.z; |
| 67592 | u.bf.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 67593 | assert( u.bf.pC->isTable ); |
| 67594 | db->xUpdateCallback(db->pUpdateArg, u.bf.op, u.bf.zDb, u.bf.zTbl, u.bf.iKey); |
| 67595 | assert( u.bf.pC->iDb>=0 ); |
| 67596 | } |
| 67597 | break; |
| 67598 | } |
| 67599 | |
| 67600 | /* Opcode: Delete P1 P2 * P4 * |
| @@ -67616,51 +67598,51 @@ | |
| 67616 | ** pointing to. The update hook will be invoked, if it exists. |
| 67617 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 67618 | ** using OP_NotFound prior to invoking this opcode. |
| 67619 | */ |
| 67620 | case OP_Delete: { |
| 67621 | #if 0 /* local variables moved into u.bg */ |
| 67622 | i64 iKey; |
| 67623 | VdbeCursor *pC; |
| 67624 | #endif /* local variables moved into u.bg */ |
| 67625 | |
| 67626 | u.bg.iKey = 0; |
| 67627 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67628 | u.bg.pC = p->apCsr[pOp->p1]; |
| 67629 | assert( u.bg.pC!=0 ); |
| 67630 | assert( u.bg.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 67631 | |
| 67632 | /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the |
| 67633 | ** row being deleted. |
| 67634 | */ |
| 67635 | if( db->xUpdateCallback && pOp->p4.z ){ |
| 67636 | assert( u.bg.pC->isTable ); |
| 67637 | assert( u.bg.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 67638 | u.bg.iKey = u.bg.pC->lastRowid; |
| 67639 | } |
| 67640 | |
| 67641 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 67642 | ** OP_Column on the same table without any intervening operations that |
| 67643 | ** might move or invalidate the cursor. Hence cursor u.bg.pC is always pointing |
| 67644 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 67645 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 67646 | ** to guard against future changes to the code generator. |
| 67647 | **/ |
| 67648 | assert( u.bg.pC->deferredMoveto==0 ); |
| 67649 | rc = sqlite3VdbeCursorMoveto(u.bg.pC); |
| 67650 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67651 | |
| 67652 | sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); |
| 67653 | rc = sqlite3BtreeDelete(u.bg.pC->pCursor); |
| 67654 | u.bg.pC->cacheStatus = CACHE_STALE; |
| 67655 | |
| 67656 | /* Invoke the update-hook if required. */ |
| 67657 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67658 | const char *zDb = db->aDb[u.bg.pC->iDb].zName; |
| 67659 | const char *zTbl = pOp->p4.z; |
| 67660 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bg.iKey); |
| 67661 | assert( u.bg.pC->iDb>=0 ); |
| 67662 | } |
| 67663 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 67664 | break; |
| 67665 | } |
| 67666 | /* Opcode: ResetCount * * * * * |
| @@ -67673,10 +67655,53 @@ | |
| 67673 | case OP_ResetCount: { |
| 67674 | sqlite3VdbeSetChanges(db, p->nChange); |
| 67675 | p->nChange = 0; |
| 67676 | break; |
| 67677 | } |
| 67678 | |
| 67679 | /* Opcode: RowData P1 P2 * * * |
| 67680 | ** |
| 67681 | ** Write into register P2 the complete row data for cursor P1. |
| 67682 | ** There is no interpretation of the data. |
| @@ -67696,72 +67721,67 @@ | |
| 67696 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 67697 | ** of a real table, not a pseudo-table. |
| 67698 | */ |
| 67699 | case OP_RowKey: |
| 67700 | case OP_RowData: { |
| 67701 | #if 0 /* local variables moved into u.bh */ |
| 67702 | VdbeCursor *pC; |
| 67703 | BtCursor *pCrsr; |
| 67704 | u32 n; |
| 67705 | i64 n64; |
| 67706 | #endif /* local variables moved into u.bh */ |
| 67707 | |
| 67708 | pOut = &aMem[pOp->p2]; |
| 67709 | memAboutToChange(p, pOut); |
| 67710 | |
| 67711 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 67712 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67713 | u.bh.pC = p->apCsr[pOp->p1]; |
| 67714 | assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey ); |
| 67715 | assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData ); |
| 67716 | assert( u.bh.pC!=0 ); |
| 67717 | assert( u.bh.pC->nullRow==0 ); |
| 67718 | assert( u.bh.pC->pseudoTableReg==0 ); |
| 67719 | |
| 67720 | if( isSorter(u.bh.pC) ){ |
| 67721 | assert( pOp->opcode==OP_RowKey ); |
| 67722 | rc = sqlite3VdbeSorterRowkey(u.bh.pC, pOut); |
| 67723 | break; |
| 67724 | } |
| 67725 | |
| 67726 | assert( u.bh.pC->pCursor!=0 ); |
| 67727 | u.bh.pCrsr = u.bh.pC->pCursor; |
| 67728 | assert( sqlite3BtreeCursorIsValid(u.bh.pCrsr) ); |
| 67729 | |
| 67730 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 67731 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 67732 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 67733 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 67734 | */ |
| 67735 | assert( u.bh.pC->deferredMoveto==0 ); |
| 67736 | rc = sqlite3VdbeCursorMoveto(u.bh.pC); |
| 67737 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67738 | |
| 67739 | if( u.bh.pC->isIndex ){ |
| 67740 | assert( !u.bh.pC->isTable ); |
| 67741 | rc = sqlite3BtreeKeySize(u.bh.pCrsr, &u.bh.n64); |
| 67742 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 67743 | if( u.bh.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67744 | goto too_big; |
| 67745 | } |
| 67746 | u.bh.n = (u32)u.bh.n64; |
| 67747 | }else{ |
| 67748 | rc = sqlite3BtreeDataSize(u.bh.pCrsr, &u.bh.n); |
| 67749 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 67750 | if( u.bh.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67751 | goto too_big; |
| 67752 | } |
| 67753 | } |
| 67754 | if( sqlite3VdbeMemGrow(pOut, u.bh.n, 0) ){ |
| 67755 | goto no_mem; |
| 67756 | } |
| 67757 | pOut->n = u.bh.n; |
| 67758 | MemSetTypeFlag(pOut, MEM_Blob); |
| 67759 | if( u.bh.pC->isIndex ){ |
| 67760 | rc = sqlite3BtreeKey(u.bh.pCrsr, 0, u.bh.n, pOut->z); |
| 67761 | }else{ |
| 67762 | rc = sqlite3BtreeData(u.bh.pCrsr, 0, u.bh.n, pOut->z); |
| 67763 | } |
| 67764 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 67765 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67766 | break; |
| 67767 | } |
| @@ -67774,46 +67794,46 @@ | |
| 67774 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 67775 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 67776 | ** one opcode now works for both table types. |
| 67777 | */ |
| 67778 | case OP_Rowid: { /* out2-prerelease */ |
| 67779 | #if 0 /* local variables moved into u.bi */ |
| 67780 | VdbeCursor *pC; |
| 67781 | i64 v; |
| 67782 | sqlite3_vtab *pVtab; |
| 67783 | const sqlite3_module *pModule; |
| 67784 | #endif /* local variables moved into u.bi */ |
| 67785 | |
| 67786 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67787 | u.bi.pC = p->apCsr[pOp->p1]; |
| 67788 | assert( u.bi.pC!=0 ); |
| 67789 | assert( u.bi.pC->pseudoTableReg==0 ); |
| 67790 | if( u.bi.pC->nullRow ){ |
| 67791 | pOut->flags = MEM_Null; |
| 67792 | break; |
| 67793 | }else if( u.bi.pC->deferredMoveto ){ |
| 67794 | u.bi.v = u.bi.pC->movetoTarget; |
| 67795 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 67796 | }else if( u.bi.pC->pVtabCursor ){ |
| 67797 | u.bi.pVtab = u.bi.pC->pVtabCursor->pVtab; |
| 67798 | u.bi.pModule = u.bi.pVtab->pModule; |
| 67799 | assert( u.bi.pModule->xRowid ); |
| 67800 | rc = u.bi.pModule->xRowid(u.bi.pC->pVtabCursor, &u.bi.v); |
| 67801 | importVtabErrMsg(p, u.bi.pVtab); |
| 67802 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 67803 | }else{ |
| 67804 | assert( u.bi.pC->pCursor!=0 ); |
| 67805 | rc = sqlite3VdbeCursorMoveto(u.bi.pC); |
| 67806 | if( rc ) goto abort_due_to_error; |
| 67807 | if( u.bi.pC->rowidIsValid ){ |
| 67808 | u.bi.v = u.bi.pC->lastRowid; |
| 67809 | }else{ |
| 67810 | rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v); |
| 67811 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 67812 | } |
| 67813 | } |
| 67814 | pOut->u.i = u.bi.v; |
| 67815 | break; |
| 67816 | } |
| 67817 | |
| 67818 | /* Opcode: NullRow P1 * * * * |
| 67819 | ** |
| @@ -67820,22 +67840,22 @@ | |
| 67820 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 67821 | ** that occur while the cursor is on the null row will always |
| 67822 | ** write a NULL. |
| 67823 | */ |
| 67824 | case OP_NullRow: { |
| 67825 | #if 0 /* local variables moved into u.bj */ |
| 67826 | VdbeCursor *pC; |
| 67827 | #endif /* local variables moved into u.bj */ |
| 67828 | |
| 67829 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67830 | u.bj.pC = p->apCsr[pOp->p1]; |
| 67831 | assert( u.bj.pC!=0 ); |
| 67832 | u.bj.pC->nullRow = 1; |
| 67833 | u.bj.pC->rowidIsValid = 0; |
| 67834 | assert( u.bj.pC->pCursor || u.bj.pC->pVtabCursor ); |
| 67835 | if( u.bj.pC->pCursor ){ |
| 67836 | sqlite3BtreeClearCursor(u.bj.pC->pCursor); |
| 67837 | } |
| 67838 | break; |
| 67839 | } |
| 67840 | |
| 67841 | /* Opcode: Last P1 P2 * * * |
| @@ -67845,30 +67865,30 @@ | |
| 67845 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67846 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67847 | ** to the following instruction. |
| 67848 | */ |
| 67849 | case OP_Last: { /* jump */ |
| 67850 | #if 0 /* local variables moved into u.bk */ |
| 67851 | VdbeCursor *pC; |
| 67852 | BtCursor *pCrsr; |
| 67853 | int res; |
| 67854 | #endif /* local variables moved into u.bk */ |
| 67855 | |
| 67856 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67857 | u.bk.pC = p->apCsr[pOp->p1]; |
| 67858 | assert( u.bk.pC!=0 ); |
| 67859 | u.bk.pCrsr = u.bk.pC->pCursor; |
| 67860 | if( NEVER(u.bk.pCrsr==0) ){ |
| 67861 | u.bk.res = 1; |
| 67862 | }else{ |
| 67863 | rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res); |
| 67864 | } |
| 67865 | u.bk.pC->nullRow = (u8)u.bk.res; |
| 67866 | u.bk.pC->deferredMoveto = 0; |
| 67867 | u.bk.pC->rowidIsValid = 0; |
| 67868 | u.bk.pC->cacheStatus = CACHE_STALE; |
| 67869 | if( pOp->p2>0 && u.bk.res ){ |
| 67870 | pc = pOp->p2 - 1; |
| 67871 | } |
| 67872 | break; |
| 67873 | } |
| 67874 | |
| @@ -67883,10 +67903,14 @@ | |
| 67883 | ** end. We use the OP_Sort opcode instead of OP_Rewind to do the |
| 67884 | ** rewinding so that the global variable will be incremented and |
| 67885 | ** regression tests can determine whether or not the optimizer is |
| 67886 | ** correctly optimizing out sorts. |
| 67887 | */ |
| 67888 | case OP_Sort: { /* jump */ |
| 67889 | #ifdef SQLITE_TEST |
| 67890 | sqlite3_sort_count++; |
| 67891 | sqlite3_search_count--; |
| 67892 | #endif |
| @@ -67900,34 +67924,35 @@ | |
| 67900 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67901 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67902 | ** to the following instruction. |
| 67903 | */ |
| 67904 | case OP_Rewind: { /* jump */ |
| 67905 | #if 0 /* local variables moved into u.bl */ |
| 67906 | VdbeCursor *pC; |
| 67907 | BtCursor *pCrsr; |
| 67908 | int res; |
| 67909 | #endif /* local variables moved into u.bl */ |
| 67910 | |
| 67911 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67912 | u.bl.pC = p->apCsr[pOp->p1]; |
| 67913 | assert( u.bl.pC!=0 ); |
| 67914 | u.bl.res = 1; |
| 67915 | if( isSorter(u.bl.pC) ){ |
| 67916 | rc = sqlite3VdbeSorterRewind(db, u.bl.pC, &u.bl.res); |
| 67917 | }else{ |
| 67918 | u.bl.pCrsr = u.bl.pC->pCursor; |
| 67919 | assert( u.bl.pCrsr ); |
| 67920 | rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); |
| 67921 | u.bl.pC->atFirst = u.bl.res==0 ?1:0; |
| 67922 | u.bl.pC->deferredMoveto = 0; |
| 67923 | u.bl.pC->cacheStatus = CACHE_STALE; |
| 67924 | u.bl.pC->rowidIsValid = 0; |
| 67925 | } |
| 67926 | u.bl.pC->nullRow = (u8)u.bl.res; |
| 67927 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 67928 | if( u.bl.res ){ |
| 67929 | pc = pOp->p2 - 1; |
| 67930 | } |
| 67931 | break; |
| 67932 | } |
| 67933 | |
| @@ -67961,45 +67986,50 @@ | |
| 67961 | ** sqlite3BtreePrevious(). |
| 67962 | ** |
| 67963 | ** If P5 is positive and the jump is taken, then event counter |
| 67964 | ** number P5-1 in the prepared statement is incremented. |
| 67965 | */ |
| 67966 | case OP_Prev: /* jump */ |
| 67967 | case OP_Next: { /* jump */ |
| 67968 | #if 0 /* local variables moved into u.bm */ |
| 67969 | VdbeCursor *pC; |
| 67970 | int res; |
| 67971 | #endif /* local variables moved into u.bm */ |
| 67972 | |
| 67973 | CHECK_FOR_INTERRUPT; |
| 67974 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67975 | assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 67976 | u.bm.pC = p->apCsr[pOp->p1]; |
| 67977 | if( u.bm.pC==0 ){ |
| 67978 | break; /* See ticket #2273 */ |
| 67979 | } |
| 67980 | if( isSorter(u.bm.pC) ){ |
| 67981 | assert( pOp->opcode==OP_Next ); |
| 67982 | rc = sqlite3VdbeSorterNext(db, u.bm.pC, &u.bm.res); |
| 67983 | }else{ |
| 67984 | u.bm.res = 1; |
| 67985 | assert( u.bm.pC->deferredMoveto==0 ); |
| 67986 | assert( u.bm.pC->pCursor ); |
| 67987 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 67988 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 67989 | rc = pOp->p4.xAdvance(u.bm.pC->pCursor, &u.bm.res); |
| 67990 | } |
| 67991 | u.bm.pC->nullRow = (u8)u.bm.res; |
| 67992 | u.bm.pC->cacheStatus = CACHE_STALE; |
| 67993 | if( u.bm.res==0 ){ |
| 67994 | pc = pOp->p2 - 1; |
| 67995 | if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 67996 | #ifdef SQLITE_TEST |
| 67997 | sqlite3_search_count++; |
| 67998 | #endif |
| 67999 | } |
| 68000 | u.bm.pC->rowidIsValid = 0; |
| 68001 | break; |
| 68002 | } |
| 68003 | |
| 68004 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 68005 | ** |
| @@ -68011,38 +68041,44 @@ | |
| 68011 | ** insert is likely to be an append. |
| 68012 | ** |
| 68013 | ** This instruction only works for indices. The equivalent instruction |
| 68014 | ** for tables is OP_Insert. |
| 68015 | */ |
| 68016 | case OP_IdxInsert: { /* in2 */ |
| 68017 | #if 0 /* local variables moved into u.bn */ |
| 68018 | VdbeCursor *pC; |
| 68019 | BtCursor *pCrsr; |
| 68020 | int nKey; |
| 68021 | const char *zKey; |
| 68022 | #endif /* local variables moved into u.bn */ |
| 68023 | |
| 68024 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68025 | u.bn.pC = p->apCsr[pOp->p1]; |
| 68026 | assert( u.bn.pC!=0 ); |
| 68027 | pIn2 = &aMem[pOp->p2]; |
| 68028 | assert( pIn2->flags & MEM_Blob ); |
| 68029 | u.bn.pCrsr = u.bn.pC->pCursor; |
| 68030 | if( ALWAYS(u.bn.pCrsr!=0) ){ |
| 68031 | assert( u.bn.pC->isTable==0 ); |
| 68032 | rc = ExpandBlob(pIn2); |
| 68033 | if( rc==SQLITE_OK ){ |
| 68034 | u.bn.nKey = pIn2->n; |
| 68035 | u.bn.zKey = pIn2->z; |
| 68036 | rc = sqlite3VdbeSorterWrite(db, u.bn.pC, u.bn.nKey); |
| 68037 | if( rc==SQLITE_OK ){ |
| 68038 | rc = sqlite3BtreeInsert(u.bn.pCrsr, u.bn.zKey, u.bn.nKey, "", 0, 0, pOp->p3, |
| 68039 | ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bn.pC->seekResult : 0) |
| 68040 | ); |
| 68041 | assert( u.bn.pC->deferredMoveto==0 ); |
| 68042 | } |
| 68043 | u.bn.pC->cacheStatus = CACHE_STALE; |
| 68044 | } |
| 68045 | } |
| 68046 | break; |
| 68047 | } |
| 68048 | |
| @@ -68051,37 +68087,37 @@ | |
| 68051 | ** The content of P3 registers starting at register P2 form |
| 68052 | ** an unpacked index key. This opcode removes that entry from the |
| 68053 | ** index opened by cursor P1. |
| 68054 | */ |
| 68055 | case OP_IdxDelete: { |
| 68056 | #if 0 /* local variables moved into u.bo */ |
| 68057 | VdbeCursor *pC; |
| 68058 | BtCursor *pCrsr; |
| 68059 | int res; |
| 68060 | UnpackedRecord r; |
| 68061 | #endif /* local variables moved into u.bo */ |
| 68062 | |
| 68063 | assert( pOp->p3>0 ); |
| 68064 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 68065 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68066 | u.bo.pC = p->apCsr[pOp->p1]; |
| 68067 | assert( u.bo.pC!=0 ); |
| 68068 | u.bo.pCrsr = u.bo.pC->pCursor; |
| 68069 | if( ALWAYS(u.bo.pCrsr!=0) ){ |
| 68070 | u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo; |
| 68071 | u.bo.r.nField = (u16)pOp->p3; |
| 68072 | u.bo.r.flags = 0; |
| 68073 | u.bo.r.aMem = &aMem[pOp->p2]; |
| 68074 | #ifdef SQLITE_DEBUG |
| 68075 | { int i; for(i=0; i<u.bo.r.nField; i++) assert( memIsValid(&u.bo.r.aMem[i]) ); } |
| 68076 | #endif |
| 68077 | rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res); |
| 68078 | if( rc==SQLITE_OK && u.bo.res==0 ){ |
| 68079 | rc = sqlite3BtreeDelete(u.bo.pCrsr); |
| 68080 | } |
| 68081 | assert( u.bo.pC->deferredMoveto==0 ); |
| 68082 | u.bo.pC->cacheStatus = CACHE_STALE; |
| 68083 | } |
| 68084 | break; |
| 68085 | } |
| 68086 | |
| 68087 | /* Opcode: IdxRowid P1 P2 * * * |
| @@ -68091,32 +68127,32 @@ | |
| 68091 | ** the rowid of the table entry to which this index entry points. |
| 68092 | ** |
| 68093 | ** See also: Rowid, MakeRecord. |
| 68094 | */ |
| 68095 | case OP_IdxRowid: { /* out2-prerelease */ |
| 68096 | #if 0 /* local variables moved into u.bp */ |
| 68097 | BtCursor *pCrsr; |
| 68098 | VdbeCursor *pC; |
| 68099 | i64 rowid; |
| 68100 | #endif /* local variables moved into u.bp */ |
| 68101 | |
| 68102 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68103 | u.bp.pC = p->apCsr[pOp->p1]; |
| 68104 | assert( u.bp.pC!=0 ); |
| 68105 | u.bp.pCrsr = u.bp.pC->pCursor; |
| 68106 | pOut->flags = MEM_Null; |
| 68107 | if( ALWAYS(u.bp.pCrsr!=0) ){ |
| 68108 | rc = sqlite3VdbeCursorMoveto(u.bp.pC); |
| 68109 | if( NEVER(rc) ) goto abort_due_to_error; |
| 68110 | assert( u.bp.pC->deferredMoveto==0 ); |
| 68111 | assert( u.bp.pC->isTable==0 ); |
| 68112 | if( !u.bp.pC->nullRow ){ |
| 68113 | rc = sqlite3VdbeIdxRowid(db, u.bp.pCrsr, &u.bp.rowid); |
| 68114 | if( rc!=SQLITE_OK ){ |
| 68115 | goto abort_due_to_error; |
| 68116 | } |
| 68117 | pOut->u.i = u.bp.rowid; |
| 68118 | pOut->flags = MEM_Int; |
| 68119 | } |
| 68120 | } |
| 68121 | break; |
| 68122 | } |
| @@ -68147,43 +68183,43 @@ | |
| 68147 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 68148 | ** to the comparison. This makes the opcode work like IdxLE. |
| 68149 | */ |
| 68150 | case OP_IdxLT: /* jump */ |
| 68151 | case OP_IdxGE: { /* jump */ |
| 68152 | #if 0 /* local variables moved into u.bq */ |
| 68153 | VdbeCursor *pC; |
| 68154 | int res; |
| 68155 | UnpackedRecord r; |
| 68156 | #endif /* local variables moved into u.bq */ |
| 68157 | |
| 68158 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68159 | u.bq.pC = p->apCsr[pOp->p1]; |
| 68160 | assert( u.bq.pC!=0 ); |
| 68161 | assert( u.bq.pC->isOrdered ); |
| 68162 | if( ALWAYS(u.bq.pC->pCursor!=0) ){ |
| 68163 | assert( u.bq.pC->deferredMoveto==0 ); |
| 68164 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 68165 | assert( pOp->p4type==P4_INT32 ); |
| 68166 | u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo; |
| 68167 | u.bq.r.nField = (u16)pOp->p4.i; |
| 68168 | if( pOp->p5 ){ |
| 68169 | u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
| 68170 | }else{ |
| 68171 | u.bq.r.flags = UNPACKED_IGNORE_ROWID; |
| 68172 | } |
| 68173 | u.bq.r.aMem = &aMem[pOp->p3]; |
| 68174 | #ifdef SQLITE_DEBUG |
| 68175 | { int i; for(i=0; i<u.bq.r.nField; i++) assert( memIsValid(&u.bq.r.aMem[i]) ); } |
| 68176 | #endif |
| 68177 | rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res); |
| 68178 | if( pOp->opcode==OP_IdxLT ){ |
| 68179 | u.bq.res = -u.bq.res; |
| 68180 | }else{ |
| 68181 | assert( pOp->opcode==OP_IdxGE ); |
| 68182 | u.bq.res++; |
| 68183 | } |
| 68184 | if( u.bq.res>0 ){ |
| 68185 | pc = pOp->p2 - 1 ; |
| 68186 | } |
| 68187 | } |
| 68188 | break; |
| 68189 | } |
| @@ -68207,43 +68243,43 @@ | |
| 68207 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 68208 | ** |
| 68209 | ** See also: Clear |
| 68210 | */ |
| 68211 | case OP_Destroy: { /* out2-prerelease */ |
| 68212 | #if 0 /* local variables moved into u.br */ |
| 68213 | int iMoved; |
| 68214 | int iCnt; |
| 68215 | Vdbe *pVdbe; |
| 68216 | int iDb; |
| 68217 | #endif /* local variables moved into u.br */ |
| 68218 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 68219 | u.br.iCnt = 0; |
| 68220 | for(u.br.pVdbe=db->pVdbe; u.br.pVdbe; u.br.pVdbe = u.br.pVdbe->pNext){ |
| 68221 | if( u.br.pVdbe->magic==VDBE_MAGIC_RUN && u.br.pVdbe->inVtabMethod<2 && u.br.pVdbe->pc>=0 ){ |
| 68222 | u.br.iCnt++; |
| 68223 | } |
| 68224 | } |
| 68225 | #else |
| 68226 | u.br.iCnt = db->activeVdbeCnt; |
| 68227 | #endif |
| 68228 | pOut->flags = MEM_Null; |
| 68229 | if( u.br.iCnt>1 ){ |
| 68230 | rc = SQLITE_LOCKED; |
| 68231 | p->errorAction = OE_Abort; |
| 68232 | }else{ |
| 68233 | u.br.iDb = pOp->p3; |
| 68234 | assert( u.br.iCnt==1 ); |
| 68235 | assert( (p->btreeMask & (((yDbMask)1)<<u.br.iDb))!=0 ); |
| 68236 | rc = sqlite3BtreeDropTable(db->aDb[u.br.iDb].pBt, pOp->p1, &u.br.iMoved); |
| 68237 | pOut->flags = MEM_Int; |
| 68238 | pOut->u.i = u.br.iMoved; |
| 68239 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 68240 | if( rc==SQLITE_OK && u.br.iMoved!=0 ){ |
| 68241 | sqlite3RootPageMoved(db, u.br.iDb, u.br.iMoved, pOp->p1); |
| 68242 | /* All OP_Destroy operations occur on the same btree */ |
| 68243 | assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.br.iDb+1 ); |
| 68244 | resetSchemaOnFault = u.br.iDb+1; |
| 68245 | } |
| 68246 | #endif |
| 68247 | } |
| 68248 | break; |
| 68249 | } |
| @@ -68265,25 +68301,25 @@ | |
| 68265 | ** also incremented by the number of rows in the table being cleared. |
| 68266 | ** |
| 68267 | ** See also: Destroy |
| 68268 | */ |
| 68269 | case OP_Clear: { |
| 68270 | #if 0 /* local variables moved into u.bs */ |
| 68271 | int nChange; |
| 68272 | #endif /* local variables moved into u.bs */ |
| 68273 | |
| 68274 | u.bs.nChange = 0; |
| 68275 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 68276 | rc = sqlite3BtreeClearTable( |
| 68277 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0) |
| 68278 | ); |
| 68279 | if( pOp->p3 ){ |
| 68280 | p->nChange += u.bs.nChange; |
| 68281 | if( pOp->p3>0 ){ |
| 68282 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 68283 | memAboutToChange(p, &aMem[pOp->p3]); |
| 68284 | aMem[pOp->p3].u.i += u.bs.nChange; |
| 68285 | } |
| 68286 | } |
| 68287 | break; |
| 68288 | } |
| 68289 | |
| @@ -68309,29 +68345,29 @@ | |
| 68309 | ** |
| 68310 | ** See documentation on OP_CreateTable for additional information. |
| 68311 | */ |
| 68312 | case OP_CreateIndex: /* out2-prerelease */ |
| 68313 | case OP_CreateTable: { /* out2-prerelease */ |
| 68314 | #if 0 /* local variables moved into u.bt */ |
| 68315 | int pgno; |
| 68316 | int flags; |
| 68317 | Db *pDb; |
| 68318 | #endif /* local variables moved into u.bt */ |
| 68319 | |
| 68320 | u.bt.pgno = 0; |
| 68321 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68322 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68323 | u.bt.pDb = &db->aDb[pOp->p1]; |
| 68324 | assert( u.bt.pDb->pBt!=0 ); |
| 68325 | if( pOp->opcode==OP_CreateTable ){ |
| 68326 | /* u.bt.flags = BTREE_INTKEY; */ |
| 68327 | u.bt.flags = BTREE_INTKEY; |
| 68328 | }else{ |
| 68329 | u.bt.flags = BTREE_BLOBKEY; |
| 68330 | } |
| 68331 | rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); |
| 68332 | pOut->u.i = u.bt.pgno; |
| 68333 | break; |
| 68334 | } |
| 68335 | |
| 68336 | /* Opcode: ParseSchema P1 * * P4 * |
| 68337 | ** |
| @@ -68340,48 +68376,48 @@ | |
| 68340 | ** |
| 68341 | ** This opcode invokes the parser to create a new virtual machine, |
| 68342 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 68343 | */ |
| 68344 | case OP_ParseSchema: { |
| 68345 | #if 0 /* local variables moved into u.bu */ |
| 68346 | int iDb; |
| 68347 | const char *zMaster; |
| 68348 | char *zSql; |
| 68349 | InitData initData; |
| 68350 | #endif /* local variables moved into u.bu */ |
| 68351 | |
| 68352 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 68353 | ** on every btree. This is a prerequisite for invoking |
| 68354 | ** sqlite3InitCallback(). |
| 68355 | */ |
| 68356 | #ifdef SQLITE_DEBUG |
| 68357 | for(u.bu.iDb=0; u.bu.iDb<db->nDb; u.bu.iDb++){ |
| 68358 | assert( u.bu.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) ); |
| 68359 | } |
| 68360 | #endif |
| 68361 | |
| 68362 | u.bu.iDb = pOp->p1; |
| 68363 | assert( u.bu.iDb>=0 && u.bu.iDb<db->nDb ); |
| 68364 | assert( DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ); |
| 68365 | /* Used to be a conditional */ { |
| 68366 | u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb); |
| 68367 | u.bu.initData.db = db; |
| 68368 | u.bu.initData.iDb = pOp->p1; |
| 68369 | u.bu.initData.pzErrMsg = &p->zErrMsg; |
| 68370 | u.bu.zSql = sqlite3MPrintf(db, |
| 68371 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| 68372 | db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z); |
| 68373 | if( u.bu.zSql==0 ){ |
| 68374 | rc = SQLITE_NOMEM; |
| 68375 | }else{ |
| 68376 | assert( db->init.busy==0 ); |
| 68377 | db->init.busy = 1; |
| 68378 | u.bu.initData.rc = SQLITE_OK; |
| 68379 | assert( !db->mallocFailed ); |
| 68380 | rc = sqlite3_exec(db, u.bu.zSql, sqlite3InitCallback, &u.bu.initData, 0); |
| 68381 | if( rc==SQLITE_OK ) rc = u.bu.initData.rc; |
| 68382 | sqlite3DbFree(db, u.bu.zSql); |
| 68383 | db->init.busy = 0; |
| 68384 | } |
| 68385 | } |
| 68386 | if( rc==SQLITE_NOMEM ){ |
| 68387 | goto no_mem; |
| @@ -68460,45 +68496,45 @@ | |
| 68460 | ** file, not the main database file. |
| 68461 | ** |
| 68462 | ** This opcode is used to implement the integrity_check pragma. |
| 68463 | */ |
| 68464 | case OP_IntegrityCk: { |
| 68465 | #if 0 /* local variables moved into u.bv */ |
| 68466 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 68467 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 68468 | int j; /* Loop counter */ |
| 68469 | int nErr; /* Number of errors reported */ |
| 68470 | char *z; /* Text of the error report */ |
| 68471 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 68472 | #endif /* local variables moved into u.bv */ |
| 68473 | |
| 68474 | u.bv.nRoot = pOp->p2; |
| 68475 | assert( u.bv.nRoot>0 ); |
| 68476 | u.bv.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bv.nRoot+1) ); |
| 68477 | if( u.bv.aRoot==0 ) goto no_mem; |
| 68478 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68479 | u.bv.pnErr = &aMem[pOp->p3]; |
| 68480 | assert( (u.bv.pnErr->flags & MEM_Int)!=0 ); |
| 68481 | assert( (u.bv.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 68482 | pIn1 = &aMem[pOp->p1]; |
| 68483 | for(u.bv.j=0; u.bv.j<u.bv.nRoot; u.bv.j++){ |
| 68484 | u.bv.aRoot[u.bv.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bv.j]); |
| 68485 | } |
| 68486 | u.bv.aRoot[u.bv.j] = 0; |
| 68487 | assert( pOp->p5<db->nDb ); |
| 68488 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 68489 | u.bv.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bv.aRoot, u.bv.nRoot, |
| 68490 | (int)u.bv.pnErr->u.i, &u.bv.nErr); |
| 68491 | sqlite3DbFree(db, u.bv.aRoot); |
| 68492 | u.bv.pnErr->u.i -= u.bv.nErr; |
| 68493 | sqlite3VdbeMemSetNull(pIn1); |
| 68494 | if( u.bv.nErr==0 ){ |
| 68495 | assert( u.bv.z==0 ); |
| 68496 | }else if( u.bv.z==0 ){ |
| 68497 | goto no_mem; |
| 68498 | }else{ |
| 68499 | sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68500 | } |
| 68501 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 68502 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 68503 | break; |
| 68504 | } |
| @@ -68528,24 +68564,24 @@ | |
| 68528 | ** Extract the smallest value from boolean index P1 and put that value into |
| 68529 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 68530 | ** unchanged and jump to instruction P2. |
| 68531 | */ |
| 68532 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 68533 | #if 0 /* local variables moved into u.bw */ |
| 68534 | i64 val; |
| 68535 | #endif /* local variables moved into u.bw */ |
| 68536 | CHECK_FOR_INTERRUPT; |
| 68537 | pIn1 = &aMem[pOp->p1]; |
| 68538 | if( (pIn1->flags & MEM_RowSet)==0 |
| 68539 | || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bw.val)==0 |
| 68540 | ){ |
| 68541 | /* The boolean index is empty */ |
| 68542 | sqlite3VdbeMemSetNull(pIn1); |
| 68543 | pc = pOp->p2 - 1; |
| 68544 | }else{ |
| 68545 | /* A value was pulled from the index */ |
| 68546 | sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bw.val); |
| 68547 | } |
| 68548 | break; |
| 68549 | } |
| 68550 | |
| 68551 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| @@ -68570,18 +68606,18 @@ | |
| 68570 | ** inserted, there is no need to search to see if the same value was |
| 68571 | ** previously inserted as part of set X (only if it was previously |
| 68572 | ** inserted as part of some other set). |
| 68573 | */ |
| 68574 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 68575 | #if 0 /* local variables moved into u.bx */ |
| 68576 | int iSet; |
| 68577 | int exists; |
| 68578 | #endif /* local variables moved into u.bx */ |
| 68579 | |
| 68580 | pIn1 = &aMem[pOp->p1]; |
| 68581 | pIn3 = &aMem[pOp->p3]; |
| 68582 | u.bx.iSet = pOp->p4.i; |
| 68583 | assert( pIn3->flags&MEM_Int ); |
| 68584 | |
| 68585 | /* If there is anything other than a rowset object in memory cell P1, |
| 68586 | ** delete it now and initialize P1 with an empty rowset |
| 68587 | */ |
| @@ -68589,21 +68625,21 @@ | |
| 68589 | sqlite3VdbeMemSetRowSet(pIn1); |
| 68590 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 68591 | } |
| 68592 | |
| 68593 | assert( pOp->p4type==P4_INT32 ); |
| 68594 | assert( u.bx.iSet==-1 || u.bx.iSet>=0 ); |
| 68595 | if( u.bx.iSet ){ |
| 68596 | u.bx.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 68597 | (u8)(u.bx.iSet>=0 ? u.bx.iSet & 0xf : 0xff), |
| 68598 | pIn3->u.i); |
| 68599 | if( u.bx.exists ){ |
| 68600 | pc = pOp->p2 - 1; |
| 68601 | break; |
| 68602 | } |
| 68603 | } |
| 68604 | if( u.bx.iSet>=0 ){ |
| 68605 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 68606 | } |
| 68607 | break; |
| 68608 | } |
| 68609 | |
| @@ -68622,25 +68658,25 @@ | |
| 68622 | ** memory required by the sub-vdbe at runtime. |
| 68623 | ** |
| 68624 | ** P4 is a pointer to the VM containing the trigger program. |
| 68625 | */ |
| 68626 | case OP_Program: { /* jump */ |
| 68627 | #if 0 /* local variables moved into u.by */ |
| 68628 | int nMem; /* Number of memory registers for sub-program */ |
| 68629 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 68630 | Mem *pRt; /* Register to allocate runtime space */ |
| 68631 | Mem *pMem; /* Used to iterate through memory cells */ |
| 68632 | Mem *pEnd; /* Last memory cell in new array */ |
| 68633 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 68634 | SubProgram *pProgram; /* Sub-program to execute */ |
| 68635 | void *t; /* Token identifying trigger */ |
| 68636 | #endif /* local variables moved into u.by */ |
| 68637 | |
| 68638 | u.by.pProgram = pOp->p4.pProgram; |
| 68639 | u.by.pRt = &aMem[pOp->p3]; |
| 68640 | assert( memIsValid(u.by.pRt) ); |
| 68641 | assert( u.by.pProgram->nOp>0 ); |
| 68642 | |
| 68643 | /* If the p5 flag is clear, then recursive invocation of triggers is |
| 68644 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 68645 | ** is really a trigger, not a foreign key action, and the flag set |
| 68646 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| @@ -68650,79 +68686,79 @@ | |
| 68650 | ** SubProgram (if the trigger may be executed with more than one different |
| 68651 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 68652 | ** single trigger all have the same value for the SubProgram.token |
| 68653 | ** variable. */ |
| 68654 | if( pOp->p5 ){ |
| 68655 | u.by.t = u.by.pProgram->token; |
| 68656 | for(u.by.pFrame=p->pFrame; u.by.pFrame && u.by.pFrame->token!=u.by.t; u.by.pFrame=u.by.pFrame->pParent); |
| 68657 | if( u.by.pFrame ) break; |
| 68658 | } |
| 68659 | |
| 68660 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 68661 | rc = SQLITE_ERROR; |
| 68662 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 68663 | break; |
| 68664 | } |
| 68665 | |
| 68666 | /* Register u.by.pRt is used to store the memory required to save the state |
| 68667 | ** of the current program, and the memory required at runtime to execute |
| 68668 | ** the trigger program. If this trigger has been fired before, then u.by.pRt |
| 68669 | ** is already allocated. Otherwise, it must be initialized. */ |
| 68670 | if( (u.by.pRt->flags&MEM_Frame)==0 ){ |
| 68671 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 68672 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 68673 | ** cell is required for each cursor used by the program. Set local |
| 68674 | ** variable u.by.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68675 | */ |
| 68676 | u.by.nMem = u.by.pProgram->nMem + u.by.pProgram->nCsr; |
| 68677 | u.by.nByte = ROUND8(sizeof(VdbeFrame)) |
| 68678 | + u.by.nMem * sizeof(Mem) |
| 68679 | + u.by.pProgram->nCsr * sizeof(VdbeCursor *); |
| 68680 | u.by.pFrame = sqlite3DbMallocZero(db, u.by.nByte); |
| 68681 | if( !u.by.pFrame ){ |
| 68682 | goto no_mem; |
| 68683 | } |
| 68684 | sqlite3VdbeMemRelease(u.by.pRt); |
| 68685 | u.by.pRt->flags = MEM_Frame; |
| 68686 | u.by.pRt->u.pFrame = u.by.pFrame; |
| 68687 | |
| 68688 | u.by.pFrame->v = p; |
| 68689 | u.by.pFrame->nChildMem = u.by.nMem; |
| 68690 | u.by.pFrame->nChildCsr = u.by.pProgram->nCsr; |
| 68691 | u.by.pFrame->pc = pc; |
| 68692 | u.by.pFrame->aMem = p->aMem; |
| 68693 | u.by.pFrame->nMem = p->nMem; |
| 68694 | u.by.pFrame->apCsr = p->apCsr; |
| 68695 | u.by.pFrame->nCursor = p->nCursor; |
| 68696 | u.by.pFrame->aOp = p->aOp; |
| 68697 | u.by.pFrame->nOp = p->nOp; |
| 68698 | u.by.pFrame->token = u.by.pProgram->token; |
| 68699 | |
| 68700 | u.by.pEnd = &VdbeFrameMem(u.by.pFrame)[u.by.pFrame->nChildMem]; |
| 68701 | for(u.by.pMem=VdbeFrameMem(u.by.pFrame); u.by.pMem!=u.by.pEnd; u.by.pMem++){ |
| 68702 | u.by.pMem->flags = MEM_Null; |
| 68703 | u.by.pMem->db = db; |
| 68704 | } |
| 68705 | }else{ |
| 68706 | u.by.pFrame = u.by.pRt->u.pFrame; |
| 68707 | assert( u.by.pProgram->nMem+u.by.pProgram->nCsr==u.by.pFrame->nChildMem ); |
| 68708 | assert( u.by.pProgram->nCsr==u.by.pFrame->nChildCsr ); |
| 68709 | assert( pc==u.by.pFrame->pc ); |
| 68710 | } |
| 68711 | |
| 68712 | p->nFrame++; |
| 68713 | u.by.pFrame->pParent = p->pFrame; |
| 68714 | u.by.pFrame->lastRowid = lastRowid; |
| 68715 | u.by.pFrame->nChange = p->nChange; |
| 68716 | p->nChange = 0; |
| 68717 | p->pFrame = u.by.pFrame; |
| 68718 | p->aMem = aMem = &VdbeFrameMem(u.by.pFrame)[-1]; |
| 68719 | p->nMem = u.by.pFrame->nChildMem; |
| 68720 | p->nCursor = (u16)u.by.pFrame->nChildCsr; |
| 68721 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 68722 | p->aOp = aOp = u.by.pProgram->aOp; |
| 68723 | p->nOp = u.by.pProgram->nOp; |
| 68724 | pc = -1; |
| 68725 | |
| 68726 | break; |
| 68727 | } |
| 68728 | |
| @@ -68737,17 +68773,17 @@ | |
| 68737 | ** The address of the cell in the parent frame is determined by adding |
| 68738 | ** the value of the P1 argument to the value of the P1 argument to the |
| 68739 | ** calling OP_Program instruction. |
| 68740 | */ |
| 68741 | case OP_Param: { /* out2-prerelease */ |
| 68742 | #if 0 /* local variables moved into u.bz */ |
| 68743 | VdbeFrame *pFrame; |
| 68744 | Mem *pIn; |
| 68745 | #endif /* local variables moved into u.bz */ |
| 68746 | u.bz.pFrame = p->pFrame; |
| 68747 | u.bz.pIn = &u.bz.pFrame->aMem[pOp->p1 + u.bz.pFrame->aOp[u.bz.pFrame->pc].p1]; |
| 68748 | sqlite3VdbeMemShallowCopy(pOut, u.bz.pIn, MEM_Ephem); |
| 68749 | break; |
| 68750 | } |
| 68751 | |
| 68752 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 68753 | |
| @@ -68799,26 +68835,26 @@ | |
| 68799 | ** |
| 68800 | ** This instruction throws an error if the memory cell is not initially |
| 68801 | ** an integer. |
| 68802 | */ |
| 68803 | case OP_MemMax: { /* in2 */ |
| 68804 | #if 0 /* local variables moved into u.ca */ |
| 68805 | Mem *pIn1; |
| 68806 | VdbeFrame *pFrame; |
| 68807 | #endif /* local variables moved into u.ca */ |
| 68808 | if( p->pFrame ){ |
| 68809 | for(u.ca.pFrame=p->pFrame; u.ca.pFrame->pParent; u.ca.pFrame=u.ca.pFrame->pParent); |
| 68810 | u.ca.pIn1 = &u.ca.pFrame->aMem[pOp->p1]; |
| 68811 | }else{ |
| 68812 | u.ca.pIn1 = &aMem[pOp->p1]; |
| 68813 | } |
| 68814 | assert( memIsValid(u.ca.pIn1) ); |
| 68815 | sqlite3VdbeMemIntegerify(u.ca.pIn1); |
| 68816 | pIn2 = &aMem[pOp->p2]; |
| 68817 | sqlite3VdbeMemIntegerify(pIn2); |
| 68818 | if( u.ca.pIn1->u.i<pIn2->u.i){ |
| 68819 | u.ca.pIn1->u.i = pIn2->u.i; |
| 68820 | } |
| 68821 | break; |
| 68822 | } |
| 68823 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 68824 | |
| @@ -68881,54 +68917,54 @@ | |
| 68881 | ** |
| 68882 | ** The P5 arguments are taken from register P2 and its |
| 68883 | ** successors. |
| 68884 | */ |
| 68885 | case OP_AggStep: { |
| 68886 | #if 0 /* local variables moved into u.cb */ |
| 68887 | int n; |
| 68888 | int i; |
| 68889 | Mem *pMem; |
| 68890 | Mem *pRec; |
| 68891 | sqlite3_context ctx; |
| 68892 | sqlite3_value **apVal; |
| 68893 | #endif /* local variables moved into u.cb */ |
| 68894 | |
| 68895 | u.cb.n = pOp->p5; |
| 68896 | assert( u.cb.n>=0 ); |
| 68897 | u.cb.pRec = &aMem[pOp->p2]; |
| 68898 | u.cb.apVal = p->apArg; |
| 68899 | assert( u.cb.apVal || u.cb.n==0 ); |
| 68900 | for(u.cb.i=0; u.cb.i<u.cb.n; u.cb.i++, u.cb.pRec++){ |
| 68901 | assert( memIsValid(u.cb.pRec) ); |
| 68902 | u.cb.apVal[u.cb.i] = u.cb.pRec; |
| 68903 | memAboutToChange(p, u.cb.pRec); |
| 68904 | sqlite3VdbeMemStoreType(u.cb.pRec); |
| 68905 | } |
| 68906 | u.cb.ctx.pFunc = pOp->p4.pFunc; |
| 68907 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68908 | u.cb.ctx.pMem = u.cb.pMem = &aMem[pOp->p3]; |
| 68909 | u.cb.pMem->n++; |
| 68910 | u.cb.ctx.s.flags = MEM_Null; |
| 68911 | u.cb.ctx.s.z = 0; |
| 68912 | u.cb.ctx.s.zMalloc = 0; |
| 68913 | u.cb.ctx.s.xDel = 0; |
| 68914 | u.cb.ctx.s.db = db; |
| 68915 | u.cb.ctx.isError = 0; |
| 68916 | u.cb.ctx.pColl = 0; |
| 68917 | if( u.cb.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 68918 | assert( pOp>p->aOp ); |
| 68919 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 68920 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 68921 | u.cb.ctx.pColl = pOp[-1].p4.pColl; |
| 68922 | } |
| 68923 | (u.cb.ctx.pFunc->xStep)(&u.cb.ctx, u.cb.n, u.cb.apVal); /* IMP: R-24505-23230 */ |
| 68924 | if( u.cb.ctx.isError ){ |
| 68925 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cb.ctx.s)); |
| 68926 | rc = u.cb.ctx.isError; |
| 68927 | } |
| 68928 | |
| 68929 | sqlite3VdbeMemRelease(&u.cb.ctx.s); |
| 68930 | |
| 68931 | break; |
| 68932 | } |
| 68933 | |
| 68934 | /* Opcode: AggFinal P1 P2 * P4 * |
| @@ -68942,23 +68978,23 @@ | |
| 68942 | ** functions that can take varying numbers of arguments. The |
| 68943 | ** P4 argument is only needed for the degenerate case where |
| 68944 | ** the step function was not previously called. |
| 68945 | */ |
| 68946 | case OP_AggFinal: { |
| 68947 | #if 0 /* local variables moved into u.cc */ |
| 68948 | Mem *pMem; |
| 68949 | #endif /* local variables moved into u.cc */ |
| 68950 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 68951 | u.cc.pMem = &aMem[pOp->p1]; |
| 68952 | assert( (u.cc.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 68953 | rc = sqlite3VdbeMemFinalize(u.cc.pMem, pOp->p4.pFunc); |
| 68954 | if( rc ){ |
| 68955 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cc.pMem)); |
| 68956 | } |
| 68957 | sqlite3VdbeChangeEncoding(u.cc.pMem, encoding); |
| 68958 | UPDATE_MAX_BLOBSIZE(u.cc.pMem); |
| 68959 | if( sqlite3VdbeMemTooBig(u.cc.pMem) ){ |
| 68960 | goto too_big; |
| 68961 | } |
| 68962 | break; |
| 68963 | } |
| 68964 | |
| @@ -68973,29 +69009,29 @@ | |
| 68973 | ** in the WAL that have been checkpointed after the checkpoint |
| 68974 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 68975 | ** mem[P3+2] are initialized to -1. |
| 68976 | */ |
| 68977 | case OP_Checkpoint: { |
| 68978 | #if 0 /* local variables moved into u.cd */ |
| 68979 | int i; /* Loop counter */ |
| 68980 | int aRes[3]; /* Results */ |
| 68981 | Mem *pMem; /* Write results here */ |
| 68982 | #endif /* local variables moved into u.cd */ |
| 68983 | |
| 68984 | u.cd.aRes[0] = 0; |
| 68985 | u.cd.aRes[1] = u.cd.aRes[2] = -1; |
| 68986 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 68987 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 68988 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 68989 | ); |
| 68990 | rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cd.aRes[1], &u.cd.aRes[2]); |
| 68991 | if( rc==SQLITE_BUSY ){ |
| 68992 | rc = SQLITE_OK; |
| 68993 | u.cd.aRes[0] = 1; |
| 68994 | } |
| 68995 | for(u.cd.i=0, u.cd.pMem = &aMem[pOp->p3]; u.cd.i<3; u.cd.i++, u.cd.pMem++){ |
| 68996 | sqlite3VdbeMemSetInt64(u.cd.pMem, (i64)u.cd.aRes[u.cd.i]); |
| 68997 | } |
| 68998 | break; |
| 68999 | }; |
| 69000 | #endif |
| 69001 | |
| @@ -69010,95 +69046,95 @@ | |
| 69010 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 69011 | ** |
| 69012 | ** Write a string containing the final journal-mode to register P2. |
| 69013 | */ |
| 69014 | case OP_JournalMode: { /* out2-prerelease */ |
| 69015 | #if 0 /* local variables moved into u.ce */ |
| 69016 | Btree *pBt; /* Btree to change journal mode of */ |
| 69017 | Pager *pPager; /* Pager associated with pBt */ |
| 69018 | int eNew; /* New journal mode */ |
| 69019 | int eOld; /* The old journal mode */ |
| 69020 | const char *zFilename; /* Name of database file for pPager */ |
| 69021 | #endif /* local variables moved into u.ce */ |
| 69022 | |
| 69023 | u.ce.eNew = pOp->p3; |
| 69024 | assert( u.ce.eNew==PAGER_JOURNALMODE_DELETE |
| 69025 | || u.ce.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 69026 | || u.ce.eNew==PAGER_JOURNALMODE_PERSIST |
| 69027 | || u.ce.eNew==PAGER_JOURNALMODE_OFF |
| 69028 | || u.ce.eNew==PAGER_JOURNALMODE_MEMORY |
| 69029 | || u.ce.eNew==PAGER_JOURNALMODE_WAL |
| 69030 | || u.ce.eNew==PAGER_JOURNALMODE_QUERY |
| 69031 | ); |
| 69032 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69033 | |
| 69034 | u.ce.pBt = db->aDb[pOp->p1].pBt; |
| 69035 | u.ce.pPager = sqlite3BtreePager(u.ce.pBt); |
| 69036 | u.ce.eOld = sqlite3PagerGetJournalMode(u.ce.pPager); |
| 69037 | if( u.ce.eNew==PAGER_JOURNALMODE_QUERY ) u.ce.eNew = u.ce.eOld; |
| 69038 | if( !sqlite3PagerOkToChangeJournalMode(u.ce.pPager) ) u.ce.eNew = u.ce.eOld; |
| 69039 | |
| 69040 | #ifndef SQLITE_OMIT_WAL |
| 69041 | u.ce.zFilename = sqlite3PagerFilename(u.ce.pPager); |
| 69042 | |
| 69043 | /* Do not allow a transition to journal_mode=WAL for a database |
| 69044 | ** in temporary storage or if the VFS does not support shared memory |
| 69045 | */ |
| 69046 | if( u.ce.eNew==PAGER_JOURNALMODE_WAL |
| 69047 | && (u.ce.zFilename[0]==0 /* Temp file */ |
| 69048 | || !sqlite3PagerWalSupported(u.ce.pPager)) /* No shared-memory support */ |
| 69049 | ){ |
| 69050 | u.ce.eNew = u.ce.eOld; |
| 69051 | } |
| 69052 | |
| 69053 | if( (u.ce.eNew!=u.ce.eOld) |
| 69054 | && (u.ce.eOld==PAGER_JOURNALMODE_WAL || u.ce.eNew==PAGER_JOURNALMODE_WAL) |
| 69055 | ){ |
| 69056 | if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 69057 | rc = SQLITE_ERROR; |
| 69058 | sqlite3SetString(&p->zErrMsg, db, |
| 69059 | "cannot change %s wal mode from within a transaction", |
| 69060 | (u.ce.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69061 | ); |
| 69062 | break; |
| 69063 | }else{ |
| 69064 | |
| 69065 | if( u.ce.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69066 | /* If leaving WAL mode, close the log file. If successful, the call |
| 69067 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 69068 | ** file. An EXCLUSIVE lock may still be held on the database file |
| 69069 | ** after a successful return. |
| 69070 | */ |
| 69071 | rc = sqlite3PagerCloseWal(u.ce.pPager); |
| 69072 | if( rc==SQLITE_OK ){ |
| 69073 | sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); |
| 69074 | } |
| 69075 | }else if( u.ce.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69076 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 69077 | ** as an intermediate */ |
| 69078 | sqlite3PagerSetJournalMode(u.ce.pPager, PAGER_JOURNALMODE_OFF); |
| 69079 | } |
| 69080 | |
| 69081 | /* Open a transaction on the database file. Regardless of the journal |
| 69082 | ** mode, this transaction always uses a rollback journal. |
| 69083 | */ |
| 69084 | assert( sqlite3BtreeIsInTrans(u.ce.pBt)==0 ); |
| 69085 | if( rc==SQLITE_OK ){ |
| 69086 | rc = sqlite3BtreeSetVersion(u.ce.pBt, (u.ce.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69087 | } |
| 69088 | } |
| 69089 | } |
| 69090 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 69091 | |
| 69092 | if( rc ){ |
| 69093 | u.ce.eNew = u.ce.eOld; |
| 69094 | } |
| 69095 | u.ce.eNew = sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); |
| 69096 | |
| 69097 | pOut = &aMem[pOp->p2]; |
| 69098 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 69099 | pOut->z = (char *)sqlite3JournalModename(u.ce.eNew); |
| 69100 | pOut->n = sqlite3Strlen30(pOut->z); |
| 69101 | pOut->enc = SQLITE_UTF8; |
| 69102 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 69103 | break; |
| 69104 | }; |
| @@ -69123,18 +69159,18 @@ | |
| 69123 | ** Perform a single step of the incremental vacuum procedure on |
| 69124 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 69125 | ** P2. Otherwise, fall through to the next instruction. |
| 69126 | */ |
| 69127 | case OP_IncrVacuum: { /* jump */ |
| 69128 | #if 0 /* local variables moved into u.cf */ |
| 69129 | Btree *pBt; |
| 69130 | #endif /* local variables moved into u.cf */ |
| 69131 | |
| 69132 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69133 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69134 | u.cf.pBt = db->aDb[pOp->p1].pBt; |
| 69135 | rc = sqlite3BtreeIncrVacuum(u.cf.pBt); |
| 69136 | if( rc==SQLITE_DONE ){ |
| 69137 | pc = pOp->p2 - 1; |
| 69138 | rc = SQLITE_OK; |
| 69139 | } |
| 69140 | break; |
| @@ -69200,16 +69236,16 @@ | |
| 69200 | ** Also, whether or not P4 is set, check that this is not being called from |
| 69201 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 69202 | ** code will be set to SQLITE_LOCKED. |
| 69203 | */ |
| 69204 | case OP_VBegin: { |
| 69205 | #if 0 /* local variables moved into u.cg */ |
| 69206 | VTable *pVTab; |
| 69207 | #endif /* local variables moved into u.cg */ |
| 69208 | u.cg.pVTab = pOp->p4.pVtab; |
| 69209 | rc = sqlite3VtabBegin(db, u.cg.pVTab); |
| 69210 | if( u.cg.pVTab ) importVtabErrMsg(p, u.cg.pVTab->pVtab); |
| 69211 | break; |
| 69212 | } |
| 69213 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69214 | |
| 69215 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| @@ -69244,36 +69280,36 @@ | |
| 69244 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69245 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 69246 | ** table and stores that cursor in P1. |
| 69247 | */ |
| 69248 | case OP_VOpen: { |
| 69249 | #if 0 /* local variables moved into u.ch */ |
| 69250 | VdbeCursor *pCur; |
| 69251 | sqlite3_vtab_cursor *pVtabCursor; |
| 69252 | sqlite3_vtab *pVtab; |
| 69253 | sqlite3_module *pModule; |
| 69254 | #endif /* local variables moved into u.ch */ |
| 69255 | |
| 69256 | u.ch.pCur = 0; |
| 69257 | u.ch.pVtabCursor = 0; |
| 69258 | u.ch.pVtab = pOp->p4.pVtab->pVtab; |
| 69259 | u.ch.pModule = (sqlite3_module *)u.ch.pVtab->pModule; |
| 69260 | assert(u.ch.pVtab && u.ch.pModule); |
| 69261 | rc = u.ch.pModule->xOpen(u.ch.pVtab, &u.ch.pVtabCursor); |
| 69262 | importVtabErrMsg(p, u.ch.pVtab); |
| 69263 | if( SQLITE_OK==rc ){ |
| 69264 | /* Initialize sqlite3_vtab_cursor base class */ |
| 69265 | u.ch.pVtabCursor->pVtab = u.ch.pVtab; |
| 69266 | |
| 69267 | /* Initialise vdbe cursor object */ |
| 69268 | u.ch.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 69269 | if( u.ch.pCur ){ |
| 69270 | u.ch.pCur->pVtabCursor = u.ch.pVtabCursor; |
| 69271 | u.ch.pCur->pModule = u.ch.pVtabCursor->pVtab->pModule; |
| 69272 | }else{ |
| 69273 | db->mallocFailed = 1; |
| 69274 | u.ch.pModule->xClose(u.ch.pVtabCursor); |
| 69275 | } |
| 69276 | } |
| 69277 | break; |
| 69278 | } |
| 69279 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69296,11 +69332,11 @@ | |
| 69296 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 69297 | ** |
| 69298 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 69299 | */ |
| 69300 | case OP_VFilter: { /* jump */ |
| 69301 | #if 0 /* local variables moved into u.ci */ |
| 69302 | int nArg; |
| 69303 | int iQuery; |
| 69304 | const sqlite3_module *pModule; |
| 69305 | Mem *pQuery; |
| 69306 | Mem *pArgc; |
| @@ -69308,49 +69344,49 @@ | |
| 69308 | sqlite3_vtab *pVtab; |
| 69309 | VdbeCursor *pCur; |
| 69310 | int res; |
| 69311 | int i; |
| 69312 | Mem **apArg; |
| 69313 | #endif /* local variables moved into u.ci */ |
| 69314 | |
| 69315 | u.ci.pQuery = &aMem[pOp->p3]; |
| 69316 | u.ci.pArgc = &u.ci.pQuery[1]; |
| 69317 | u.ci.pCur = p->apCsr[pOp->p1]; |
| 69318 | assert( memIsValid(u.ci.pQuery) ); |
| 69319 | REGISTER_TRACE(pOp->p3, u.ci.pQuery); |
| 69320 | assert( u.ci.pCur->pVtabCursor ); |
| 69321 | u.ci.pVtabCursor = u.ci.pCur->pVtabCursor; |
| 69322 | u.ci.pVtab = u.ci.pVtabCursor->pVtab; |
| 69323 | u.ci.pModule = u.ci.pVtab->pModule; |
| 69324 | |
| 69325 | /* Grab the index number and argc parameters */ |
| 69326 | assert( (u.ci.pQuery->flags&MEM_Int)!=0 && u.ci.pArgc->flags==MEM_Int ); |
| 69327 | u.ci.nArg = (int)u.ci.pArgc->u.i; |
| 69328 | u.ci.iQuery = (int)u.ci.pQuery->u.i; |
| 69329 | |
| 69330 | /* Invoke the xFilter method */ |
| 69331 | { |
| 69332 | u.ci.res = 0; |
| 69333 | u.ci.apArg = p->apArg; |
| 69334 | for(u.ci.i = 0; u.ci.i<u.ci.nArg; u.ci.i++){ |
| 69335 | u.ci.apArg[u.ci.i] = &u.ci.pArgc[u.ci.i+1]; |
| 69336 | sqlite3VdbeMemStoreType(u.ci.apArg[u.ci.i]); |
| 69337 | } |
| 69338 | |
| 69339 | p->inVtabMethod = 1; |
| 69340 | rc = u.ci.pModule->xFilter(u.ci.pVtabCursor, u.ci.iQuery, pOp->p4.z, u.ci.nArg, u.ci.apArg); |
| 69341 | p->inVtabMethod = 0; |
| 69342 | importVtabErrMsg(p, u.ci.pVtab); |
| 69343 | if( rc==SQLITE_OK ){ |
| 69344 | u.ci.res = u.ci.pModule->xEof(u.ci.pVtabCursor); |
| 69345 | } |
| 69346 | |
| 69347 | if( u.ci.res ){ |
| 69348 | pc = pOp->p2 - 1; |
| 69349 | } |
| 69350 | } |
| 69351 | u.ci.pCur->nullRow = 0; |
| 69352 | |
| 69353 | break; |
| 69354 | } |
| 69355 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69356 | |
| @@ -69360,55 +69396,55 @@ | |
| 69360 | ** Store the value of the P2-th column of |
| 69361 | ** the row of the virtual-table that the |
| 69362 | ** P1 cursor is pointing to into register P3. |
| 69363 | */ |
| 69364 | case OP_VColumn: { |
| 69365 | #if 0 /* local variables moved into u.cj */ |
| 69366 | sqlite3_vtab *pVtab; |
| 69367 | const sqlite3_module *pModule; |
| 69368 | Mem *pDest; |
| 69369 | sqlite3_context sContext; |
| 69370 | #endif /* local variables moved into u.cj */ |
| 69371 | |
| 69372 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 69373 | assert( pCur->pVtabCursor ); |
| 69374 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69375 | u.cj.pDest = &aMem[pOp->p3]; |
| 69376 | memAboutToChange(p, u.cj.pDest); |
| 69377 | if( pCur->nullRow ){ |
| 69378 | sqlite3VdbeMemSetNull(u.cj.pDest); |
| 69379 | break; |
| 69380 | } |
| 69381 | u.cj.pVtab = pCur->pVtabCursor->pVtab; |
| 69382 | u.cj.pModule = u.cj.pVtab->pModule; |
| 69383 | assert( u.cj.pModule->xColumn ); |
| 69384 | memset(&u.cj.sContext, 0, sizeof(u.cj.sContext)); |
| 69385 | |
| 69386 | /* The output cell may already have a buffer allocated. Move |
| 69387 | ** the current contents to u.cj.sContext.s so in case the user-function |
| 69388 | ** can use the already allocated buffer instead of allocating a |
| 69389 | ** new one. |
| 69390 | */ |
| 69391 | sqlite3VdbeMemMove(&u.cj.sContext.s, u.cj.pDest); |
| 69392 | MemSetTypeFlag(&u.cj.sContext.s, MEM_Null); |
| 69393 | |
| 69394 | rc = u.cj.pModule->xColumn(pCur->pVtabCursor, &u.cj.sContext, pOp->p2); |
| 69395 | importVtabErrMsg(p, u.cj.pVtab); |
| 69396 | if( u.cj.sContext.isError ){ |
| 69397 | rc = u.cj.sContext.isError; |
| 69398 | } |
| 69399 | |
| 69400 | /* Copy the result of the function to the P3 register. We |
| 69401 | ** do this regardless of whether or not an error occurred to ensure any |
| 69402 | ** dynamic allocation in u.cj.sContext.s (a Mem struct) is released. |
| 69403 | */ |
| 69404 | sqlite3VdbeChangeEncoding(&u.cj.sContext.s, encoding); |
| 69405 | sqlite3VdbeMemMove(u.cj.pDest, &u.cj.sContext.s); |
| 69406 | REGISTER_TRACE(pOp->p3, u.cj.pDest); |
| 69407 | UPDATE_MAX_BLOBSIZE(u.cj.pDest); |
| 69408 | |
| 69409 | if( sqlite3VdbeMemTooBig(u.cj.pDest) ){ |
| 69410 | goto too_big; |
| 69411 | } |
| 69412 | break; |
| 69413 | } |
| 69414 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69419,42 +69455,42 @@ | |
| 69419 | ** Advance virtual table P1 to the next row in its result set and |
| 69420 | ** jump to instruction P2. Or, if the virtual table has reached |
| 69421 | ** the end of its result set, then fall through to the next instruction. |
| 69422 | */ |
| 69423 | case OP_VNext: { /* jump */ |
| 69424 | #if 0 /* local variables moved into u.ck */ |
| 69425 | sqlite3_vtab *pVtab; |
| 69426 | const sqlite3_module *pModule; |
| 69427 | int res; |
| 69428 | VdbeCursor *pCur; |
| 69429 | #endif /* local variables moved into u.ck */ |
| 69430 | |
| 69431 | u.ck.res = 0; |
| 69432 | u.ck.pCur = p->apCsr[pOp->p1]; |
| 69433 | assert( u.ck.pCur->pVtabCursor ); |
| 69434 | if( u.ck.pCur->nullRow ){ |
| 69435 | break; |
| 69436 | } |
| 69437 | u.ck.pVtab = u.ck.pCur->pVtabCursor->pVtab; |
| 69438 | u.ck.pModule = u.ck.pVtab->pModule; |
| 69439 | assert( u.ck.pModule->xNext ); |
| 69440 | |
| 69441 | /* Invoke the xNext() method of the module. There is no way for the |
| 69442 | ** underlying implementation to return an error if one occurs during |
| 69443 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 69444 | ** data is available) and the error code returned when xColumn or |
| 69445 | ** some other method is next invoked on the save virtual table cursor. |
| 69446 | */ |
| 69447 | p->inVtabMethod = 1; |
| 69448 | rc = u.ck.pModule->xNext(u.ck.pCur->pVtabCursor); |
| 69449 | p->inVtabMethod = 0; |
| 69450 | importVtabErrMsg(p, u.ck.pVtab); |
| 69451 | if( rc==SQLITE_OK ){ |
| 69452 | u.ck.res = u.ck.pModule->xEof(u.ck.pCur->pVtabCursor); |
| 69453 | } |
| 69454 | |
| 69455 | if( !u.ck.res ){ |
| 69456 | /* If there is data, jump to P2 */ |
| 69457 | pc = pOp->p2 - 1; |
| 69458 | } |
| 69459 | break; |
| 69460 | } |
| @@ -69466,23 +69502,23 @@ | |
| 69466 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69467 | ** This opcode invokes the corresponding xRename method. The value |
| 69468 | ** in register P1 is passed as the zName argument to the xRename method. |
| 69469 | */ |
| 69470 | case OP_VRename: { |
| 69471 | #if 0 /* local variables moved into u.cl */ |
| 69472 | sqlite3_vtab *pVtab; |
| 69473 | Mem *pName; |
| 69474 | #endif /* local variables moved into u.cl */ |
| 69475 | |
| 69476 | u.cl.pVtab = pOp->p4.pVtab->pVtab; |
| 69477 | u.cl.pName = &aMem[pOp->p1]; |
| 69478 | assert( u.cl.pVtab->pModule->xRename ); |
| 69479 | assert( memIsValid(u.cl.pName) ); |
| 69480 | REGISTER_TRACE(pOp->p1, u.cl.pName); |
| 69481 | assert( u.cl.pName->flags & MEM_Str ); |
| 69482 | rc = u.cl.pVtab->pModule->xRename(u.cl.pVtab, u.cl.pName->z); |
| 69483 | importVtabErrMsg(p, u.cl.pVtab); |
| 69484 | p->expired = 0; |
| 69485 | |
| 69486 | break; |
| 69487 | } |
| 69488 | #endif |
| @@ -69510,45 +69546,45 @@ | |
| 69510 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 69511 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 69512 | ** is set to the value of the rowid for the row just inserted. |
| 69513 | */ |
| 69514 | case OP_VUpdate: { |
| 69515 | #if 0 /* local variables moved into u.cm */ |
| 69516 | sqlite3_vtab *pVtab; |
| 69517 | sqlite3_module *pModule; |
| 69518 | int nArg; |
| 69519 | int i; |
| 69520 | sqlite_int64 rowid; |
| 69521 | Mem **apArg; |
| 69522 | Mem *pX; |
| 69523 | #endif /* local variables moved into u.cm */ |
| 69524 | |
| 69525 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 69526 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 69527 | ); |
| 69528 | u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 69529 | u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 69530 | u.cm.nArg = pOp->p2; |
| 69531 | assert( pOp->p4type==P4_VTAB ); |
| 69532 | if( ALWAYS(u.cm.pModule->xUpdate) ){ |
| 69533 | u8 vtabOnConflict = db->vtabOnConflict; |
| 69534 | u.cm.apArg = p->apArg; |
| 69535 | u.cm.pX = &aMem[pOp->p3]; |
| 69536 | for(u.cm.i=0; u.cm.i<u.cm.nArg; u.cm.i++){ |
| 69537 | assert( memIsValid(u.cm.pX) ); |
| 69538 | memAboutToChange(p, u.cm.pX); |
| 69539 | sqlite3VdbeMemStoreType(u.cm.pX); |
| 69540 | u.cm.apArg[u.cm.i] = u.cm.pX; |
| 69541 | u.cm.pX++; |
| 69542 | } |
| 69543 | db->vtabOnConflict = pOp->p5; |
| 69544 | rc = u.cm.pModule->xUpdate(u.cm.pVtab, u.cm.nArg, u.cm.apArg, &u.cm.rowid); |
| 69545 | db->vtabOnConflict = vtabOnConflict; |
| 69546 | importVtabErrMsg(p, u.cm.pVtab); |
| 69547 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 69548 | assert( u.cm.nArg>1 && u.cm.apArg[0] && (u.cm.apArg[0]->flags&MEM_Null) ); |
| 69549 | db->lastRowid = lastRowid = u.cm.rowid; |
| 69550 | } |
| 69551 | if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 69552 | if( pOp->p5==OE_Ignore ){ |
| 69553 | rc = SQLITE_OK; |
| 69554 | }else{ |
| @@ -69604,25 +69640,25 @@ | |
| 69604 | ** |
| 69605 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 69606 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 69607 | */ |
| 69608 | case OP_Trace: { |
| 69609 | #if 0 /* local variables moved into u.cn */ |
| 69610 | char *zTrace; |
| 69611 | char *z; |
| 69612 | #endif /* local variables moved into u.cn */ |
| 69613 | |
| 69614 | if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ |
| 69615 | u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); |
| 69616 | db->xTrace(db->pTraceArg, u.cn.z); |
| 69617 | sqlite3DbFree(db, u.cn.z); |
| 69618 | } |
| 69619 | #ifdef SQLITE_DEBUG |
| 69620 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 69621 | && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69622 | ){ |
| 69623 | sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 69624 | } |
| 69625 | #endif /* SQLITE_DEBUG */ |
| 69626 | break; |
| 69627 | } |
| 69628 | #endif |
| @@ -70239,10 +70275,11 @@ | |
| 70239 | |
| 70240 | |
| 70241 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70242 | |
| 70243 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70244 | |
| 70245 | /* |
| 70246 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70247 | ** |
| 70248 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70310,19 +70347,23 @@ | |
| 70310 | ** In other words, each time we advance to the next sorter element, log2(N) |
| 70311 | ** key comparison operations are required, where N is the number of segments |
| 70312 | ** being merged (rounded up to the next power of 2). |
| 70313 | */ |
| 70314 | struct VdbeSorter { |
| 70315 | int nWorking; /* Start a new b-tree after this many pages */ |
| 70316 | int nBtree; /* Current size of b-tree contents as PMA */ |
| 70317 | int nTree; /* Used size of aTree/aIter (power of 2) */ |
| 70318 | VdbeSorterIter *aIter; /* Array of iterators to merge */ |
| 70319 | int *aTree; /* Current state of incremental merge */ |
| 70320 | i64 iWriteOff; /* Current write offset within file pTemp1 */ |
| 70321 | i64 iReadOff; /* Current read offset within file pTemp1 */ |
| 70322 | sqlite3_file *pTemp1; /* PMA file 1 */ |
| 70323 | int nPMA; /* Number of PMAs stored in pTemp1 */ |
| 70324 | }; |
| 70325 | |
| 70326 | /* |
| 70327 | ** The following type is an iterator for a PMA. It caches the current key in |
| 70328 | ** variables nKey/aKey. If the iterator is at EOF, pFile==0. |
| @@ -70334,10 +70375,21 @@ | |
| 70334 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70335 | u8 *aAlloc; /* Allocated space */ |
| 70336 | int nKey; /* Number of bytes in key */ |
| 70337 | u8 *aKey; /* Pointer to current key */ |
| 70338 | }; |
| 70339 | |
| 70340 | /* Minimum allowable value for the VdbeSorter.nWorking variable */ |
| 70341 | #define SORTER_MIN_WORKING 10 |
| 70342 | |
| 70343 | /* Maximum number of segments to merge in a single pass. */ |
| @@ -70360,12 +70412,12 @@ | |
| 70360 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70361 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70362 | ){ |
| 70363 | int rc; /* Return Code */ |
| 70364 | int nRead; /* Number of bytes read */ |
| 70365 | int nRec; /* Size of record in bytes */ |
| 70366 | int iOff; /* Size of serialized size varint in bytes */ |
| 70367 | |
| 70368 | nRead = pIter->iEof - pIter->iReadOff; |
| 70369 | if( nRead>5 ) nRead = 5; |
| 70370 | if( nRead<=0 ){ |
| 70371 | /* This is an EOF condition */ |
| @@ -70372,29 +70424,30 @@ | |
| 70372 | vdbeSorterIterZero(db, pIter); |
| 70373 | return SQLITE_OK; |
| 70374 | } |
| 70375 | |
| 70376 | rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); |
| 70377 | iOff = getVarint32(pIter->aAlloc, nRec); |
| 70378 | |
| 70379 | if( rc==SQLITE_OK && (iOff+nRec)>nRead ){ |
| 70380 | int nRead2; /* Number of extra bytes to read */ |
| 70381 | if( (iOff+nRec)>pIter->nAlloc ){ |
| 70382 | int nNew = pIter->nAlloc*2; |
| 70383 | while( (iOff+nRec)>nNew ) nNew = nNew*2; |
| 70384 | pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); |
| 70385 | if( !pIter->aAlloc ) return SQLITE_NOMEM; |
| 70386 | pIter->nAlloc = nNew; |
| 70387 | } |
| 70388 | |
| 70389 | nRead2 = iOff + nRec - nRead; |
| 70390 | rc = sqlite3OsRead( |
| 70391 | pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead |
| 70392 | ); |
| 70393 | } |
| 70394 | |
| 70395 | assert( nRec>0 || rc!=SQLITE_OK ); |
| 70396 | pIter->iReadOff += iOff+nRec; |
| 70397 | pIter->nKey = nRec; |
| 70398 | pIter->aKey = &pIter->aAlloc[iOff]; |
| 70399 | return rc; |
| 70400 | } |
| @@ -70434,25 +70487,18 @@ | |
| 70434 | ** set to the integer value read. If an error occurs, the final values of |
| 70435 | ** both *piOffset and *piVal are undefined. |
| 70436 | */ |
| 70437 | static int vdbeSorterReadVarint( |
| 70438 | sqlite3_file *pFile, /* File to read from */ |
| 70439 | i64 iEof, /* Total number of bytes in file */ |
| 70440 | i64 *piOffset, /* IN/OUT: Read offset in pFile */ |
| 70441 | i64 *piVal /* OUT: Value read from file */ |
| 70442 | ){ |
| 70443 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70444 | i64 iOff = *piOffset; /* Offset in file to read from */ |
| 70445 | int nRead = 9; /* Number of bytes to read from file */ |
| 70446 | int rc; /* Return code */ |
| 70447 | |
| 70448 | assert( iEof>iOff ); |
| 70449 | if( (iEof-iOff)<nRead ){ |
| 70450 | nRead = iEof-iOff; |
| 70451 | } |
| 70452 | |
| 70453 | rc = sqlite3OsRead(pFile, aVarint, nRead, iOff); |
| 70454 | if( rc==SQLITE_OK ){ |
| 70455 | *piOffset += getVarint(aVarint, (u64 *)piVal); |
| 70456 | } |
| 70457 | |
| 70458 | return rc; |
| @@ -70480,22 +70526,85 @@ | |
| 70480 | pIter->nAlloc = 128; |
| 70481 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70482 | if( !pIter->aAlloc ){ |
| 70483 | rc = SQLITE_NOMEM; |
| 70484 | }else{ |
| 70485 | i64 iEof = pSorter->iWriteOff; /* EOF of file pSorter->pTemp1 */ |
| 70486 | i64 nByte; /* Total size of PMA in bytes */ |
| 70487 | rc = vdbeSorterReadVarint(pSorter->pTemp1, iEof, &pIter->iReadOff, &nByte); |
| 70488 | *pnByte += nByte; |
| 70489 | pIter->iEof = pIter->iReadOff + nByte; |
| 70490 | } |
| 70491 | if( rc==SQLITE_OK ){ |
| 70492 | rc = vdbeSorterIterNext(db, pIter); |
| 70493 | } |
| 70494 | return rc; |
| 70495 | } |
| 70496 | |
| 70497 | /* |
| 70498 | ** This function is called to compare two iterator keys when merging |
| 70499 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70500 | ** value to recalculate. |
| 70501 | */ |
| @@ -70523,24 +70632,25 @@ | |
| 70523 | if( p1->pFile==0 ){ |
| 70524 | iRes = i2; |
| 70525 | }else if( p2->pFile==0 ){ |
| 70526 | iRes = i1; |
| 70527 | }else{ |
| 70528 | char aSpace[150]; |
| 70529 | UnpackedRecord *r1; |
| 70530 | |
| 70531 | r1 = sqlite3VdbeRecordUnpack( |
| 70532 | pCsr->pKeyInfo, p1->nKey, p1->aKey, aSpace, sizeof(aSpace) |
| 70533 | ); |
| 70534 | if( r1==0 ) return SQLITE_NOMEM; |
| 70535 | |
| 70536 | if( sqlite3VdbeRecordCompare(p2->nKey, p2->aKey, r1)>=0 ){ |
| 70537 | iRes = i1; |
| 70538 | }else{ |
| 70539 | iRes = i2; |
| 70540 | } |
| 70541 | sqlite3VdbeDeleteUnpackedRecord(r1); |
| 70542 | } |
| 70543 | |
| 70544 | pSorter->aTree[iOut] = iRes; |
| 70545 | return SQLITE_OK; |
| 70546 | } |
| @@ -70547,13 +70657,41 @@ | |
| 70547 | |
| 70548 | /* |
| 70549 | ** Initialize the temporary index cursor just opened as a sorter cursor. |
| 70550 | */ |
| 70551 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ |
| 70552 | assert( pCsr->pKeyInfo && pCsr->pBt ); |
| 70553 | pCsr->pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); |
| 70554 | return (pCsr->pSorter ? SQLITE_OK : SQLITE_NOMEM); |
| 70555 | } |
| 70556 | |
| 70557 | /* |
| 70558 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 70559 | */ |
| @@ -70568,10 +70706,12 @@ | |
| 70568 | sqlite3DbFree(db, pSorter->aIter); |
| 70569 | } |
| 70570 | if( pSorter->pTemp1 ){ |
| 70571 | sqlite3OsCloseFree(pSorter->pTemp1); |
| 70572 | } |
| 70573 | sqlite3DbFree(db, pSorter); |
| 70574 | pCsr->pSorter = 0; |
| 70575 | } |
| 70576 | } |
| 70577 | |
| @@ -70587,14 +70727,107 @@ | |
| 70587 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| 70588 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy |
| 70589 | ); |
| 70590 | } |
| 70591 | |
| 70592 | |
| 70593 | /* |
| 70594 | ** Write the current contents of the b-tree to a PMA. Return SQLITE_OK |
| 70595 | ** if successful, or an SQLite error code otherwise. |
| 70596 | ** |
| 70597 | ** The format of a PMA is: |
| 70598 | ** |
| 70599 | ** * A varint. This varint contains the total number of bytes of content |
| 70600 | ** in the PMA (not including the varint itself). |
| @@ -70601,153 +70834,111 @@ | |
| 70601 | ** |
| 70602 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70603 | ** Each record consists of a varint followed by a blob of data (the |
| 70604 | ** key). The varint is the number of bytes in the blob of data. |
| 70605 | */ |
| 70606 | static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){ |
| 70607 | int rc = SQLITE_OK; /* Return code */ |
| 70608 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70609 | int res = 0; |
| 70610 | |
| 70611 | /* sqlite3BtreeFirst() cannot fail because sorter btrees are always held |
| 70612 | ** in memory and so an I/O error is not possible. */ |
| 70613 | rc = sqlite3BtreeFirst(pCsr->pCursor, &res); |
| 70614 | if( NEVER(rc!=SQLITE_OK) || res ) return rc; |
| 70615 | assert( pSorter->nBtree>0 ); |
| 70616 | |
| 70617 | /* If the first temporary PMA file has not been opened, open it now. */ |
| 70618 | if( pSorter->pTemp1==0 ){ |
| 70619 | rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); |
| 70620 | assert( rc!=SQLITE_OK || pSorter->pTemp1 ); |
| 70621 | assert( pSorter->iWriteOff==0 ); |
| 70622 | assert( pSorter->nPMA==0 ); |
| 70623 | } |
| 70624 | |
| 70625 | if( rc==SQLITE_OK ){ |
| 70626 | i64 iWriteOff = pSorter->iWriteOff; |
| 70627 | void *aMalloc = 0; /* Array used to hold a single record */ |
| 70628 | int nMalloc = 0; /* Allocated size of aMalloc[] in bytes */ |
| 70629 | |
| 70630 | pSorter->nPMA++; |
| 70631 | for( |
| 70632 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nBtree, &iWriteOff); |
| 70633 | rc==SQLITE_OK && res==0; |
| 70634 | rc = sqlite3BtreeNext(pCsr->pCursor, &res) |
| 70635 | ){ |
| 70636 | i64 nKey; /* Size of this key in bytes */ |
| 70637 | |
| 70638 | /* Write the size of the record in bytes to the output file */ |
| 70639 | (void)sqlite3BtreeKeySize(pCsr->pCursor, &nKey); |
| 70640 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, nKey, &iWriteOff); |
| 70641 | |
| 70642 | /* Make sure the aMalloc[] buffer is large enough for the record */ |
| 70643 | if( rc==SQLITE_OK && nKey>nMalloc ){ |
| 70644 | aMalloc = sqlite3DbReallocOrFree(db, aMalloc, nKey); |
| 70645 | if( !aMalloc ){ |
| 70646 | rc = SQLITE_NOMEM; |
| 70647 | }else{ |
| 70648 | nMalloc = nKey; |
| 70649 | } |
| 70650 | } |
| 70651 | |
| 70652 | /* Write the record itself to the output file */ |
| 70653 | if( rc==SQLITE_OK ){ |
| 70654 | /* sqlite3BtreeKey() cannot fail because sorter btrees held in memory */ |
| 70655 | rc = sqlite3BtreeKey(pCsr->pCursor, 0, nKey, aMalloc); |
| 70656 | if( ALWAYS(rc==SQLITE_OK) ){ |
| 70657 | rc = sqlite3OsWrite(pSorter->pTemp1, aMalloc, nKey, iWriteOff); |
| 70658 | iWriteOff += nKey; |
| 70659 | } |
| 70660 | } |
| 70661 | |
| 70662 | if( rc!=SQLITE_OK ) break; |
| 70663 | } |
| 70664 | |
| 70665 | /* This assert verifies that unless an error has occurred, the size of |
| 70666 | ** the PMA on disk is the same as the expected size stored in |
| 70667 | ** pSorter->nBtree. */ |
| 70668 | assert( rc!=SQLITE_OK || pSorter->nBtree==( |
| 70669 | iWriteOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nBtree) |
| 70670 | )); |
| 70671 | |
| 70672 | pSorter->iWriteOff = iWriteOff; |
| 70673 | sqlite3DbFree(db, aMalloc); |
| 70674 | } |
| 70675 | |
| 70676 | pSorter->nBtree = 0; |
| 70677 | return rc; |
| 70678 | } |
| 70679 | |
| 70680 | /* |
| 70681 | ** This function is called on a sorter cursor by the VDBE before each row |
| 70682 | ** is inserted into VdbeCursor.pCsr. Argument nKey is the size of the key, in |
| 70683 | ** bytes, about to be inserted. |
| 70684 | ** |
| 70685 | ** If it is determined that the temporary b-tree accessed via VdbeCursor.pCsr |
| 70686 | ** is large enough, its contents are written to a sorted PMA on disk and the |
| 70687 | ** tree emptied. This prevents the b-tree (which must be small enough to |
| 70688 | ** fit entirely in the cache in order to support efficient inserts) from |
| 70689 | ** growing too large. |
| 70690 | ** |
| 70691 | ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. |
| 70692 | */ |
| 70693 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *db, VdbeCursor *pCsr, int nKey){ |
| 70694 | int rc = SQLITE_OK; /* Return code */ |
| 70695 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70696 | if( pSorter ){ |
| 70697 | Pager *pPager = sqlite3BtreePager(pCsr->pBt); |
| 70698 | int nPage; /* Current size of temporary file in pages */ |
| 70699 | |
| 70700 | /* Sorters never spill to disk */ |
| 70701 | assert( sqlite3PagerFile(pPager)->pMethods==0 ); |
| 70702 | |
| 70703 | /* Determine how many pages the temporary b-tree has grown to */ |
| 70704 | sqlite3PagerPagecount(pPager, &nPage); |
| 70705 | |
| 70706 | /* If pSorter->nWorking is still zero, but the temporary file has been |
| 70707 | ** created in the file-system, then the most recent insert into the |
| 70708 | ** current b-tree segment probably caused the cache to overflow (it is |
| 70709 | ** also possible that sqlite3_release_memory() was called). So set the |
| 70710 | ** size of the working set to a little less than the current size of the |
| 70711 | ** file in pages. */ |
| 70712 | if( pSorter->nWorking==0 && sqlite3PagerUnderStress(pPager) ){ |
| 70713 | pSorter->nWorking = nPage-5; |
| 70714 | if( pSorter->nWorking<SORTER_MIN_WORKING ){ |
| 70715 | pSorter->nWorking = SORTER_MIN_WORKING; |
| 70716 | } |
| 70717 | } |
| 70718 | |
| 70719 | /* If the number of pages used by the current b-tree segment is greater |
| 70720 | ** than the size of the working set (VdbeSorter.nWorking), start a new |
| 70721 | ** segment b-tree. */ |
| 70722 | if( pSorter->nWorking && nPage>=pSorter->nWorking ){ |
| 70723 | BtCursor *p = pCsr->pCursor;/* Cursor structure to close and reopen */ |
| 70724 | int iRoot; /* Root page of new tree */ |
| 70725 | |
| 70726 | /* Copy the current contents of the b-tree into a PMA in sorted order. |
| 70727 | ** Close the currently open b-tree cursor. */ |
| 70728 | rc = vdbeSorterBtreeToPMA(db, pCsr); |
| 70729 | sqlite3BtreeCloseCursor(p); |
| 70730 | |
| 70731 | if( rc==SQLITE_OK ){ |
| 70732 | rc = sqlite3BtreeDropTable(pCsr->pBt, 2, 0); |
| 70733 | #ifdef SQLITE_DEBUG |
| 70734 | sqlite3PagerPagecount(pPager, &nPage); |
| 70735 | assert( rc!=SQLITE_OK || nPage==1 ); |
| 70736 | #endif |
| 70737 | } |
| 70738 | if( rc==SQLITE_OK ){ |
| 70739 | rc = sqlite3BtreeCreateTable(pCsr->pBt, &iRoot, BTREE_BLOBKEY); |
| 70740 | } |
| 70741 | if( rc==SQLITE_OK ){ |
| 70742 | assert( iRoot==2 ); |
| 70743 | rc = sqlite3BtreeCursor(pCsr->pBt, iRoot, 1, pCsr->pKeyInfo, p); |
| 70744 | } |
| 70745 | } |
| 70746 | |
| 70747 | pSorter->nBtree += sqlite3VarintLen(nKey) + nKey; |
| 70748 | } |
| 70749 | return rc; |
| 70750 | } |
| 70751 | |
| 70752 | /* |
| 70753 | ** Helper function for sqlite3VdbeSorterRewind(). |
| @@ -70761,16 +70952,16 @@ | |
| 70761 | int rc = SQLITE_OK; /* Return code */ |
| 70762 | int i; /* Used to iterator through aIter[] */ |
| 70763 | i64 nByte = 0; /* Total bytes in all opened PMAs */ |
| 70764 | |
| 70765 | /* Initialize the iterators. */ |
| 70766 | for(i=0; rc==SQLITE_OK && i<SORTER_MAX_MERGE_COUNT; i++){ |
| 70767 | VdbeSorterIter *pIter = &pSorter->aIter[i]; |
| 70768 | rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); |
| 70769 | pSorter->iReadOff = pIter->iEof; |
| 70770 | assert( pSorter->iReadOff<=pSorter->iWriteOff || rc!=SQLITE_OK ); |
| 70771 | if( pSorter->iReadOff>=pSorter->iWriteOff ) break; |
| 70772 | } |
| 70773 | |
| 70774 | /* Initialize the aTree[] array. */ |
| 70775 | for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ |
| 70776 | rc = vdbeSorterDoCompare(pCsr, i); |
| @@ -70793,18 +70984,22 @@ | |
| 70793 | int nByte; /* Bytes of space required for aIter/aTree */ |
| 70794 | int N = 2; /* Power of 2 >= nIter */ |
| 70795 | |
| 70796 | assert( pSorter ); |
| 70797 | |
| 70798 | /* Write the current b-tree to a PMA. Close the b-tree cursor. */ |
| 70799 | rc = vdbeSorterBtreeToPMA(db, pCsr); |
| 70800 | sqlite3BtreeCloseCursor(pCsr->pCursor); |
| 70801 | if( rc!=SQLITE_OK ) return rc; |
| 70802 | if( pSorter->nPMA==0 ){ |
| 70803 | *pbEof = 1; |
| 70804 | return SQLITE_OK; |
| 70805 | } |
| 70806 | |
| 70807 | /* Allocate space for aIter[] and aTree[]. */ |
| 70808 | nIter = pSorter->nPMA; |
| 70809 | if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; |
| 70810 | assert( nIter>0 ); |
| @@ -70888,47 +71083,96 @@ | |
| 70888 | /* |
| 70889 | ** Advance to the next element in the sorter. |
| 70890 | */ |
| 70891 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 70892 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70893 | int iPrev = pSorter->aTree[1]; /* Index of iterator to advance */ |
| 70894 | int i; /* Index of aTree[] to recalculate */ |
| 70895 | int rc; /* Return code */ |
| 70896 | |
| 70897 | rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 70898 | for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ |
| 70899 | rc = vdbeSorterDoCompare(pCsr, i); |
| 70900 | } |
| 70901 | |
| 70902 | *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 70903 | return rc; |
| 70904 | } |
| 70905 | |
| 70906 | /* |
| 70907 | ** Copy the current sorter key into the memory cell pOut. |
| 70908 | */ |
| 70909 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ |
| 70910 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70911 | VdbeSorterIter *pIter; |
| 70912 | |
| 70913 | pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 70914 | |
| 70915 | /* Coverage testing note: As things are currently, this call will always |
| 70916 | ** succeed. This is because the memory cell passed by the VDBE layer |
| 70917 | ** happens to be the same one as was used to assemble the keys before they |
| 70918 | ** were passed to the sorter - meaning it is always large enough for the |
| 70919 | ** largest key. But this could change very easily, so we leave the call |
| 70920 | ** to sqlite3VdbeMemGrow() in. */ |
| 70921 | if( NEVER(sqlite3VdbeMemGrow(pOut, pIter->nKey, 0)) ){ |
| 70922 | return SQLITE_NOMEM; |
| 70923 | } |
| 70924 | pOut->n = pIter->nKey; |
| 70925 | MemSetTypeFlag(pOut, MEM_Blob); |
| 70926 | memcpy(pOut->z, pIter->aKey, pIter->nKey); |
| 70927 | |
| 70928 | return SQLITE_OK; |
| 70929 | } |
| 70930 | |
| 70931 | #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ |
| 70932 | |
| 70933 | /************** End of vdbesort.c ********************************************/ |
| 70934 | /************** Begin file journal.c *****************************************/ |
| @@ -75077,11 +75321,11 @@ | |
| 75077 | if( !pAggInfo->directMode ){ |
| 75078 | assert( pCol->iMem>0 ); |
| 75079 | inReg = pCol->iMem; |
| 75080 | break; |
| 75081 | }else if( pAggInfo->useSortingIdx ){ |
| 75082 | sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, |
| 75083 | pCol->iSorterColumn, target); |
| 75084 | break; |
| 75085 | } |
| 75086 | /* Otherwise, fall thru into the TK_COLUMN case */ |
| 75087 | } |
| @@ -81235,27 +81479,19 @@ | |
| 81235 | Table *pTab = pIndex->pTable; /* The table that is indexed */ |
| 81236 | int iTab = pParse->nTab++; /* Btree cursor used for pTab */ |
| 81237 | int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ |
| 81238 | int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ |
| 81239 | int addr1; /* Address of top of loop */ |
| 81240 | int tnum; /* Root page of index */ |
| 81241 | Vdbe *v; /* Generate code into this virtual machine */ |
| 81242 | KeyInfo *pKey; /* KeyInfo for index */ |
| 81243 | int regIdxKey; /* Registers containing the index key */ |
| 81244 | int regRecord; /* Register holding assemblied index record */ |
| 81245 | sqlite3 *db = pParse->db; /* The database connection */ |
| 81246 | int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); |
| 81247 | |
| 81248 | /* Set bUseSorter to use OP_OpenSorter, or clear it to insert directly |
| 81249 | ** into the index. The sorter is used unless either OMIT_MERGE_SORT is |
| 81250 | ** defined or the system is configured to store temp files in-memory. */ |
| 81251 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 81252 | static const int bUseSorter = 0; |
| 81253 | #else |
| 81254 | const int bUseSorter = !sqlite3TempInMemory(pParse->db); |
| 81255 | #endif |
| 81256 | |
| 81257 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 81258 | if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, |
| 81259 | db->aDb[iDb].zName ) ){ |
| 81260 | return; |
| 81261 | } |
| @@ -81277,32 +81513,44 @@ | |
| 81277 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81278 | if( memRootPage>=0 ){ |
| 81279 | sqlite3VdbeChangeP5(v, 1); |
| 81280 | } |
| 81281 | |
| 81282 | /* Open the sorter cursor if we are to use one. */ |
| 81283 | if( bUseSorter ){ |
| 81284 | iSorter = pParse->nTab++; |
| 81285 | sqlite3VdbeAddOp4(v, OP_OpenSorter, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| 81286 | sqlite3VdbeChangeP5(v, BTREE_SORTER); |
| 81287 | } |
| 81288 | |
| 81289 | /* Open the table. Loop through all rows of the table, inserting index |
| 81290 | ** records into the sorter. */ |
| 81291 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| 81292 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); |
| 81293 | regRecord = sqlite3GetTempReg(pParse); |
| 81294 | regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); |
| 81295 | |
| 81296 | if( bUseSorter ){ |
| 81297 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iSorter, regRecord); |
| 81298 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); |
| 81299 | sqlite3VdbeJumpHere(v, addr1); |
| 81300 | addr1 = sqlite3VdbeAddOp2(v, OP_Sort, iSorter, 0); |
| 81301 | sqlite3VdbeAddOp2(v, OP_RowKey, iSorter, regRecord); |
| 81302 | } |
| 81303 | |
| 81304 | if( pIndex->onError!=OE_None ){ |
| 81305 | const int regRowid = regIdxKey + pIndex->nColumn; |
| 81306 | const int j2 = sqlite3VdbeCurrentAddr(v) + 2; |
| 81307 | void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); |
| 81308 | |
| @@ -81317,14 +81565,15 @@ | |
| 81317 | */ |
| 81318 | sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); |
| 81319 | sqlite3HaltConstraint( |
| 81320 | pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); |
| 81321 | } |
| 81322 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, bUseSorter); |
| 81323 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81324 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 81325 | sqlite3VdbeAddOp2(v, OP_Next, iSorter, addr1+1); |
| 81326 | sqlite3VdbeJumpHere(v, addr1); |
| 81327 | |
| 81328 | sqlite3VdbeAddOp1(v, OP_Close, iTab); |
| 81329 | sqlite3VdbeAddOp1(v, OP_Close, iIdx); |
| 81330 | sqlite3VdbeAddOp1(v, OP_Close, iSorter); |
| @@ -92534,16 +92783,22 @@ | |
| 92534 | ){ |
| 92535 | Vdbe *v = pParse->pVdbe; |
| 92536 | int nExpr = pOrderBy->nExpr; |
| 92537 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 92538 | int regRecord = sqlite3GetTempReg(pParse); |
| 92539 | sqlite3ExprCacheClear(pParse); |
| 92540 | sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 92541 | sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 92542 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 92543 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 92544 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); |
| 92545 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 92546 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 92547 | if( pSelect->iLimit ){ |
| 92548 | int addr1, addr2; |
| 92549 | int iLimit; |
| @@ -93008,13 +93263,24 @@ | |
| 93008 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 93009 | regRowid = 0; |
| 93010 | }else{ |
| 93011 | regRowid = sqlite3GetTempReg(pParse); |
| 93012 | } |
| 93013 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); |
| 93014 | codeOffset(v, p, addrContinue); |
| 93015 | sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); |
| 93016 | switch( eDest ){ |
| 93017 | case SRT_Table: |
| 93018 | case SRT_EphemTab: { |
| 93019 | testcase( eDest==SRT_Table ); |
| 93020 | testcase( eDest==SRT_EphemTab ); |
| @@ -93063,11 +93329,15 @@ | |
| 93063 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 93064 | |
| 93065 | /* The bottom of the loop |
| 93066 | */ |
| 93067 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 93068 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); |
| 93069 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 93070 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 93071 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 93072 | } |
| 93073 | } |
| @@ -96029,10 +96299,14 @@ | |
| 96029 | /* Set the limiter. |
| 96030 | */ |
| 96031 | iEnd = sqlite3VdbeMakeLabel(v); |
| 96032 | p->nSelectRow = (double)LARGEST_INT64; |
| 96033 | computeLimitRegisters(pParse, p, iEnd); |
| 96034 | |
| 96035 | /* Open a virtual index to use for the distinct set. |
| 96036 | */ |
| 96037 | if( p->selFlags & SF_Distinct ){ |
| 96038 | KeyInfo *pKeyInfo; |
| @@ -96064,11 +96338,11 @@ | |
| 96064 | } |
| 96065 | |
| 96066 | if( pWInfo->eDistinct ){ |
| 96067 | VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 96068 | |
| 96069 | assert( addrDistinctIndex>0 ); |
| 96070 | pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); |
| 96071 | |
| 96072 | assert( isDistinct ); |
| 96073 | assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED |
| 96074 | || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE |
| @@ -96123,10 +96397,12 @@ | |
| 96123 | ** one row of the input to the aggregator has been |
| 96124 | ** processed */ |
| 96125 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 96126 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 96127 | int addrEnd; /* End of processing for this SELECT */ |
| 96128 | |
| 96129 | /* Remove any and all aliases between the result set and the |
| 96130 | ** GROUP BY clause. |
| 96131 | */ |
| 96132 | if( pGroupBy ){ |
| @@ -96184,16 +96460,16 @@ | |
| 96184 | int addrReset; /* Subroutine for resetting the accumulator */ |
| 96185 | int regReset; /* Return address register for reset subroutine */ |
| 96186 | |
| 96187 | /* If there is a GROUP BY clause we might need a sorting index to |
| 96188 | ** implement it. Allocate that sorting index now. If it turns out |
| 96189 | ** that we do not need it after all, the OpenEphemeral instruction |
| 96190 | ** will be converted into a Noop. |
| 96191 | */ |
| 96192 | sAggInfo.sortingIdx = pParse->nTab++; |
| 96193 | pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); |
| 96194 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 96195 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 96196 | 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); |
| 96197 | |
| 96198 | /* Initialize memory locations used by GROUP BY aggregate processing |
| 96199 | */ |
| @@ -96270,15 +96546,18 @@ | |
| 96270 | j++; |
| 96271 | } |
| 96272 | } |
| 96273 | regRecord = sqlite3GetTempReg(pParse); |
| 96274 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); |
| 96275 | sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); |
| 96276 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 96277 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 96278 | sqlite3WhereEnd(pWInfo); |
| 96279 | sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); |
| 96280 | VdbeComment((v, "GROUP BY sort")); |
| 96281 | sAggInfo.useSortingIdx = 1; |
| 96282 | sqlite3ExprCacheClear(pParse); |
| 96283 | } |
| 96284 | |
| @@ -96287,13 +96566,17 @@ | |
| 96287 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| 96288 | ** from the previous row currently stored in a0, a1, a2... |
| 96289 | */ |
| 96290 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 96291 | sqlite3ExprCacheClear(pParse); |
| 96292 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 96293 | if( groupBySort ){ |
| 96294 | sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j); |
| 96295 | }else{ |
| 96296 | sAggInfo.directMode = 1; |
| 96297 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 96298 | } |
| 96299 | } |
| @@ -96328,11 +96611,11 @@ | |
| 96328 | VdbeComment((v, "indicate data in accumulator")); |
| 96329 | |
| 96330 | /* End of the loop |
| 96331 | */ |
| 96332 | if( groupBySort ){ |
| 96333 | sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); |
| 96334 | }else{ |
| 96335 | sqlite3WhereEnd(pWInfo); |
| 96336 | sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); |
| 96337 | } |
| 96338 | |
| 96339 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -656,11 +656,11 @@ | |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | */ |
| 659 | #define SQLITE_VERSION "3.7.8" |
| 660 | #define SQLITE_VERSION_NUMBER 3007008 |
| 661 | #define SQLITE_SOURCE_ID "2011-09-04 01:27:00 6b657ae75035eb10b0ad640998d3c9eadfdffa6e" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -7632,18 +7632,10 @@ | |
| 7632 | */ |
| 7633 | #ifndef SQLITE_TEMP_STORE |
| 7634 | # define SQLITE_TEMP_STORE 1 |
| 7635 | #endif |
| 7636 | |
| 7637 | /* |
| 7638 | ** GCC does not define the offsetof() macro so we'll have to do it |
| 7639 | ** ourselves. |
| 7640 | */ |
| 7641 | #ifndef offsetof |
| @@ -7982,11 +7974,10 @@ | |
| 7974 | #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ |
| 7975 | #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ |
| 7976 | #define BTREE_MEMORY 4 /* This is an in-memory DB */ |
| 7977 | #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ |
| 7978 | #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ |
| 7979 | |
| 7980 | SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); |
| 7981 | SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); |
| 7982 | SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); |
| 7983 | SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); |
| @@ -8399,13 +8390,13 @@ | |
| 8390 | #define OP_ReadCookie 35 |
| 8391 | #define OP_SetCookie 36 |
| 8392 | #define OP_VerifyCookie 37 |
| 8393 | #define OP_OpenRead 38 |
| 8394 | #define OP_OpenWrite 39 |
| 8395 | #define OP_OpenAutoindex 40 |
| 8396 | #define OP_OpenEphemeral 41 |
| 8397 | #define OP_SorterOpen 42 |
| 8398 | #define OP_OpenPseudo 43 |
| 8399 | #define OP_Close 44 |
| 8400 | #define OP_SeekLt 45 |
| 8401 | #define OP_SeekLe 46 |
| 8402 | #define OP_SeekGe 47 |
| @@ -8419,70 +8410,72 @@ | |
| 8410 | #define OP_NewRowid 55 |
| 8411 | #define OP_Insert 56 |
| 8412 | #define OP_InsertInt 57 |
| 8413 | #define OP_Delete 58 |
| 8414 | #define OP_ResetCount 59 |
| 8415 | #define OP_SorterCompare 60 |
| 8416 | #define OP_SorterData 61 |
| 8417 | #define OP_RowKey 62 |
| 8418 | #define OP_RowData 63 |
| 8419 | #define OP_Rowid 64 |
| 8420 | #define OP_NullRow 65 |
| 8421 | #define OP_Last 66 |
| 8422 | #define OP_SorterSort 67 |
| 8423 | #define OP_Sort 70 |
| 8424 | #define OP_Rewind 71 |
| 8425 | #define OP_SorterNext 72 |
| 8426 | #define OP_Prev 81 |
| 8427 | #define OP_Next 92 |
| 8428 | #define OP_SorterInsert 95 |
| 8429 | #define OP_IdxInsert 96 |
| 8430 | #define OP_IdxDelete 97 |
| 8431 | #define OP_IdxRowid 98 |
| 8432 | #define OP_IdxLT 99 |
| 8433 | #define OP_IdxGE 100 |
| 8434 | #define OP_Destroy 101 |
| 8435 | #define OP_Clear 102 |
| 8436 | #define OP_CreateIndex 103 |
| 8437 | #define OP_CreateTable 104 |
| 8438 | #define OP_ParseSchema 105 |
| 8439 | #define OP_LoadAnalysis 106 |
| 8440 | #define OP_DropTable 107 |
| 8441 | #define OP_DropIndex 108 |
| 8442 | #define OP_DropTrigger 109 |
| 8443 | #define OP_IntegrityCk 110 |
| 8444 | #define OP_RowSetAdd 111 |
| 8445 | #define OP_RowSetRead 112 |
| 8446 | #define OP_RowSetTest 113 |
| 8447 | #define OP_Program 114 |
| 8448 | #define OP_Param 115 |
| 8449 | #define OP_FkCounter 116 |
| 8450 | #define OP_FkIfZero 117 |
| 8451 | #define OP_MemMax 118 |
| 8452 | #define OP_IfPos 119 |
| 8453 | #define OP_IfNeg 120 |
| 8454 | #define OP_IfZero 121 |
| 8455 | #define OP_AggStep 122 |
| 8456 | #define OP_AggFinal 123 |
| 8457 | #define OP_Checkpoint 124 |
| 8458 | #define OP_JournalMode 125 |
| 8459 | #define OP_Vacuum 126 |
| 8460 | #define OP_IncrVacuum 127 |
| 8461 | #define OP_Expire 128 |
| 8462 | #define OP_TableLock 129 |
| 8463 | #define OP_VBegin 131 |
| 8464 | #define OP_VCreate 132 |
| 8465 | #define OP_VDestroy 133 |
| 8466 | #define OP_VOpen 134 |
| 8467 | #define OP_VFilter 135 |
| 8468 | #define OP_VColumn 136 |
| 8469 | #define OP_VNext 137 |
| 8470 | #define OP_VRename 138 |
| 8471 | #define OP_VUpdate 139 |
| 8472 | #define OP_Pagecount 140 |
| 8473 | #define OP_MaxPgcnt 146 |
| 8474 | #define OP_Trace 147 |
| 8475 | #define OP_Noop 148 |
| 8476 | #define OP_Explain 149 |
| 8477 | |
| 8478 | |
| 8479 | /* Properties such as "out2" or "jump" that are specified in |
| 8480 | ** comments following the "case" for each opcode in the vdbe.c |
| 8481 | ** are encoded into bitvectors as follows: |
| @@ -8500,22 +8493,22 @@ | |
| 8493 | /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ |
| 8494 | /* 24 */ 0x00, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02,\ |
| 8495 | /* 32 */ 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00,\ |
| 8496 | /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,\ |
| 8497 | /* 48 */ 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02,\ |
| 8498 | /* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 8499 | /* 64 */ 0x02, 0x00, 0x01, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ |
| 8500 | /* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ |
| 8501 | /* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ |
| 8502 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x08,\ |
| 8503 | /* 96 */ 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02,\ |
| 8504 | /* 104 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,\ |
| 8505 | /* 112 */ 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05,\ |
| 8506 | /* 120 */ 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\ |
| 8507 | /* 128 */ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01,\ |
| 8508 | /* 136 */ 0x00, 0x01, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04,\ |
| 8509 | /* 144 */ 0x04, 0x04, 0x02, 0x00, 0x00, 0x00,} |
| 8510 | |
| 8511 | /************** End of opcodes.h *********************************************/ |
| 8512 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 8513 | |
| 8514 | /* |
| @@ -8749,13 +8742,10 @@ | |
| 8742 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); |
| 8743 | SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); |
| 8744 | SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); |
| 8745 | SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); |
| 8746 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); |
| 8747 | |
| 8748 | /* Functions used to truncate the database file. */ |
| 8749 | SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); |
| 8750 | |
| 8751 | #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) |
| @@ -10186,10 +10176,11 @@ | |
| 10176 | u8 directMode; /* Direct rendering mode means take data directly |
| 10177 | ** from source tables rather than from accumulators */ |
| 10178 | u8 useSortingIdx; /* In direct mode, reference the sorting index rather |
| 10179 | ** than the source table */ |
| 10180 | int sortingIdx; /* Cursor number of the sorting index */ |
| 10181 | int sortingIdxPTab; /* Cursor number of pseudo-table */ |
| 10182 | ExprList *pGroupBy; /* The group by clause */ |
| 10183 | int nSortingColumn; /* Number of columns in the sorting index */ |
| 10184 | struct AggInfo_col { /* For each column used in source tables */ |
| 10185 | Table *pTab; /* Source table */ |
| 10186 | int iTable; /* Cursor number of the source table */ |
| @@ -10718,10 +10709,11 @@ | |
| 10709 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 10710 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 10711 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 10712 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 10713 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 10714 | #define SF_UseSorter 0x0040 /* Sort using a sorter */ |
| 10715 | |
| 10716 | |
| 10717 | /* |
| 10718 | ** The results of a select can be distributed in several ways. The |
| 10719 | ** "SRT" prefix means "SELECT Result Type". |
| @@ -12267,10 +12259,13 @@ | |
| 12259 | "INT64_TYPE", |
| 12260 | #endif |
| 12261 | #ifdef SQLITE_LOCK_TRACE |
| 12262 | "LOCK_TRACE", |
| 12263 | #endif |
| 12264 | #ifdef SQLITE_MAX_SCHEMA_RETRY |
| 12265 | "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 12266 | #endif |
| 12267 | #ifdef SQLITE_MEMDEBUG |
| 12268 | "MEMDEBUG", |
| 12269 | #endif |
| 12270 | #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 12271 | "MIXED_ENDIAN_64BIT_FLOAT", |
| @@ -12601,16 +12596,17 @@ | |
| 12596 | Bool nullRow; /* True if pointing to a row with no data */ |
| 12597 | Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 12598 | Bool isTable; /* True if a table requiring integer keys */ |
| 12599 | Bool isIndex; /* True if an index containing keys only - no data */ |
| 12600 | Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ |
| 12601 | Bool isSorter; /* True if a new-style sorter */ |
| 12602 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 12603 | const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ |
| 12604 | i64 seqCount; /* Sequence counter */ |
| 12605 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 12606 | i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ |
| 12607 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 12608 | |
| 12609 | /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or |
| 12610 | ** OP_IsUnique opcode on this cursor. */ |
| 12611 | int seekResult; |
| 12612 | |
| @@ -12944,17 +12940,19 @@ | |
| 12940 | # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK |
| 12941 | # define sqlite3VdbeSorterClose(Y,Z) |
| 12942 | # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK |
| 12943 | # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK |
| 12944 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 12945 | # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK |
| 12946 | #else |
| 12947 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 12948 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 12949 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); |
| 12950 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); |
| 12951 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); |
| 12952 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); |
| 12953 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); |
| 12954 | #endif |
| 12955 | |
| 12956 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 12957 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 12958 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22114,13 +22112,13 @@ | |
| 22112 | /* 35 */ "ReadCookie", |
| 22113 | /* 36 */ "SetCookie", |
| 22114 | /* 37 */ "VerifyCookie", |
| 22115 | /* 38 */ "OpenRead", |
| 22116 | /* 39 */ "OpenWrite", |
| 22117 | /* 40 */ "OpenAutoindex", |
| 22118 | /* 41 */ "OpenEphemeral", |
| 22119 | /* 42 */ "SorterOpen", |
| 22120 | /* 43 */ "OpenPseudo", |
| 22121 | /* 44 */ "Close", |
| 22122 | /* 45 */ "SeekLt", |
| 22123 | /* 46 */ "SeekLe", |
| 22124 | /* 47 */ "SeekGe", |
| @@ -22134,32 +22132,32 @@ | |
| 22132 | /* 55 */ "NewRowid", |
| 22133 | /* 56 */ "Insert", |
| 22134 | /* 57 */ "InsertInt", |
| 22135 | /* 58 */ "Delete", |
| 22136 | /* 59 */ "ResetCount", |
| 22137 | /* 60 */ "SorterCompare", |
| 22138 | /* 61 */ "SorterData", |
| 22139 | /* 62 */ "RowKey", |
| 22140 | /* 63 */ "RowData", |
| 22141 | /* 64 */ "Rowid", |
| 22142 | /* 65 */ "NullRow", |
| 22143 | /* 66 */ "Last", |
| 22144 | /* 67 */ "SorterSort", |
| 22145 | /* 68 */ "Or", |
| 22146 | /* 69 */ "And", |
| 22147 | /* 70 */ "Sort", |
| 22148 | /* 71 */ "Rewind", |
| 22149 | /* 72 */ "SorterNext", |
| 22150 | /* 73 */ "IsNull", |
| 22151 | /* 74 */ "NotNull", |
| 22152 | /* 75 */ "Ne", |
| 22153 | /* 76 */ "Eq", |
| 22154 | /* 77 */ "Gt", |
| 22155 | /* 78 */ "Le", |
| 22156 | /* 79 */ "Lt", |
| 22157 | /* 80 */ "Ge", |
| 22158 | /* 81 */ "Prev", |
| 22159 | /* 82 */ "BitAnd", |
| 22160 | /* 83 */ "BitOr", |
| 22161 | /* 84 */ "ShiftLeft", |
| 22162 | /* 85 */ "ShiftRight", |
| 22163 | /* 86 */ "Add", |
| @@ -22166,64 +22164,68 @@ | |
| 22164 | /* 87 */ "Subtract", |
| 22165 | /* 88 */ "Multiply", |
| 22166 | /* 89 */ "Divide", |
| 22167 | /* 90 */ "Remainder", |
| 22168 | /* 91 */ "Concat", |
| 22169 | /* 92 */ "Next", |
| 22170 | /* 93 */ "BitNot", |
| 22171 | /* 94 */ "String8", |
| 22172 | /* 95 */ "SorterInsert", |
| 22173 | /* 96 */ "IdxInsert", |
| 22174 | /* 97 */ "IdxDelete", |
| 22175 | /* 98 */ "IdxRowid", |
| 22176 | /* 99 */ "IdxLT", |
| 22177 | /* 100 */ "IdxGE", |
| 22178 | /* 101 */ "Destroy", |
| 22179 | /* 102 */ "Clear", |
| 22180 | /* 103 */ "CreateIndex", |
| 22181 | /* 104 */ "CreateTable", |
| 22182 | /* 105 */ "ParseSchema", |
| 22183 | /* 106 */ "LoadAnalysis", |
| 22184 | /* 107 */ "DropTable", |
| 22185 | /* 108 */ "DropIndex", |
| 22186 | /* 109 */ "DropTrigger", |
| 22187 | /* 110 */ "IntegrityCk", |
| 22188 | /* 111 */ "RowSetAdd", |
| 22189 | /* 112 */ "RowSetRead", |
| 22190 | /* 113 */ "RowSetTest", |
| 22191 | /* 114 */ "Program", |
| 22192 | /* 115 */ "Param", |
| 22193 | /* 116 */ "FkCounter", |
| 22194 | /* 117 */ "FkIfZero", |
| 22195 | /* 118 */ "MemMax", |
| 22196 | /* 119 */ "IfPos", |
| 22197 | /* 120 */ "IfNeg", |
| 22198 | /* 121 */ "IfZero", |
| 22199 | /* 122 */ "AggStep", |
| 22200 | /* 123 */ "AggFinal", |
| 22201 | /* 124 */ "Checkpoint", |
| 22202 | /* 125 */ "JournalMode", |
| 22203 | /* 126 */ "Vacuum", |
| 22204 | /* 127 */ "IncrVacuum", |
| 22205 | /* 128 */ "Expire", |
| 22206 | /* 129 */ "TableLock", |
| 22207 | /* 130 */ "Real", |
| 22208 | /* 131 */ "VBegin", |
| 22209 | /* 132 */ "VCreate", |
| 22210 | /* 133 */ "VDestroy", |
| 22211 | /* 134 */ "VOpen", |
| 22212 | /* 135 */ "VFilter", |
| 22213 | /* 136 */ "VColumn", |
| 22214 | /* 137 */ "VNext", |
| 22215 | /* 138 */ "VRename", |
| 22216 | /* 139 */ "VUpdate", |
| 22217 | /* 140 */ "Pagecount", |
| 22218 | /* 141 */ "ToText", |
| 22219 | /* 142 */ "ToBlob", |
| 22220 | /* 143 */ "ToNumeric", |
| 22221 | /* 144 */ "ToInt", |
| 22222 | /* 145 */ "ToReal", |
| 22223 | /* 146 */ "MaxPgcnt", |
| 22224 | /* 147 */ "Trace", |
| 22225 | /* 148 */ "Noop", |
| 22226 | /* 149 */ "Explain", |
| 22227 | }; |
| 22228 | return azName[i]; |
| 22229 | } |
| 22230 | #endif |
| 22231 | |
| @@ -22314,11 +22316,11 @@ | |
| 22316 | */ |
| 22317 | #ifdef MEMORY_DEBUG |
| 22318 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 22319 | #endif |
| 22320 | |
| 22321 | #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 22322 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 22323 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 22324 | # endif |
| 22325 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 22326 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -24656,11 +24658,11 @@ | |
| 24658 | */ |
| 24659 | #ifdef MEMORY_DEBUG |
| 24660 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 24661 | #endif |
| 24662 | |
| 24663 | #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 24664 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 24665 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 24666 | # endif |
| 24667 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 24668 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -27716,15 +27718,15 @@ | |
| 27718 | SQLITE_API int sqlite3_fullsync_count = 0; |
| 27719 | #endif |
| 27720 | |
| 27721 | /* |
| 27722 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 27723 | ** Others do no. To be safe, we will stick with the (slightly slower) |
| 27724 | ** fsync(). If you know that your system does support fdatasync() correctly, |
| 27725 | ** then simply compile with -Dfdatasync=fdatasync |
| 27726 | */ |
| 27727 | #if !defined(fdatasync) |
| 27728 | # define fdatasync fsync |
| 27729 | #endif |
| 27730 | |
| 27731 | /* |
| 27732 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28015,11 +28017,11 @@ | |
| 28017 | ** file-control operation. Enlarge the database to nBytes in size |
| 28018 | ** (rounded up to the next chunk-size). If the database is already |
| 28019 | ** nBytes or larger, this routine is a no-op. |
| 28020 | */ |
| 28021 | static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
| 28022 | if( pFile->szChunk>0 ){ |
| 28023 | i64 nSize; /* Required file size */ |
| 28024 | struct stat buf; /* Used to hold return values of fstat() */ |
| 28025 | |
| 28026 | if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 28027 | |
| @@ -28210,15 +28212,13 @@ | |
| 28212 | */ |
| 28213 | struct unixShm { |
| 28214 | unixShmNode *pShmNode; /* The underlying unixShmNode object */ |
| 28215 | unixShm *pNext; /* Next unixShm with the same unixShmNode */ |
| 28216 | u8 hasMutex; /* True if holding the unixShmNode mutex */ |
| 28217 | u8 id; /* Id of this connection within its unixShmNode */ |
| 28218 | u16 sharedMask; /* Mask of shared locks held */ |
| 28219 | u16 exclMask; /* Mask of exclusive locks held */ |
| 28220 | }; |
| 28221 | |
| 28222 | /* |
| 28223 | ** Constants used for locking |
| 28224 | */ |
| @@ -31435,11 +31435,11 @@ | |
| 31435 | */ |
| 31436 | #ifdef MEMORY_DEBUG |
| 31437 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 31438 | #endif |
| 31439 | |
| 31440 | #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 31441 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 31442 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 31443 | # endif |
| 31444 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 31445 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| @@ -32768,11 +32768,11 @@ | |
| 32768 | /* If the user has configured a chunk-size for this file, truncate the |
| 32769 | ** file so that it consists of an integer number of chunks (i.e. the |
| 32770 | ** actual file size after the operation may be larger than the requested |
| 32771 | ** size). |
| 32772 | */ |
| 32773 | if( pFile->szChunk>0 ){ |
| 32774 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 32775 | } |
| 32776 | |
| 32777 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 32778 | if( seekWinFile(pFile, nByte) ){ |
| @@ -33155,22 +33155,24 @@ | |
| 33155 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33156 | pFile->szChunk = *(int *)pArg; |
| 33157 | return SQLITE_OK; |
| 33158 | } |
| 33159 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33160 | if( pFile->szChunk>0 ){ |
| 33161 | sqlite3_int64 oldSz; |
| 33162 | int rc = winFileSize(id, &oldSz); |
| 33163 | if( rc==SQLITE_OK ){ |
| 33164 | sqlite3_int64 newSz = *(sqlite3_int64*)pArg; |
| 33165 | if( newSz>oldSz ){ |
| 33166 | SimulateIOErrorBenign(1); |
| 33167 | rc = winTruncate(id, newSz); |
| 33168 | SimulateIOErrorBenign(0); |
| 33169 | } |
| 33170 | } |
| 33171 | return rc; |
| 33172 | } |
| 33173 | return SQLITE_OK; |
| 33174 | } |
| 33175 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33176 | int bPersist = *(int*)pArg; |
| 33177 | if( bPersist<0 ){ |
| 33178 | *(int*)pArg = pFile->bPersistWal; |
| @@ -38137,11 +38139,10 @@ | |
| 38139 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 38140 | u8 tempFile; /* zFilename is a temporary file */ |
| 38141 | u8 readOnly; /* True for a read-only database */ |
| 38142 | u8 memDb; /* True to inhibit all file I/O */ |
| 38143 | u8 hasSeenStress; /* pagerStress() called one or more times */ |
| 38144 | |
| 38145 | /************************************************************************** |
| 38146 | ** The following block contains those class members that change during |
| 38147 | ** routine opertion. Class members not in this block are either fixed |
| 38148 | ** when the pager is first created or else only change when there is a |
| @@ -38361,19 +38362,10 @@ | |
| 38362 | ); |
| 38363 | assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); |
| 38364 | assert( pagerUseWal(p)==0 ); |
| 38365 | } |
| 38366 | |
| 38367 | /* If changeCountDone is set, a RESERVED lock or greater must be held |
| 38368 | ** on the file. |
| 38369 | */ |
| 38370 | assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); |
| 38371 | assert( p->eLock!=PENDING_LOCK ); |
| @@ -42073,16 +42065,10 @@ | |
| 42065 | } |
| 42066 | /* pPager->xBusyHandler = 0; */ |
| 42067 | /* pPager->pBusyHandlerArg = 0; */ |
| 42068 | pPager->xReiniter = xReinit; |
| 42069 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ |
| 42070 | |
| 42071 | *ppPager = pPager; |
| 42072 | return SQLITE_OK; |
| 42073 | } |
| 42074 | |
| @@ -43623,21 +43609,10 @@ | |
| 43609 | */ |
| 43610 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ |
| 43611 | return MEMDB; |
| 43612 | } |
| 43613 | |
| 43614 | /* |
| 43615 | ** Check that there are at least nSavepoint savepoints open. If there are |
| 43616 | ** currently less than nSavepoints open, then open one or more savepoints |
| 43617 | ** to make up the difference. If the number of savepoints is already |
| 43618 | ** equal to nSavepoint, then this function is a no-op. |
| @@ -50002,26 +49977,15 @@ | |
| 49977 | assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); |
| 49978 | |
| 49979 | /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ |
| 49980 | assert( (flags & BTREE_SINGLE)==0 || isTempDb ); |
| 49981 | |
| 49982 | if( db->flags & SQLITE_NoReadlock ){ |
| 49983 | flags |= BTREE_NO_READLOCK; |
| 49984 | } |
| 49985 | if( isMemdb ){ |
| 49986 | flags |= BTREE_MEMORY; |
| 49987 | } |
| 49988 | if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ |
| 49989 | vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; |
| 49990 | } |
| 49991 | p = sqlite3MallocZero(sizeof(Btree)); |
| @@ -51022,15 +50986,16 @@ | |
| 50986 | for(i=0; i<nCell; i++){ |
| 50987 | u8 *pCell = findCell(pPage, i); |
| 50988 | if( eType==PTRMAP_OVERFLOW1 ){ |
| 50989 | CellInfo info; |
| 50990 | btreeParseCellPtr(pPage, pCell, &info); |
| 50991 | if( info.iOverflow |
| 50992 | && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage |
| 50993 | && iFrom==get4byte(&pCell[info.iOverflow]) |
| 50994 | ){ |
| 50995 | put4byte(&pCell[info.iOverflow], iTo); |
| 50996 | break; |
| 50997 | } |
| 50998 | }else{ |
| 50999 | if( get4byte(pCell)==iFrom ){ |
| 51000 | put4byte(pCell, iTo); |
| 51001 | break; |
| @@ -53458,10 +53423,13 @@ | |
| 53423 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 53424 | btreeParseCellPtr(pPage, pCell, &info); |
| 53425 | if( info.iOverflow==0 ){ |
| 53426 | return SQLITE_OK; /* No overflow pages. Return without doing anything */ |
| 53427 | } |
| 53428 | if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ |
| 53429 | return SQLITE_CORRUPT; /* Cell extends past end of page */ |
| 53430 | } |
| 53431 | ovflPgno = get4byte(&pCell[info.iOverflow]); |
| 53432 | assert( pBt->usableSize > 4 ); |
| 53433 | ovflPageSize = pBt->usableSize - 4; |
| 53434 | nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; |
| 53435 | assert( ovflPgno==0 || nOvfl>0 ); |
| @@ -55560,20 +55528,13 @@ | |
| 55528 | releasePage(pPage); |
| 55529 | } |
| 55530 | return rc; |
| 55531 | } |
| 55532 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ |
| 55533 | int rc; |
| 55534 | sqlite3BtreeEnter(p); |
| 55535 | rc = btreeDropTable(p, iTable, piMoved); |
| 55536 | sqlite3BtreeLeave(p); |
| 55537 | return rc; |
| 55538 | } |
| 55539 | |
| 55540 | |
| @@ -58758,11 +58719,11 @@ | |
| 58719 | assert( p->nOp - i >= 3 ); |
| 58720 | assert( pOp[-1].opcode==OP_Integer ); |
| 58721 | n = pOp[-1].p1; |
| 58722 | if( n>nMaxArgs ) nMaxArgs = n; |
| 58723 | #endif |
| 58724 | }else if( opcode==OP_Next || opcode==OP_SorterNext ){ |
| 58725 | pOp->p4.xAdvance = sqlite3BtreeNext; |
| 58726 | pOp->p4type = P4_ADVANCE; |
| 58727 | }else if( opcode==OP_Prev ){ |
| 58728 | pOp->p4.xAdvance = sqlite3BtreePrevious; |
| 58729 | pOp->p4type = P4_ADVANCE; |
| @@ -63871,55 +63832,58 @@ | |
| 63832 | Db *pDb; |
| 63833 | } aw; |
| 63834 | struct OP_OpenEphemeral_stack_vars { |
| 63835 | VdbeCursor *pCx; |
| 63836 | } ax; |
| 63837 | struct OP_SorterOpen_stack_vars { |
| 63838 | VdbeCursor *pCx; |
| 63839 | } ay; |
| 63840 | struct OP_OpenPseudo_stack_vars { |
| 63841 | VdbeCursor *pCx; |
| 63842 | } az; |
| 63843 | struct OP_SeekGt_stack_vars { |
| 63844 | int res; |
| 63845 | int oc; |
| 63846 | VdbeCursor *pC; |
| 63847 | UnpackedRecord r; |
| 63848 | int nField; |
| 63849 | i64 iKey; /* The rowid we are to seek to */ |
| 63850 | } ba; |
| 63851 | struct OP_Seek_stack_vars { |
| 63852 | VdbeCursor *pC; |
| 63853 | } bb; |
| 63854 | struct OP_Found_stack_vars { |
| 63855 | int alreadyExists; |
| 63856 | VdbeCursor *pC; |
| 63857 | int res; |
| 63858 | UnpackedRecord *pIdxKey; |
| 63859 | UnpackedRecord r; |
| 63860 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 63861 | } bc; |
| 63862 | struct OP_IsUnique_stack_vars { |
| 63863 | u16 ii; |
| 63864 | VdbeCursor *pCx; |
| 63865 | BtCursor *pCrsr; |
| 63866 | u16 nField; |
| 63867 | Mem *aMx; |
| 63868 | UnpackedRecord r; /* B-Tree index search key */ |
| 63869 | i64 R; /* Rowid stored in register P3 */ |
| 63870 | } bd; |
| 63871 | struct OP_NotExists_stack_vars { |
| 63872 | VdbeCursor *pC; |
| 63873 | BtCursor *pCrsr; |
| 63874 | int res; |
| 63875 | u64 iKey; |
| 63876 | } be; |
| 63877 | struct OP_NewRowid_stack_vars { |
| 63878 | i64 v; /* The new rowid */ |
| 63879 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 63880 | int res; /* Result of an sqlite3BtreeLast() */ |
| 63881 | int cnt; /* Counter to limit the number of searches */ |
| 63882 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 63883 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 63884 | } bf; |
| 63885 | struct OP_InsertInt_stack_vars { |
| 63886 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 63887 | Mem *pKey; /* MEM cell holding key for the record */ |
| 63888 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 63889 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| @@ -63926,154 +63890,161 @@ | |
| 63890 | int nZero; /* Number of zero-bytes to append */ |
| 63891 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 63892 | const char *zDb; /* database name - used by the update hook */ |
| 63893 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 63894 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 63895 | } bg; |
| 63896 | struct OP_Delete_stack_vars { |
| 63897 | i64 iKey; |
| 63898 | VdbeCursor *pC; |
| 63899 | } bh; |
| 63900 | struct OP_SorterCompare_stack_vars { |
| 63901 | VdbeCursor *pC; |
| 63902 | int res; |
| 63903 | } bi; |
| 63904 | struct OP_SorterData_stack_vars { |
| 63905 | VdbeCursor *pC; |
| 63906 | } bj; |
| 63907 | struct OP_RowData_stack_vars { |
| 63908 | VdbeCursor *pC; |
| 63909 | BtCursor *pCrsr; |
| 63910 | u32 n; |
| 63911 | i64 n64; |
| 63912 | } bk; |
| 63913 | struct OP_Rowid_stack_vars { |
| 63914 | VdbeCursor *pC; |
| 63915 | i64 v; |
| 63916 | sqlite3_vtab *pVtab; |
| 63917 | const sqlite3_module *pModule; |
| 63918 | } bl; |
| 63919 | struct OP_NullRow_stack_vars { |
| 63920 | VdbeCursor *pC; |
| 63921 | } bm; |
| 63922 | struct OP_Last_stack_vars { |
| 63923 | VdbeCursor *pC; |
| 63924 | BtCursor *pCrsr; |
| 63925 | int res; |
| 63926 | } bn; |
| 63927 | struct OP_Rewind_stack_vars { |
| 63928 | VdbeCursor *pC; |
| 63929 | BtCursor *pCrsr; |
| 63930 | int res; |
| 63931 | } bo; |
| 63932 | struct OP_Next_stack_vars { |
| 63933 | VdbeCursor *pC; |
| 63934 | int res; |
| 63935 | } bp; |
| 63936 | struct OP_IdxInsert_stack_vars { |
| 63937 | VdbeCursor *pC; |
| 63938 | BtCursor *pCrsr; |
| 63939 | int nKey; |
| 63940 | const char *zKey; |
| 63941 | } bq; |
| 63942 | struct OP_IdxDelete_stack_vars { |
| 63943 | VdbeCursor *pC; |
| 63944 | BtCursor *pCrsr; |
| 63945 | int res; |
| 63946 | UnpackedRecord r; |
| 63947 | } br; |
| 63948 | struct OP_IdxRowid_stack_vars { |
| 63949 | BtCursor *pCrsr; |
| 63950 | VdbeCursor *pC; |
| 63951 | i64 rowid; |
| 63952 | } bs; |
| 63953 | struct OP_IdxGE_stack_vars { |
| 63954 | VdbeCursor *pC; |
| 63955 | int res; |
| 63956 | UnpackedRecord r; |
| 63957 | } bt; |
| 63958 | struct OP_Destroy_stack_vars { |
| 63959 | int iMoved; |
| 63960 | int iCnt; |
| 63961 | Vdbe *pVdbe; |
| 63962 | int iDb; |
| 63963 | } bu; |
| 63964 | struct OP_Clear_stack_vars { |
| 63965 | int nChange; |
| 63966 | } bv; |
| 63967 | struct OP_CreateTable_stack_vars { |
| 63968 | int pgno; |
| 63969 | int flags; |
| 63970 | Db *pDb; |
| 63971 | } bw; |
| 63972 | struct OP_ParseSchema_stack_vars { |
| 63973 | int iDb; |
| 63974 | const char *zMaster; |
| 63975 | char *zSql; |
| 63976 | InitData initData; |
| 63977 | } bx; |
| 63978 | struct OP_IntegrityCk_stack_vars { |
| 63979 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 63980 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 63981 | int j; /* Loop counter */ |
| 63982 | int nErr; /* Number of errors reported */ |
| 63983 | char *z; /* Text of the error report */ |
| 63984 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 63985 | } by; |
| 63986 | struct OP_RowSetRead_stack_vars { |
| 63987 | i64 val; |
| 63988 | } bz; |
| 63989 | struct OP_RowSetTest_stack_vars { |
| 63990 | int iSet; |
| 63991 | int exists; |
| 63992 | } ca; |
| 63993 | struct OP_Program_stack_vars { |
| 63994 | int nMem; /* Number of memory registers for sub-program */ |
| 63995 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 63996 | Mem *pRt; /* Register to allocate runtime space */ |
| 63997 | Mem *pMem; /* Used to iterate through memory cells */ |
| 63998 | Mem *pEnd; /* Last memory cell in new array */ |
| 63999 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 64000 | SubProgram *pProgram; /* Sub-program to execute */ |
| 64001 | void *t; /* Token identifying trigger */ |
| 64002 | } cb; |
| 64003 | struct OP_Param_stack_vars { |
| 64004 | VdbeFrame *pFrame; |
| 64005 | Mem *pIn; |
| 64006 | } cc; |
| 64007 | struct OP_MemMax_stack_vars { |
| 64008 | Mem *pIn1; |
| 64009 | VdbeFrame *pFrame; |
| 64010 | } cd; |
| 64011 | struct OP_AggStep_stack_vars { |
| 64012 | int n; |
| 64013 | int i; |
| 64014 | Mem *pMem; |
| 64015 | Mem *pRec; |
| 64016 | sqlite3_context ctx; |
| 64017 | sqlite3_value **apVal; |
| 64018 | } ce; |
| 64019 | struct OP_AggFinal_stack_vars { |
| 64020 | Mem *pMem; |
| 64021 | } cf; |
| 64022 | struct OP_Checkpoint_stack_vars { |
| 64023 | int i; /* Loop counter */ |
| 64024 | int aRes[3]; /* Results */ |
| 64025 | Mem *pMem; /* Write results here */ |
| 64026 | } cg; |
| 64027 | struct OP_JournalMode_stack_vars { |
| 64028 | Btree *pBt; /* Btree to change journal mode of */ |
| 64029 | Pager *pPager; /* Pager associated with pBt */ |
| 64030 | int eNew; /* New journal mode */ |
| 64031 | int eOld; /* The old journal mode */ |
| 64032 | const char *zFilename; /* Name of database file for pPager */ |
| 64033 | } ch; |
| 64034 | struct OP_IncrVacuum_stack_vars { |
| 64035 | Btree *pBt; |
| 64036 | } ci; |
| 64037 | struct OP_VBegin_stack_vars { |
| 64038 | VTable *pVTab; |
| 64039 | } cj; |
| 64040 | struct OP_VOpen_stack_vars { |
| 64041 | VdbeCursor *pCur; |
| 64042 | sqlite3_vtab_cursor *pVtabCursor; |
| 64043 | sqlite3_vtab *pVtab; |
| 64044 | sqlite3_module *pModule; |
| 64045 | } ck; |
| 64046 | struct OP_VFilter_stack_vars { |
| 64047 | int nArg; |
| 64048 | int iQuery; |
| 64049 | const sqlite3_module *pModule; |
| 64050 | Mem *pQuery; |
| @@ -64082,40 +64053,40 @@ | |
| 64053 | sqlite3_vtab *pVtab; |
| 64054 | VdbeCursor *pCur; |
| 64055 | int res; |
| 64056 | int i; |
| 64057 | Mem **apArg; |
| 64058 | } cl; |
| 64059 | struct OP_VColumn_stack_vars { |
| 64060 | sqlite3_vtab *pVtab; |
| 64061 | const sqlite3_module *pModule; |
| 64062 | Mem *pDest; |
| 64063 | sqlite3_context sContext; |
| 64064 | } cm; |
| 64065 | struct OP_VNext_stack_vars { |
| 64066 | sqlite3_vtab *pVtab; |
| 64067 | const sqlite3_module *pModule; |
| 64068 | int res; |
| 64069 | VdbeCursor *pCur; |
| 64070 | } cn; |
| 64071 | struct OP_VRename_stack_vars { |
| 64072 | sqlite3_vtab *pVtab; |
| 64073 | Mem *pName; |
| 64074 | } co; |
| 64075 | struct OP_VUpdate_stack_vars { |
| 64076 | sqlite3_vtab *pVtab; |
| 64077 | sqlite3_module *pModule; |
| 64078 | int nArg; |
| 64079 | int i; |
| 64080 | sqlite_int64 rowid; |
| 64081 | Mem **apArg; |
| 64082 | Mem *pX; |
| 64083 | } cp; |
| 64084 | struct OP_Trace_stack_vars { |
| 64085 | char *zTrace; |
| 64086 | char *z; |
| 64087 | } cq; |
| 64088 | } u; |
| 64089 | /* End automatically generated code |
| 64090 | ********************************************************************/ |
| 64091 | |
| 64092 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| @@ -66746,17 +66717,10 @@ | |
| 66717 | ** This opcode works the same as OP_OpenEphemeral. It has a |
| 66718 | ** different name to distinguish its use. Tables created using |
| 66719 | ** by this opcode will be used for automatically created transient |
| 66720 | ** indices in joins. |
| 66721 | */ |
| 66722 | case OP_OpenAutoindex: |
| 66723 | case OP_OpenEphemeral: { |
| 66724 | #if 0 /* local variables moved into u.ax */ |
| 66725 | VdbeCursor *pCx; |
| 66726 | #endif /* local variables moved into u.ax */ |
| @@ -66766,11 +66730,10 @@ | |
| 66730 | SQLITE_OPEN_EXCLUSIVE | |
| 66731 | SQLITE_OPEN_DELETEONCLOSE | |
| 66732 | SQLITE_OPEN_TRANSIENT_DB; |
| 66733 | |
| 66734 | assert( pOp->p1>=0 ); |
| 66735 | u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66736 | if( u.ax.pCx==0 ) goto no_mem; |
| 66737 | u.ax.pCx->nullRow = 1; |
| 66738 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, |
| 66739 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| @@ -66800,14 +66763,33 @@ | |
| 66763 | u.ax.pCx->isTable = 1; |
| 66764 | } |
| 66765 | } |
| 66766 | u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66767 | u.ax.pCx->isIndex = !u.ax.pCx->isTable; |
| 66768 | break; |
| 66769 | } |
| 66770 | |
| 66771 | /* Opcode: OpenSorter P1 P2 * P4 * |
| 66772 | ** |
| 66773 | ** This opcode works like OP_OpenEphemeral except that it opens |
| 66774 | ** a transient index that is specifically designed to sort large |
| 66775 | ** tables using an external merge-sort algorithm. |
| 66776 | */ |
| 66777 | case OP_SorterOpen: { |
| 66778 | #if 0 /* local variables moved into u.ay */ |
| 66779 | VdbeCursor *pCx; |
| 66780 | #endif /* local variables moved into u.ay */ |
| 66781 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 66782 | u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66783 | if( u.ay.pCx==0 ) goto no_mem; |
| 66784 | u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66785 | u.ay.pCx->pKeyInfo->enc = ENC(p->db); |
| 66786 | u.ay.pCx->isSorter = 1; |
| 66787 | rc = sqlite3VdbeSorterInit(db, u.ay.pCx); |
| 66788 | #else |
| 66789 | pOp->opcode = OP_OpenEphemeral; |
| 66790 | pc--; |
| 66791 | #endif |
| 66792 | break; |
| 66793 | } |
| 66794 | |
| 66795 | /* Opcode: OpenPseudo P1 P2 P3 * * |
| @@ -66824,21 +66806,21 @@ | |
| 66806 | ** |
| 66807 | ** P3 is the number of fields in the records that will be stored by |
| 66808 | ** the pseudo-table. |
| 66809 | */ |
| 66810 | case OP_OpenPseudo: { |
| 66811 | #if 0 /* local variables moved into u.az */ |
| 66812 | VdbeCursor *pCx; |
| 66813 | #endif /* local variables moved into u.az */ |
| 66814 | |
| 66815 | assert( pOp->p1>=0 ); |
| 66816 | u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 66817 | if( u.az.pCx==0 ) goto no_mem; |
| 66818 | u.az.pCx->nullRow = 1; |
| 66819 | u.az.pCx->pseudoTableReg = pOp->p2; |
| 66820 | u.az.pCx->isTable = 1; |
| 66821 | u.az.pCx->isIndex = 0; |
| 66822 | break; |
| 66823 | } |
| 66824 | |
| 66825 | /* Opcode: Close P1 * * * * |
| 66826 | ** |
| @@ -66906,39 +66888,39 @@ | |
| 66888 | */ |
| 66889 | case OP_SeekLt: /* jump, in3 */ |
| 66890 | case OP_SeekLe: /* jump, in3 */ |
| 66891 | case OP_SeekGe: /* jump, in3 */ |
| 66892 | case OP_SeekGt: { /* jump, in3 */ |
| 66893 | #if 0 /* local variables moved into u.ba */ |
| 66894 | int res; |
| 66895 | int oc; |
| 66896 | VdbeCursor *pC; |
| 66897 | UnpackedRecord r; |
| 66898 | int nField; |
| 66899 | i64 iKey; /* The rowid we are to seek to */ |
| 66900 | #endif /* local variables moved into u.ba */ |
| 66901 | |
| 66902 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 66903 | assert( pOp->p2!=0 ); |
| 66904 | u.ba.pC = p->apCsr[pOp->p1]; |
| 66905 | assert( u.ba.pC!=0 ); |
| 66906 | assert( u.ba.pC->pseudoTableReg==0 ); |
| 66907 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 66908 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 66909 | assert( OP_SeekGt == OP_SeekLt+3 ); |
| 66910 | assert( u.ba.pC->isOrdered ); |
| 66911 | if( ALWAYS(u.ba.pC->pCursor!=0) ){ |
| 66912 | u.ba.oc = pOp->opcode; |
| 66913 | u.ba.pC->nullRow = 0; |
| 66914 | if( u.ba.pC->isTable ){ |
| 66915 | /* The input value in P3 might be of any type: integer, real, string, |
| 66916 | ** blob, or NULL. But it needs to be an integer before we can do |
| 66917 | ** the seek, so covert it. */ |
| 66918 | pIn3 = &aMem[pOp->p3]; |
| 66919 | applyNumericAffinity(pIn3); |
| 66920 | u.ba.iKey = sqlite3VdbeIntValue(pIn3); |
| 66921 | u.ba.pC->rowidIsValid = 0; |
| 66922 | |
| 66923 | /* If the P3 value could not be converted into an integer without |
| 66924 | ** loss of information, then special processing is required... */ |
| 66925 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 66926 | if( (pIn3->flags & MEM_Real)==0 ){ |
| @@ -66949,105 +66931,105 @@ | |
| 66931 | } |
| 66932 | /* If we reach this point, then the P3 value must be a floating |
| 66933 | ** point number. */ |
| 66934 | assert( (pIn3->flags & MEM_Real)!=0 ); |
| 66935 | |
| 66936 | if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ |
| 66937 | /* The P3 value is too large in magnitude to be expressed as an |
| 66938 | ** integer. */ |
| 66939 | u.ba.res = 1; |
| 66940 | if( pIn3->r<0 ){ |
| 66941 | if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); |
| 66942 | rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); |
| 66943 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66944 | } |
| 66945 | }else{ |
| 66946 | if( u.ba.oc<=OP_SeekLe ){ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); |
| 66947 | rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); |
| 66948 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66949 | } |
| 66950 | } |
| 66951 | if( u.ba.res ){ |
| 66952 | pc = pOp->p2 - 1; |
| 66953 | } |
| 66954 | break; |
| 66955 | }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ |
| 66956 | /* Use the ceiling() function to convert real->int */ |
| 66957 | if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; |
| 66958 | }else{ |
| 66959 | /* Use the floor() function to convert real->int */ |
| 66960 | assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); |
| 66961 | if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; |
| 66962 | } |
| 66963 | } |
| 66964 | rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); |
| 66965 | if( rc!=SQLITE_OK ){ |
| 66966 | goto abort_due_to_error; |
| 66967 | } |
| 66968 | if( u.ba.res==0 ){ |
| 66969 | u.ba.pC->rowidIsValid = 1; |
| 66970 | u.ba.pC->lastRowid = u.ba.iKey; |
| 66971 | } |
| 66972 | }else{ |
| 66973 | u.ba.nField = pOp->p4.i; |
| 66974 | assert( pOp->p4type==P4_INT32 ); |
| 66975 | assert( u.ba.nField>0 ); |
| 66976 | u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; |
| 66977 | u.ba.r.nField = (u16)u.ba.nField; |
| 66978 | |
| 66979 | /* The next line of code computes as follows, only faster: |
| 66980 | ** if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ |
| 66981 | ** u.ba.r.flags = UNPACKED_INCRKEY; |
| 66982 | ** }else{ |
| 66983 | ** u.ba.r.flags = 0; |
| 66984 | ** } |
| 66985 | */ |
| 66986 | u.ba.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.ba.oc - OP_SeekLt))); |
| 66987 | assert( u.ba.oc!=OP_SeekGt || u.ba.r.flags==UNPACKED_INCRKEY ); |
| 66988 | assert( u.ba.oc!=OP_SeekLe || u.ba.r.flags==UNPACKED_INCRKEY ); |
| 66989 | assert( u.ba.oc!=OP_SeekGe || u.ba.r.flags==0 ); |
| 66990 | assert( u.ba.oc!=OP_SeekLt || u.ba.r.flags==0 ); |
| 66991 | |
| 66992 | u.ba.r.aMem = &aMem[pOp->p3]; |
| 66993 | #ifdef SQLITE_DEBUG |
| 66994 | { int i; for(i=0; i<u.ba.r.nField; i++) assert( memIsValid(&u.ba.r.aMem[i]) ); } |
| 66995 | #endif |
| 66996 | ExpandBlob(u.ba.r.aMem); |
| 66997 | rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); |
| 66998 | if( rc!=SQLITE_OK ){ |
| 66999 | goto abort_due_to_error; |
| 67000 | } |
| 67001 | u.ba.pC->rowidIsValid = 0; |
| 67002 | } |
| 67003 | u.ba.pC->deferredMoveto = 0; |
| 67004 | u.ba.pC->cacheStatus = CACHE_STALE; |
| 67005 | #ifdef SQLITE_TEST |
| 67006 | sqlite3_search_count++; |
| 67007 | #endif |
| 67008 | if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); |
| 67009 | if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ |
| 67010 | rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); |
| 67011 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67012 | u.ba.pC->rowidIsValid = 0; |
| 67013 | }else{ |
| 67014 | u.ba.res = 0; |
| 67015 | } |
| 67016 | }else{ |
| 67017 | assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); |
| 67018 | if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ |
| 67019 | rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); |
| 67020 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67021 | u.ba.pC->rowidIsValid = 0; |
| 67022 | }else{ |
| 67023 | /* u.ba.res might be negative because the table is empty. Check to |
| 67024 | ** see if this is the case. |
| 67025 | */ |
| 67026 | u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); |
| 67027 | } |
| 67028 | } |
| 67029 | assert( pOp->p2>0 ); |
| 67030 | if( u.ba.res ){ |
| 67031 | pc = pOp->p2 - 1; |
| 67032 | } |
| 67033 | }else{ |
| 67034 | /* This happens when attempting to open the sqlite3_master table |
| 67035 | ** for read access returns SQLITE_EMPTY. In this case always |
| @@ -67066,24 +67048,24 @@ | |
| 67048 | ** This is actually a deferred seek. Nothing actually happens until |
| 67049 | ** the cursor is used to read a record. That way, if no reads |
| 67050 | ** occur, no unnecessary I/O happens. |
| 67051 | */ |
| 67052 | case OP_Seek: { /* in2 */ |
| 67053 | #if 0 /* local variables moved into u.bb */ |
| 67054 | VdbeCursor *pC; |
| 67055 | #endif /* local variables moved into u.bb */ |
| 67056 | |
| 67057 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67058 | u.bb.pC = p->apCsr[pOp->p1]; |
| 67059 | assert( u.bb.pC!=0 ); |
| 67060 | if( ALWAYS(u.bb.pC->pCursor!=0) ){ |
| 67061 | assert( u.bb.pC->isTable ); |
| 67062 | u.bb.pC->nullRow = 0; |
| 67063 | pIn2 = &aMem[pOp->p2]; |
| 67064 | u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67065 | u.bb.pC->rowidIsValid = 0; |
| 67066 | u.bb.pC->deferredMoveto = 1; |
| 67067 | } |
| 67068 | break; |
| 67069 | } |
| 67070 | |
| 67071 | |
| @@ -67111,66 +67093,66 @@ | |
| 67093 | ** |
| 67094 | ** See also: Found, NotExists, IsUnique |
| 67095 | */ |
| 67096 | case OP_NotFound: /* jump, in3 */ |
| 67097 | case OP_Found: { /* jump, in3 */ |
| 67098 | #if 0 /* local variables moved into u.bc */ |
| 67099 | int alreadyExists; |
| 67100 | VdbeCursor *pC; |
| 67101 | int res; |
| 67102 | UnpackedRecord *pIdxKey; |
| 67103 | UnpackedRecord r; |
| 67104 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 67105 | #endif /* local variables moved into u.bc */ |
| 67106 | |
| 67107 | #ifdef SQLITE_TEST |
| 67108 | sqlite3_found_count++; |
| 67109 | #endif |
| 67110 | |
| 67111 | u.bc.alreadyExists = 0; |
| 67112 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67113 | assert( pOp->p4type==P4_INT32 ); |
| 67114 | u.bc.pC = p->apCsr[pOp->p1]; |
| 67115 | assert( u.bc.pC!=0 ); |
| 67116 | pIn3 = &aMem[pOp->p3]; |
| 67117 | if( ALWAYS(u.bc.pC->pCursor!=0) ){ |
| 67118 | |
| 67119 | assert( u.bc.pC->isTable==0 ); |
| 67120 | if( pOp->p4.i>0 ){ |
| 67121 | u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; |
| 67122 | u.bc.r.nField = (u16)pOp->p4.i; |
| 67123 | u.bc.r.aMem = pIn3; |
| 67124 | #ifdef SQLITE_DEBUG |
| 67125 | { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } |
| 67126 | #endif |
| 67127 | u.bc.r.flags = UNPACKED_PREFIX_MATCH; |
| 67128 | u.bc.pIdxKey = &u.bc.r; |
| 67129 | }else{ |
| 67130 | assert( pIn3->flags & MEM_Blob ); |
| 67131 | assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ |
| 67132 | u.bc.pIdxKey = sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, |
| 67133 | u.bc.aTempRec, sizeof(u.bc.aTempRec)); |
| 67134 | if( u.bc.pIdxKey==0 ){ |
| 67135 | goto no_mem; |
| 67136 | } |
| 67137 | u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 67138 | } |
| 67139 | rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); |
| 67140 | if( pOp->p4.i==0 ){ |
| 67141 | sqlite3VdbeDeleteUnpackedRecord(u.bc.pIdxKey); |
| 67142 | } |
| 67143 | if( rc!=SQLITE_OK ){ |
| 67144 | break; |
| 67145 | } |
| 67146 | u.bc.alreadyExists = (u.bc.res==0); |
| 67147 | u.bc.pC->deferredMoveto = 0; |
| 67148 | u.bc.pC->cacheStatus = CACHE_STALE; |
| 67149 | } |
| 67150 | if( pOp->opcode==OP_Found ){ |
| 67151 | if( u.bc.alreadyExists ) pc = pOp->p2 - 1; |
| 67152 | }else{ |
| 67153 | if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; |
| 67154 | } |
| 67155 | break; |
| 67156 | } |
| 67157 | |
| 67158 | /* Opcode: IsUnique P1 P2 P3 P4 * |
| @@ -67198,67 +67180,67 @@ | |
| 67180 | ** instruction. |
| 67181 | ** |
| 67182 | ** See also: NotFound, NotExists, Found |
| 67183 | */ |
| 67184 | case OP_IsUnique: { /* jump, in3 */ |
| 67185 | #if 0 /* local variables moved into u.bd */ |
| 67186 | u16 ii; |
| 67187 | VdbeCursor *pCx; |
| 67188 | BtCursor *pCrsr; |
| 67189 | u16 nField; |
| 67190 | Mem *aMx; |
| 67191 | UnpackedRecord r; /* B-Tree index search key */ |
| 67192 | i64 R; /* Rowid stored in register P3 */ |
| 67193 | #endif /* local variables moved into u.bd */ |
| 67194 | |
| 67195 | pIn3 = &aMem[pOp->p3]; |
| 67196 | u.bd.aMx = &aMem[pOp->p4.i]; |
| 67197 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 67198 | assert( pOp->p4type==P4_INT32 ); |
| 67199 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 67200 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67201 | |
| 67202 | /* Find the index cursor. */ |
| 67203 | u.bd.pCx = p->apCsr[pOp->p1]; |
| 67204 | assert( u.bd.pCx->deferredMoveto==0 ); |
| 67205 | u.bd.pCx->seekResult = 0; |
| 67206 | u.bd.pCx->cacheStatus = CACHE_STALE; |
| 67207 | u.bd.pCrsr = u.bd.pCx->pCursor; |
| 67208 | |
| 67209 | /* If any of the values are NULL, take the jump. */ |
| 67210 | u.bd.nField = u.bd.pCx->pKeyInfo->nField; |
| 67211 | for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ |
| 67212 | if( u.bd.aMx[u.bd.ii].flags & MEM_Null ){ |
| 67213 | pc = pOp->p2 - 1; |
| 67214 | u.bd.pCrsr = 0; |
| 67215 | break; |
| 67216 | } |
| 67217 | } |
| 67218 | assert( (u.bd.aMx[u.bd.nField].flags & MEM_Null)==0 ); |
| 67219 | |
| 67220 | if( u.bd.pCrsr!=0 ){ |
| 67221 | /* Populate the index search key. */ |
| 67222 | u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; |
| 67223 | u.bd.r.nField = u.bd.nField + 1; |
| 67224 | u.bd.r.flags = UNPACKED_PREFIX_SEARCH; |
| 67225 | u.bd.r.aMem = u.bd.aMx; |
| 67226 | #ifdef SQLITE_DEBUG |
| 67227 | { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } |
| 67228 | #endif |
| 67229 | |
| 67230 | /* Extract the value of u.bd.R from register P3. */ |
| 67231 | sqlite3VdbeMemIntegerify(pIn3); |
| 67232 | u.bd.R = pIn3->u.i; |
| 67233 | |
| 67234 | /* Search the B-Tree index. If no conflicting record is found, jump |
| 67235 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
| 67236 | ** register P3 and fall through to the next instruction. */ |
| 67237 | rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); |
| 67238 | if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ |
| 67239 | pc = pOp->p2 - 1; |
| 67240 | }else{ |
| 67241 | pIn3->u.i = u.bd.r.rowid; |
| 67242 | } |
| 67243 | } |
| 67244 | break; |
| 67245 | } |
| 67246 | |
| @@ -67275,46 +67257,46 @@ | |
| 67257 | ** P1 is an index. |
| 67258 | ** |
| 67259 | ** See also: Found, NotFound, IsUnique |
| 67260 | */ |
| 67261 | case OP_NotExists: { /* jump, in3 */ |
| 67262 | #if 0 /* local variables moved into u.be */ |
| 67263 | VdbeCursor *pC; |
| 67264 | BtCursor *pCrsr; |
| 67265 | int res; |
| 67266 | u64 iKey; |
| 67267 | #endif /* local variables moved into u.be */ |
| 67268 | |
| 67269 | pIn3 = &aMem[pOp->p3]; |
| 67270 | assert( pIn3->flags & MEM_Int ); |
| 67271 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67272 | u.be.pC = p->apCsr[pOp->p1]; |
| 67273 | assert( u.be.pC!=0 ); |
| 67274 | assert( u.be.pC->isTable ); |
| 67275 | assert( u.be.pC->pseudoTableReg==0 ); |
| 67276 | u.be.pCrsr = u.be.pC->pCursor; |
| 67277 | if( ALWAYS(u.be.pCrsr!=0) ){ |
| 67278 | u.be.res = 0; |
| 67279 | u.be.iKey = pIn3->u.i; |
| 67280 | rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); |
| 67281 | u.be.pC->lastRowid = pIn3->u.i; |
| 67282 | u.be.pC->rowidIsValid = u.be.res==0 ?1:0; |
| 67283 | u.be.pC->nullRow = 0; |
| 67284 | u.be.pC->cacheStatus = CACHE_STALE; |
| 67285 | u.be.pC->deferredMoveto = 0; |
| 67286 | if( u.be.res!=0 ){ |
| 67287 | pc = pOp->p2 - 1; |
| 67288 | assert( u.be.pC->rowidIsValid==0 ); |
| 67289 | } |
| 67290 | u.be.pC->seekResult = u.be.res; |
| 67291 | }else{ |
| 67292 | /* This happens when an attempt to open a read cursor on the |
| 67293 | ** sqlite_master table returns SQLITE_EMPTY. |
| 67294 | */ |
| 67295 | pc = pOp->p2 - 1; |
| 67296 | assert( u.be.pC->rowidIsValid==0 ); |
| 67297 | u.be.pC->seekResult = 0; |
| 67298 | } |
| 67299 | break; |
| 67300 | } |
| 67301 | |
| 67302 | /* Opcode: Sequence P1 P2 * * * |
| @@ -67345,25 +67327,25 @@ | |
| 67327 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 67328 | ** generated record number. This P3 mechanism is used to help implement the |
| 67329 | ** AUTOINCREMENT feature. |
| 67330 | */ |
| 67331 | case OP_NewRowid: { /* out2-prerelease */ |
| 67332 | #if 0 /* local variables moved into u.bf */ |
| 67333 | i64 v; /* The new rowid */ |
| 67334 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 67335 | int res; /* Result of an sqlite3BtreeLast() */ |
| 67336 | int cnt; /* Counter to limit the number of searches */ |
| 67337 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 67338 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 67339 | #endif /* local variables moved into u.bf */ |
| 67340 | |
| 67341 | u.bf.v = 0; |
| 67342 | u.bf.res = 0; |
| 67343 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67344 | u.bf.pC = p->apCsr[pOp->p1]; |
| 67345 | assert( u.bf.pC!=0 ); |
| 67346 | if( NEVER(u.bf.pC->pCursor==0) ){ |
| 67347 | /* The zero initialization above is all that is needed */ |
| 67348 | }else{ |
| 67349 | /* The next rowid or record number (different terms for the same |
| 67350 | ** thing) is obtained in a two-step algorithm. |
| 67351 | ** |
| @@ -67375,11 +67357,11 @@ | |
| 67357 | ** The second algorithm is to select a rowid at random and see if |
| 67358 | ** it already exists in the table. If it does not exist, we have |
| 67359 | ** succeeded. If the random rowid does exist, we select a new one |
| 67360 | ** and try again, up to 100 times. |
| 67361 | */ |
| 67362 | assert( u.bf.pC->isTable ); |
| 67363 | |
| 67364 | #ifdef SQLITE_32BIT_ROWID |
| 67365 | # define MAX_ROWID 0x7fffffff |
| 67366 | #else |
| 67367 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| @@ -67387,101 +67369,101 @@ | |
| 67369 | ** to provide the constant while making all compilers happy. |
| 67370 | */ |
| 67371 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 67372 | #endif |
| 67373 | |
| 67374 | if( !u.bf.pC->useRandomRowid ){ |
| 67375 | u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); |
| 67376 | if( u.bf.v==0 ){ |
| 67377 | rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); |
| 67378 | if( rc!=SQLITE_OK ){ |
| 67379 | goto abort_due_to_error; |
| 67380 | } |
| 67381 | if( u.bf.res ){ |
| 67382 | u.bf.v = 1; /* IMP: R-61914-48074 */ |
| 67383 | }else{ |
| 67384 | assert( sqlite3BtreeCursorIsValid(u.bf.pC->pCursor) ); |
| 67385 | rc = sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); |
| 67386 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 67387 | if( u.bf.v==MAX_ROWID ){ |
| 67388 | u.bf.pC->useRandomRowid = 1; |
| 67389 | }else{ |
| 67390 | u.bf.v++; /* IMP: R-29538-34987 */ |
| 67391 | } |
| 67392 | } |
| 67393 | } |
| 67394 | |
| 67395 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 67396 | if( pOp->p3 ){ |
| 67397 | /* Assert that P3 is a valid memory cell. */ |
| 67398 | assert( pOp->p3>0 ); |
| 67399 | if( p->pFrame ){ |
| 67400 | for(u.bf.pFrame=p->pFrame; u.bf.pFrame->pParent; u.bf.pFrame=u.bf.pFrame->pParent); |
| 67401 | /* Assert that P3 is a valid memory cell. */ |
| 67402 | assert( pOp->p3<=u.bf.pFrame->nMem ); |
| 67403 | u.bf.pMem = &u.bf.pFrame->aMem[pOp->p3]; |
| 67404 | }else{ |
| 67405 | /* Assert that P3 is a valid memory cell. */ |
| 67406 | assert( pOp->p3<=p->nMem ); |
| 67407 | u.bf.pMem = &aMem[pOp->p3]; |
| 67408 | memAboutToChange(p, u.bf.pMem); |
| 67409 | } |
| 67410 | assert( memIsValid(u.bf.pMem) ); |
| 67411 | |
| 67412 | REGISTER_TRACE(pOp->p3, u.bf.pMem); |
| 67413 | sqlite3VdbeMemIntegerify(u.bf.pMem); |
| 67414 | assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 67415 | if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ |
| 67416 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 67417 | goto abort_due_to_error; |
| 67418 | } |
| 67419 | if( u.bf.v<u.bf.pMem->u.i+1 ){ |
| 67420 | u.bf.v = u.bf.pMem->u.i + 1; |
| 67421 | } |
| 67422 | u.bf.pMem->u.i = u.bf.v; |
| 67423 | } |
| 67424 | #endif |
| 67425 | |
| 67426 | sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); |
| 67427 | } |
| 67428 | if( u.bf.pC->useRandomRowid ){ |
| 67429 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 67430 | ** largest possible integer (9223372036854775807) then the database |
| 67431 | ** engine starts picking positive candidate ROWIDs at random until |
| 67432 | ** it finds one that is not previously used. */ |
| 67433 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 67434 | ** an AUTOINCREMENT table. */ |
| 67435 | /* on the first attempt, simply do one more than previous */ |
| 67436 | u.bf.v = lastRowid; |
| 67437 | u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67438 | u.bf.v++; /* ensure non-zero */ |
| 67439 | u.bf.cnt = 0; |
| 67440 | while( ((rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, |
| 67441 | 0, &u.bf.res))==SQLITE_OK) |
| 67442 | && (u.bf.res==0) |
| 67443 | && (++u.bf.cnt<100)){ |
| 67444 | /* collision - try another random rowid */ |
| 67445 | sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); |
| 67446 | if( u.bf.cnt<5 ){ |
| 67447 | /* try "small" random rowids for the initial attempts */ |
| 67448 | u.bf.v &= 0xffffff; |
| 67449 | }else{ |
| 67450 | u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67451 | } |
| 67452 | u.bf.v++; /* ensure non-zero */ |
| 67453 | } |
| 67454 | if( rc==SQLITE_OK && u.bf.res==0 ){ |
| 67455 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 67456 | goto abort_due_to_error; |
| 67457 | } |
| 67458 | assert( u.bf.v>0 ); /* EV: R-40812-03570 */ |
| 67459 | } |
| 67460 | u.bf.pC->rowidIsValid = 0; |
| 67461 | u.bf.pC->deferredMoveto = 0; |
| 67462 | u.bf.pC->cacheStatus = CACHE_STALE; |
| 67463 | } |
| 67464 | pOut->u.i = u.bf.v; |
| 67465 | break; |
| 67466 | } |
| 67467 | |
| 67468 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 67469 | ** |
| @@ -67527,74 +67509,74 @@ | |
| 67509 | ** This works exactly like OP_Insert except that the key is the |
| 67510 | ** integer value P3, not the value of the integer stored in register P3. |
| 67511 | */ |
| 67512 | case OP_Insert: |
| 67513 | case OP_InsertInt: { |
| 67514 | #if 0 /* local variables moved into u.bg */ |
| 67515 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 67516 | Mem *pKey; /* MEM cell holding key for the record */ |
| 67517 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 67518 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 67519 | int nZero; /* Number of zero-bytes to append */ |
| 67520 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 67521 | const char *zDb; /* database name - used by the update hook */ |
| 67522 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 67523 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 67524 | #endif /* local variables moved into u.bg */ |
| 67525 | |
| 67526 | u.bg.pData = &aMem[pOp->p2]; |
| 67527 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67528 | assert( memIsValid(u.bg.pData) ); |
| 67529 | u.bg.pC = p->apCsr[pOp->p1]; |
| 67530 | assert( u.bg.pC!=0 ); |
| 67531 | assert( u.bg.pC->pCursor!=0 ); |
| 67532 | assert( u.bg.pC->pseudoTableReg==0 ); |
| 67533 | assert( u.bg.pC->isTable ); |
| 67534 | REGISTER_TRACE(pOp->p2, u.bg.pData); |
| 67535 | |
| 67536 | if( pOp->opcode==OP_Insert ){ |
| 67537 | u.bg.pKey = &aMem[pOp->p3]; |
| 67538 | assert( u.bg.pKey->flags & MEM_Int ); |
| 67539 | assert( memIsValid(u.bg.pKey) ); |
| 67540 | REGISTER_TRACE(pOp->p3, u.bg.pKey); |
| 67541 | u.bg.iKey = u.bg.pKey->u.i; |
| 67542 | }else{ |
| 67543 | assert( pOp->opcode==OP_InsertInt ); |
| 67544 | u.bg.iKey = pOp->p3; |
| 67545 | } |
| 67546 | |
| 67547 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 67548 | if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey; |
| 67549 | if( u.bg.pData->flags & MEM_Null ){ |
| 67550 | u.bg.pData->z = 0; |
| 67551 | u.bg.pData->n = 0; |
| 67552 | }else{ |
| 67553 | assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); |
| 67554 | } |
| 67555 | u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); |
| 67556 | if( u.bg.pData->flags & MEM_Zero ){ |
| 67557 | u.bg.nZero = u.bg.pData->u.nZero; |
| 67558 | }else{ |
| 67559 | u.bg.nZero = 0; |
| 67560 | } |
| 67561 | sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); |
| 67562 | rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, |
| 67563 | u.bg.pData->z, u.bg.pData->n, u.bg.nZero, |
| 67564 | pOp->p5 & OPFLAG_APPEND, u.bg.seekResult |
| 67565 | ); |
| 67566 | u.bg.pC->rowidIsValid = 0; |
| 67567 | u.bg.pC->deferredMoveto = 0; |
| 67568 | u.bg.pC->cacheStatus = CACHE_STALE; |
| 67569 | |
| 67570 | /* Invoke the update-hook if required. */ |
| 67571 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67572 | u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; |
| 67573 | u.bg.zTbl = pOp->p4.z; |
| 67574 | u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 67575 | assert( u.bg.pC->isTable ); |
| 67576 | db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); |
| 67577 | assert( u.bg.pC->iDb>=0 ); |
| 67578 | } |
| 67579 | break; |
| 67580 | } |
| 67581 | |
| 67582 | /* Opcode: Delete P1 P2 * P4 * |
| @@ -67616,51 +67598,51 @@ | |
| 67598 | ** pointing to. The update hook will be invoked, if it exists. |
| 67599 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 67600 | ** using OP_NotFound prior to invoking this opcode. |
| 67601 | */ |
| 67602 | case OP_Delete: { |
| 67603 | #if 0 /* local variables moved into u.bh */ |
| 67604 | i64 iKey; |
| 67605 | VdbeCursor *pC; |
| 67606 | #endif /* local variables moved into u.bh */ |
| 67607 | |
| 67608 | u.bh.iKey = 0; |
| 67609 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67610 | u.bh.pC = p->apCsr[pOp->p1]; |
| 67611 | assert( u.bh.pC!=0 ); |
| 67612 | assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 67613 | |
| 67614 | /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the |
| 67615 | ** row being deleted. |
| 67616 | */ |
| 67617 | if( db->xUpdateCallback && pOp->p4.z ){ |
| 67618 | assert( u.bh.pC->isTable ); |
| 67619 | assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 67620 | u.bh.iKey = u.bh.pC->lastRowid; |
| 67621 | } |
| 67622 | |
| 67623 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 67624 | ** OP_Column on the same table without any intervening operations that |
| 67625 | ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing |
| 67626 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 67627 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 67628 | ** to guard against future changes to the code generator. |
| 67629 | **/ |
| 67630 | assert( u.bh.pC->deferredMoveto==0 ); |
| 67631 | rc = sqlite3VdbeCursorMoveto(u.bh.pC); |
| 67632 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67633 | |
| 67634 | sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); |
| 67635 | rc = sqlite3BtreeDelete(u.bh.pC->pCursor); |
| 67636 | u.bh.pC->cacheStatus = CACHE_STALE; |
| 67637 | |
| 67638 | /* Invoke the update-hook if required. */ |
| 67639 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67640 | const char *zDb = db->aDb[u.bh.pC->iDb].zName; |
| 67641 | const char *zTbl = pOp->p4.z; |
| 67642 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); |
| 67643 | assert( u.bh.pC->iDb>=0 ); |
| 67644 | } |
| 67645 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 67646 | break; |
| 67647 | } |
| 67648 | /* Opcode: ResetCount * * * * * |
| @@ -67673,10 +67655,53 @@ | |
| 67655 | case OP_ResetCount: { |
| 67656 | sqlite3VdbeSetChanges(db, p->nChange); |
| 67657 | p->nChange = 0; |
| 67658 | break; |
| 67659 | } |
| 67660 | |
| 67661 | /* Opcode: SorterCompare P1 P2 P3 |
| 67662 | ** |
| 67663 | ** P1 is a sorter cursor. This instruction compares the record blob in |
| 67664 | ** register P3 with the entry that the sorter cursor currently points to. |
| 67665 | ** If, excluding the rowid fields at the end, the two records are a match, |
| 67666 | ** fall through to the next instruction. Otherwise, jump to instruction P2. |
| 67667 | */ |
| 67668 | case OP_SorterCompare: { |
| 67669 | #if 0 /* local variables moved into u.bi */ |
| 67670 | VdbeCursor *pC; |
| 67671 | int res; |
| 67672 | #endif /* local variables moved into u.bi */ |
| 67673 | |
| 67674 | u.bi.pC = p->apCsr[pOp->p1]; |
| 67675 | assert( isSorter(u.bi.pC) ); |
| 67676 | pIn3 = &aMem[pOp->p3]; |
| 67677 | rc = sqlite3VdbeSorterCompare(u.bi.pC, pIn3, &u.bi.res); |
| 67678 | if( u.bi.res ){ |
| 67679 | pc = pOp->p2-1; |
| 67680 | } |
| 67681 | break; |
| 67682 | }; |
| 67683 | |
| 67684 | /* Opcode: SorterData P1 P2 * * * |
| 67685 | ** |
| 67686 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 67687 | */ |
| 67688 | case OP_SorterData: { |
| 67689 | #if 0 /* local variables moved into u.bj */ |
| 67690 | VdbeCursor *pC; |
| 67691 | #endif /* local variables moved into u.bj */ |
| 67692 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 67693 | pOut = &aMem[pOp->p2]; |
| 67694 | u.bj.pC = p->apCsr[pOp->p1]; |
| 67695 | assert( u.bj.pC->isSorter ); |
| 67696 | rc = sqlite3VdbeSorterRowkey(u.bj.pC, pOut); |
| 67697 | #else |
| 67698 | pOp->opcode = OP_RowKey; |
| 67699 | pc--; |
| 67700 | #endif |
| 67701 | break; |
| 67702 | } |
| 67703 | |
| 67704 | /* Opcode: RowData P1 P2 * * * |
| 67705 | ** |
| 67706 | ** Write into register P2 the complete row data for cursor P1. |
| 67707 | ** There is no interpretation of the data. |
| @@ -67696,72 +67721,67 @@ | |
| 67721 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 67722 | ** of a real table, not a pseudo-table. |
| 67723 | */ |
| 67724 | case OP_RowKey: |
| 67725 | case OP_RowData: { |
| 67726 | #if 0 /* local variables moved into u.bk */ |
| 67727 | VdbeCursor *pC; |
| 67728 | BtCursor *pCrsr; |
| 67729 | u32 n; |
| 67730 | i64 n64; |
| 67731 | #endif /* local variables moved into u.bk */ |
| 67732 | |
| 67733 | pOut = &aMem[pOp->p2]; |
| 67734 | memAboutToChange(p, pOut); |
| 67735 | |
| 67736 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 67737 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67738 | u.bk.pC = p->apCsr[pOp->p1]; |
| 67739 | assert( u.bk.pC->isSorter==0 ); |
| 67740 | assert( u.bk.pC->isTable || pOp->opcode!=OP_RowData ); |
| 67741 | assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); |
| 67742 | assert( u.bk.pC!=0 ); |
| 67743 | assert( u.bk.pC->nullRow==0 ); |
| 67744 | assert( u.bk.pC->pseudoTableReg==0 ); |
| 67745 | assert( !u.bk.pC->isSorter ); |
| 67746 | assert( u.bk.pC->pCursor!=0 ); |
| 67747 | u.bk.pCrsr = u.bk.pC->pCursor; |
| 67748 | assert( sqlite3BtreeCursorIsValid(u.bk.pCrsr) ); |
| 67749 | |
| 67750 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 67751 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 67752 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 67753 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 67754 | */ |
| 67755 | assert( u.bk.pC->deferredMoveto==0 ); |
| 67756 | rc = sqlite3VdbeCursorMoveto(u.bk.pC); |
| 67757 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67758 | |
| 67759 | if( u.bk.pC->isIndex ){ |
| 67760 | assert( !u.bk.pC->isTable ); |
| 67761 | rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); |
| 67762 | assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 67763 | if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67764 | goto too_big; |
| 67765 | } |
| 67766 | u.bk.n = (u32)u.bk.n64; |
| 67767 | }else{ |
| 67768 | rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); |
| 67769 | assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 67770 | if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67771 | goto too_big; |
| 67772 | } |
| 67773 | } |
| 67774 | if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ |
| 67775 | goto no_mem; |
| 67776 | } |
| 67777 | pOut->n = u.bk.n; |
| 67778 | MemSetTypeFlag(pOut, MEM_Blob); |
| 67779 | if( u.bk.pC->isIndex ){ |
| 67780 | rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); |
| 67781 | }else{ |
| 67782 | rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); |
| 67783 | } |
| 67784 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 67785 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67786 | break; |
| 67787 | } |
| @@ -67774,46 +67794,46 @@ | |
| 67794 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 67795 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 67796 | ** one opcode now works for both table types. |
| 67797 | */ |
| 67798 | case OP_Rowid: { /* out2-prerelease */ |
| 67799 | #if 0 /* local variables moved into u.bl */ |
| 67800 | VdbeCursor *pC; |
| 67801 | i64 v; |
| 67802 | sqlite3_vtab *pVtab; |
| 67803 | const sqlite3_module *pModule; |
| 67804 | #endif /* local variables moved into u.bl */ |
| 67805 | |
| 67806 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67807 | u.bl.pC = p->apCsr[pOp->p1]; |
| 67808 | assert( u.bl.pC!=0 ); |
| 67809 | assert( u.bl.pC->pseudoTableReg==0 ); |
| 67810 | if( u.bl.pC->nullRow ){ |
| 67811 | pOut->flags = MEM_Null; |
| 67812 | break; |
| 67813 | }else if( u.bl.pC->deferredMoveto ){ |
| 67814 | u.bl.v = u.bl.pC->movetoTarget; |
| 67815 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 67816 | }else if( u.bl.pC->pVtabCursor ){ |
| 67817 | u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; |
| 67818 | u.bl.pModule = u.bl.pVtab->pModule; |
| 67819 | assert( u.bl.pModule->xRowid ); |
| 67820 | rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); |
| 67821 | importVtabErrMsg(p, u.bl.pVtab); |
| 67822 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 67823 | }else{ |
| 67824 | assert( u.bl.pC->pCursor!=0 ); |
| 67825 | rc = sqlite3VdbeCursorMoveto(u.bl.pC); |
| 67826 | if( rc ) goto abort_due_to_error; |
| 67827 | if( u.bl.pC->rowidIsValid ){ |
| 67828 | u.bl.v = u.bl.pC->lastRowid; |
| 67829 | }else{ |
| 67830 | rc = sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); |
| 67831 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 67832 | } |
| 67833 | } |
| 67834 | pOut->u.i = u.bl.v; |
| 67835 | break; |
| 67836 | } |
| 67837 | |
| 67838 | /* Opcode: NullRow P1 * * * * |
| 67839 | ** |
| @@ -67820,22 +67840,22 @@ | |
| 67840 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 67841 | ** that occur while the cursor is on the null row will always |
| 67842 | ** write a NULL. |
| 67843 | */ |
| 67844 | case OP_NullRow: { |
| 67845 | #if 0 /* local variables moved into u.bm */ |
| 67846 | VdbeCursor *pC; |
| 67847 | #endif /* local variables moved into u.bm */ |
| 67848 | |
| 67849 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67850 | u.bm.pC = p->apCsr[pOp->p1]; |
| 67851 | assert( u.bm.pC!=0 ); |
| 67852 | u.bm.pC->nullRow = 1; |
| 67853 | u.bm.pC->rowidIsValid = 0; |
| 67854 | assert( u.bm.pC->pCursor || u.bm.pC->pVtabCursor ); |
| 67855 | if( u.bm.pC->pCursor ){ |
| 67856 | sqlite3BtreeClearCursor(u.bm.pC->pCursor); |
| 67857 | } |
| 67858 | break; |
| 67859 | } |
| 67860 | |
| 67861 | /* Opcode: Last P1 P2 * * * |
| @@ -67845,30 +67865,30 @@ | |
| 67865 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67866 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67867 | ** to the following instruction. |
| 67868 | */ |
| 67869 | case OP_Last: { /* jump */ |
| 67870 | #if 0 /* local variables moved into u.bn */ |
| 67871 | VdbeCursor *pC; |
| 67872 | BtCursor *pCrsr; |
| 67873 | int res; |
| 67874 | #endif /* local variables moved into u.bn */ |
| 67875 | |
| 67876 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67877 | u.bn.pC = p->apCsr[pOp->p1]; |
| 67878 | assert( u.bn.pC!=0 ); |
| 67879 | u.bn.pCrsr = u.bn.pC->pCursor; |
| 67880 | if( NEVER(u.bn.pCrsr==0) ){ |
| 67881 | u.bn.res = 1; |
| 67882 | }else{ |
| 67883 | rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); |
| 67884 | } |
| 67885 | u.bn.pC->nullRow = (u8)u.bn.res; |
| 67886 | u.bn.pC->deferredMoveto = 0; |
| 67887 | u.bn.pC->rowidIsValid = 0; |
| 67888 | u.bn.pC->cacheStatus = CACHE_STALE; |
| 67889 | if( pOp->p2>0 && u.bn.res ){ |
| 67890 | pc = pOp->p2 - 1; |
| 67891 | } |
| 67892 | break; |
| 67893 | } |
| 67894 | |
| @@ -67883,10 +67903,14 @@ | |
| 67903 | ** end. We use the OP_Sort opcode instead of OP_Rewind to do the |
| 67904 | ** rewinding so that the global variable will be incremented and |
| 67905 | ** regression tests can determine whether or not the optimizer is |
| 67906 | ** correctly optimizing out sorts. |
| 67907 | */ |
| 67908 | case OP_SorterSort: /* jump */ |
| 67909 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 67910 | pOp->opcode = OP_Sort; |
| 67911 | #endif |
| 67912 | case OP_Sort: { /* jump */ |
| 67913 | #ifdef SQLITE_TEST |
| 67914 | sqlite3_sort_count++; |
| 67915 | sqlite3_search_count--; |
| 67916 | #endif |
| @@ -67900,34 +67924,35 @@ | |
| 67924 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67925 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67926 | ** to the following instruction. |
| 67927 | */ |
| 67928 | case OP_Rewind: { /* jump */ |
| 67929 | #if 0 /* local variables moved into u.bo */ |
| 67930 | VdbeCursor *pC; |
| 67931 | BtCursor *pCrsr; |
| 67932 | int res; |
| 67933 | #endif /* local variables moved into u.bo */ |
| 67934 | |
| 67935 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67936 | u.bo.pC = p->apCsr[pOp->p1]; |
| 67937 | assert( u.bo.pC!=0 ); |
| 67938 | assert( u.bo.pC->isSorter==(pOp->opcode==OP_SorterSort) ); |
| 67939 | u.bo.res = 1; |
| 67940 | if( isSorter(u.bo.pC) ){ |
| 67941 | rc = sqlite3VdbeSorterRewind(db, u.bo.pC, &u.bo.res); |
| 67942 | }else{ |
| 67943 | u.bo.pCrsr = u.bo.pC->pCursor; |
| 67944 | assert( u.bo.pCrsr ); |
| 67945 | rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); |
| 67946 | u.bo.pC->atFirst = u.bo.res==0 ?1:0; |
| 67947 | u.bo.pC->deferredMoveto = 0; |
| 67948 | u.bo.pC->cacheStatus = CACHE_STALE; |
| 67949 | u.bo.pC->rowidIsValid = 0; |
| 67950 | } |
| 67951 | u.bo.pC->nullRow = (u8)u.bo.res; |
| 67952 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 67953 | if( u.bo.res ){ |
| 67954 | pc = pOp->p2 - 1; |
| 67955 | } |
| 67956 | break; |
| 67957 | } |
| 67958 | |
| @@ -67961,45 +67986,50 @@ | |
| 67986 | ** sqlite3BtreePrevious(). |
| 67987 | ** |
| 67988 | ** If P5 is positive and the jump is taken, then event counter |
| 67989 | ** number P5-1 in the prepared statement is incremented. |
| 67990 | */ |
| 67991 | case OP_SorterNext: /* jump */ |
| 67992 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 67993 | pOp->opcode = OP_Next; |
| 67994 | #endif |
| 67995 | case OP_Prev: /* jump */ |
| 67996 | case OP_Next: { /* jump */ |
| 67997 | #if 0 /* local variables moved into u.bp */ |
| 67998 | VdbeCursor *pC; |
| 67999 | int res; |
| 68000 | #endif /* local variables moved into u.bp */ |
| 68001 | |
| 68002 | CHECK_FOR_INTERRUPT; |
| 68003 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68004 | assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 68005 | u.bp.pC = p->apCsr[pOp->p1]; |
| 68006 | if( u.bp.pC==0 ){ |
| 68007 | break; /* See ticket #2273 */ |
| 68008 | } |
| 68009 | assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 68010 | if( isSorter(u.bp.pC) ){ |
| 68011 | assert( pOp->opcode==OP_SorterNext ); |
| 68012 | rc = sqlite3VdbeSorterNext(db, u.bp.pC, &u.bp.res); |
| 68013 | }else{ |
| 68014 | u.bp.res = 1; |
| 68015 | assert( u.bp.pC->deferredMoveto==0 ); |
| 68016 | assert( u.bp.pC->pCursor ); |
| 68017 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 68018 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 68019 | rc = pOp->p4.xAdvance(u.bp.pC->pCursor, &u.bp.res); |
| 68020 | } |
| 68021 | u.bp.pC->nullRow = (u8)u.bp.res; |
| 68022 | u.bp.pC->cacheStatus = CACHE_STALE; |
| 68023 | if( u.bp.res==0 ){ |
| 68024 | pc = pOp->p2 - 1; |
| 68025 | if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 68026 | #ifdef SQLITE_TEST |
| 68027 | sqlite3_search_count++; |
| 68028 | #endif |
| 68029 | } |
| 68030 | u.bp.pC->rowidIsValid = 0; |
| 68031 | break; |
| 68032 | } |
| 68033 | |
| 68034 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 68035 | ** |
| @@ -68011,38 +68041,44 @@ | |
| 68041 | ** insert is likely to be an append. |
| 68042 | ** |
| 68043 | ** This instruction only works for indices. The equivalent instruction |
| 68044 | ** for tables is OP_Insert. |
| 68045 | */ |
| 68046 | case OP_SorterInsert: /* in2 */ |
| 68047 | #ifdef SQLITE_OMIT_MERGE_SORT |
| 68048 | pOp->opcode = OP_IdxInsert; |
| 68049 | #endif |
| 68050 | case OP_IdxInsert: { /* in2 */ |
| 68051 | #if 0 /* local variables moved into u.bq */ |
| 68052 | VdbeCursor *pC; |
| 68053 | BtCursor *pCrsr; |
| 68054 | int nKey; |
| 68055 | const char *zKey; |
| 68056 | #endif /* local variables moved into u.bq */ |
| 68057 | |
| 68058 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68059 | u.bq.pC = p->apCsr[pOp->p1]; |
| 68060 | assert( u.bq.pC!=0 ); |
| 68061 | assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); |
| 68062 | pIn2 = &aMem[pOp->p2]; |
| 68063 | assert( pIn2->flags & MEM_Blob ); |
| 68064 | u.bq.pCrsr = u.bq.pC->pCursor; |
| 68065 | if( ALWAYS(u.bq.pCrsr!=0) ){ |
| 68066 | assert( u.bq.pC->isTable==0 ); |
| 68067 | rc = ExpandBlob(pIn2); |
| 68068 | if( rc==SQLITE_OK ){ |
| 68069 | if( isSorter(u.bq.pC) ){ |
| 68070 | rc = sqlite3VdbeSorterWrite(db, u.bq.pC, pIn2); |
| 68071 | }else{ |
| 68072 | u.bq.nKey = pIn2->n; |
| 68073 | u.bq.zKey = pIn2->z; |
| 68074 | rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, |
| 68075 | ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) |
| 68076 | ); |
| 68077 | assert( u.bq.pC->deferredMoveto==0 ); |
| 68078 | u.bq.pC->cacheStatus = CACHE_STALE; |
| 68079 | } |
| 68080 | } |
| 68081 | } |
| 68082 | break; |
| 68083 | } |
| 68084 | |
| @@ -68051,37 +68087,37 @@ | |
| 68087 | ** The content of P3 registers starting at register P2 form |
| 68088 | ** an unpacked index key. This opcode removes that entry from the |
| 68089 | ** index opened by cursor P1. |
| 68090 | */ |
| 68091 | case OP_IdxDelete: { |
| 68092 | #if 0 /* local variables moved into u.br */ |
| 68093 | VdbeCursor *pC; |
| 68094 | BtCursor *pCrsr; |
| 68095 | int res; |
| 68096 | UnpackedRecord r; |
| 68097 | #endif /* local variables moved into u.br */ |
| 68098 | |
| 68099 | assert( pOp->p3>0 ); |
| 68100 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 68101 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68102 | u.br.pC = p->apCsr[pOp->p1]; |
| 68103 | assert( u.br.pC!=0 ); |
| 68104 | u.br.pCrsr = u.br.pC->pCursor; |
| 68105 | if( ALWAYS(u.br.pCrsr!=0) ){ |
| 68106 | u.br.r.pKeyInfo = u.br.pC->pKeyInfo; |
| 68107 | u.br.r.nField = (u16)pOp->p3; |
| 68108 | u.br.r.flags = 0; |
| 68109 | u.br.r.aMem = &aMem[pOp->p2]; |
| 68110 | #ifdef SQLITE_DEBUG |
| 68111 | { int i; for(i=0; i<u.br.r.nField; i++) assert( memIsValid(&u.br.r.aMem[i]) ); } |
| 68112 | #endif |
| 68113 | rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &u.br.r, 0, 0, &u.br.res); |
| 68114 | if( rc==SQLITE_OK && u.br.res==0 ){ |
| 68115 | rc = sqlite3BtreeDelete(u.br.pCrsr); |
| 68116 | } |
| 68117 | assert( u.br.pC->deferredMoveto==0 ); |
| 68118 | u.br.pC->cacheStatus = CACHE_STALE; |
| 68119 | } |
| 68120 | break; |
| 68121 | } |
| 68122 | |
| 68123 | /* Opcode: IdxRowid P1 P2 * * * |
| @@ -68091,32 +68127,32 @@ | |
| 68127 | ** the rowid of the table entry to which this index entry points. |
| 68128 | ** |
| 68129 | ** See also: Rowid, MakeRecord. |
| 68130 | */ |
| 68131 | case OP_IdxRowid: { /* out2-prerelease */ |
| 68132 | #if 0 /* local variables moved into u.bs */ |
| 68133 | BtCursor *pCrsr; |
| 68134 | VdbeCursor *pC; |
| 68135 | i64 rowid; |
| 68136 | #endif /* local variables moved into u.bs */ |
| 68137 | |
| 68138 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68139 | u.bs.pC = p->apCsr[pOp->p1]; |
| 68140 | assert( u.bs.pC!=0 ); |
| 68141 | u.bs.pCrsr = u.bs.pC->pCursor; |
| 68142 | pOut->flags = MEM_Null; |
| 68143 | if( ALWAYS(u.bs.pCrsr!=0) ){ |
| 68144 | rc = sqlite3VdbeCursorMoveto(u.bs.pC); |
| 68145 | if( NEVER(rc) ) goto abort_due_to_error; |
| 68146 | assert( u.bs.pC->deferredMoveto==0 ); |
| 68147 | assert( u.bs.pC->isTable==0 ); |
| 68148 | if( !u.bs.pC->nullRow ){ |
| 68149 | rc = sqlite3VdbeIdxRowid(db, u.bs.pCrsr, &u.bs.rowid); |
| 68150 | if( rc!=SQLITE_OK ){ |
| 68151 | goto abort_due_to_error; |
| 68152 | } |
| 68153 | pOut->u.i = u.bs.rowid; |
| 68154 | pOut->flags = MEM_Int; |
| 68155 | } |
| 68156 | } |
| 68157 | break; |
| 68158 | } |
| @@ -68147,43 +68183,43 @@ | |
| 68183 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 68184 | ** to the comparison. This makes the opcode work like IdxLE. |
| 68185 | */ |
| 68186 | case OP_IdxLT: /* jump */ |
| 68187 | case OP_IdxGE: { /* jump */ |
| 68188 | #if 0 /* local variables moved into u.bt */ |
| 68189 | VdbeCursor *pC; |
| 68190 | int res; |
| 68191 | UnpackedRecord r; |
| 68192 | #endif /* local variables moved into u.bt */ |
| 68193 | |
| 68194 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68195 | u.bt.pC = p->apCsr[pOp->p1]; |
| 68196 | assert( u.bt.pC!=0 ); |
| 68197 | assert( u.bt.pC->isOrdered ); |
| 68198 | if( ALWAYS(u.bt.pC->pCursor!=0) ){ |
| 68199 | assert( u.bt.pC->deferredMoveto==0 ); |
| 68200 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 68201 | assert( pOp->p4type==P4_INT32 ); |
| 68202 | u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; |
| 68203 | u.bt.r.nField = (u16)pOp->p4.i; |
| 68204 | if( pOp->p5 ){ |
| 68205 | u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
| 68206 | }else{ |
| 68207 | u.bt.r.flags = UNPACKED_IGNORE_ROWID; |
| 68208 | } |
| 68209 | u.bt.r.aMem = &aMem[pOp->p3]; |
| 68210 | #ifdef SQLITE_DEBUG |
| 68211 | { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } |
| 68212 | #endif |
| 68213 | rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); |
| 68214 | if( pOp->opcode==OP_IdxLT ){ |
| 68215 | u.bt.res = -u.bt.res; |
| 68216 | }else{ |
| 68217 | assert( pOp->opcode==OP_IdxGE ); |
| 68218 | u.bt.res++; |
| 68219 | } |
| 68220 | if( u.bt.res>0 ){ |
| 68221 | pc = pOp->p2 - 1 ; |
| 68222 | } |
| 68223 | } |
| 68224 | break; |
| 68225 | } |
| @@ -68207,43 +68243,43 @@ | |
| 68243 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 68244 | ** |
| 68245 | ** See also: Clear |
| 68246 | */ |
| 68247 | case OP_Destroy: { /* out2-prerelease */ |
| 68248 | #if 0 /* local variables moved into u.bu */ |
| 68249 | int iMoved; |
| 68250 | int iCnt; |
| 68251 | Vdbe *pVdbe; |
| 68252 | int iDb; |
| 68253 | #endif /* local variables moved into u.bu */ |
| 68254 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 68255 | u.bu.iCnt = 0; |
| 68256 | for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ |
| 68257 | if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ |
| 68258 | u.bu.iCnt++; |
| 68259 | } |
| 68260 | } |
| 68261 | #else |
| 68262 | u.bu.iCnt = db->activeVdbeCnt; |
| 68263 | #endif |
| 68264 | pOut->flags = MEM_Null; |
| 68265 | if( u.bu.iCnt>1 ){ |
| 68266 | rc = SQLITE_LOCKED; |
| 68267 | p->errorAction = OE_Abort; |
| 68268 | }else{ |
| 68269 | u.bu.iDb = pOp->p3; |
| 68270 | assert( u.bu.iCnt==1 ); |
| 68271 | assert( (p->btreeMask & (((yDbMask)1)<<u.bu.iDb))!=0 ); |
| 68272 | rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); |
| 68273 | pOut->flags = MEM_Int; |
| 68274 | pOut->u.i = u.bu.iMoved; |
| 68275 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 68276 | if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ |
| 68277 | sqlite3RootPageMoved(db, u.bu.iDb, u.bu.iMoved, pOp->p1); |
| 68278 | /* All OP_Destroy operations occur on the same btree */ |
| 68279 | assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bu.iDb+1 ); |
| 68280 | resetSchemaOnFault = u.bu.iDb+1; |
| 68281 | } |
| 68282 | #endif |
| 68283 | } |
| 68284 | break; |
| 68285 | } |
| @@ -68265,25 +68301,25 @@ | |
| 68301 | ** also incremented by the number of rows in the table being cleared. |
| 68302 | ** |
| 68303 | ** See also: Destroy |
| 68304 | */ |
| 68305 | case OP_Clear: { |
| 68306 | #if 0 /* local variables moved into u.bv */ |
| 68307 | int nChange; |
| 68308 | #endif /* local variables moved into u.bv */ |
| 68309 | |
| 68310 | u.bv.nChange = 0; |
| 68311 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 68312 | rc = sqlite3BtreeClearTable( |
| 68313 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) |
| 68314 | ); |
| 68315 | if( pOp->p3 ){ |
| 68316 | p->nChange += u.bv.nChange; |
| 68317 | if( pOp->p3>0 ){ |
| 68318 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 68319 | memAboutToChange(p, &aMem[pOp->p3]); |
| 68320 | aMem[pOp->p3].u.i += u.bv.nChange; |
| 68321 | } |
| 68322 | } |
| 68323 | break; |
| 68324 | } |
| 68325 | |
| @@ -68309,29 +68345,29 @@ | |
| 68345 | ** |
| 68346 | ** See documentation on OP_CreateTable for additional information. |
| 68347 | */ |
| 68348 | case OP_CreateIndex: /* out2-prerelease */ |
| 68349 | case OP_CreateTable: { /* out2-prerelease */ |
| 68350 | #if 0 /* local variables moved into u.bw */ |
| 68351 | int pgno; |
| 68352 | int flags; |
| 68353 | Db *pDb; |
| 68354 | #endif /* local variables moved into u.bw */ |
| 68355 | |
| 68356 | u.bw.pgno = 0; |
| 68357 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68358 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68359 | u.bw.pDb = &db->aDb[pOp->p1]; |
| 68360 | assert( u.bw.pDb->pBt!=0 ); |
| 68361 | if( pOp->opcode==OP_CreateTable ){ |
| 68362 | /* u.bw.flags = BTREE_INTKEY; */ |
| 68363 | u.bw.flags = BTREE_INTKEY; |
| 68364 | }else{ |
| 68365 | u.bw.flags = BTREE_BLOBKEY; |
| 68366 | } |
| 68367 | rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); |
| 68368 | pOut->u.i = u.bw.pgno; |
| 68369 | break; |
| 68370 | } |
| 68371 | |
| 68372 | /* Opcode: ParseSchema P1 * * P4 * |
| 68373 | ** |
| @@ -68340,48 +68376,48 @@ | |
| 68376 | ** |
| 68377 | ** This opcode invokes the parser to create a new virtual machine, |
| 68378 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 68379 | */ |
| 68380 | case OP_ParseSchema: { |
| 68381 | #if 0 /* local variables moved into u.bx */ |
| 68382 | int iDb; |
| 68383 | const char *zMaster; |
| 68384 | char *zSql; |
| 68385 | InitData initData; |
| 68386 | #endif /* local variables moved into u.bx */ |
| 68387 | |
| 68388 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 68389 | ** on every btree. This is a prerequisite for invoking |
| 68390 | ** sqlite3InitCallback(). |
| 68391 | */ |
| 68392 | #ifdef SQLITE_DEBUG |
| 68393 | for(u.bx.iDb=0; u.bx.iDb<db->nDb; u.bx.iDb++){ |
| 68394 | assert( u.bx.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); |
| 68395 | } |
| 68396 | #endif |
| 68397 | |
| 68398 | u.bx.iDb = pOp->p1; |
| 68399 | assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); |
| 68400 | assert( DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ); |
| 68401 | /* Used to be a conditional */ { |
| 68402 | u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); |
| 68403 | u.bx.initData.db = db; |
| 68404 | u.bx.initData.iDb = pOp->p1; |
| 68405 | u.bx.initData.pzErrMsg = &p->zErrMsg; |
| 68406 | u.bx.zSql = sqlite3MPrintf(db, |
| 68407 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| 68408 | db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); |
| 68409 | if( u.bx.zSql==0 ){ |
| 68410 | rc = SQLITE_NOMEM; |
| 68411 | }else{ |
| 68412 | assert( db->init.busy==0 ); |
| 68413 | db->init.busy = 1; |
| 68414 | u.bx.initData.rc = SQLITE_OK; |
| 68415 | assert( !db->mallocFailed ); |
| 68416 | rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); |
| 68417 | if( rc==SQLITE_OK ) rc = u.bx.initData.rc; |
| 68418 | sqlite3DbFree(db, u.bx.zSql); |
| 68419 | db->init.busy = 0; |
| 68420 | } |
| 68421 | } |
| 68422 | if( rc==SQLITE_NOMEM ){ |
| 68423 | goto no_mem; |
| @@ -68460,45 +68496,45 @@ | |
| 68496 | ** file, not the main database file. |
| 68497 | ** |
| 68498 | ** This opcode is used to implement the integrity_check pragma. |
| 68499 | */ |
| 68500 | case OP_IntegrityCk: { |
| 68501 | #if 0 /* local variables moved into u.by */ |
| 68502 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 68503 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 68504 | int j; /* Loop counter */ |
| 68505 | int nErr; /* Number of errors reported */ |
| 68506 | char *z; /* Text of the error report */ |
| 68507 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 68508 | #endif /* local variables moved into u.by */ |
| 68509 | |
| 68510 | u.by.nRoot = pOp->p2; |
| 68511 | assert( u.by.nRoot>0 ); |
| 68512 | u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); |
| 68513 | if( u.by.aRoot==0 ) goto no_mem; |
| 68514 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68515 | u.by.pnErr = &aMem[pOp->p3]; |
| 68516 | assert( (u.by.pnErr->flags & MEM_Int)!=0 ); |
| 68517 | assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 68518 | pIn1 = &aMem[pOp->p1]; |
| 68519 | for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ |
| 68520 | u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); |
| 68521 | } |
| 68522 | u.by.aRoot[u.by.j] = 0; |
| 68523 | assert( pOp->p5<db->nDb ); |
| 68524 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 68525 | u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, |
| 68526 | (int)u.by.pnErr->u.i, &u.by.nErr); |
| 68527 | sqlite3DbFree(db, u.by.aRoot); |
| 68528 | u.by.pnErr->u.i -= u.by.nErr; |
| 68529 | sqlite3VdbeMemSetNull(pIn1); |
| 68530 | if( u.by.nErr==0 ){ |
| 68531 | assert( u.by.z==0 ); |
| 68532 | }else if( u.by.z==0 ){ |
| 68533 | goto no_mem; |
| 68534 | }else{ |
| 68535 | sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68536 | } |
| 68537 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 68538 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 68539 | break; |
| 68540 | } |
| @@ -68528,24 +68564,24 @@ | |
| 68564 | ** Extract the smallest value from boolean index P1 and put that value into |
| 68565 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 68566 | ** unchanged and jump to instruction P2. |
| 68567 | */ |
| 68568 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 68569 | #if 0 /* local variables moved into u.bz */ |
| 68570 | i64 val; |
| 68571 | #endif /* local variables moved into u.bz */ |
| 68572 | CHECK_FOR_INTERRUPT; |
| 68573 | pIn1 = &aMem[pOp->p1]; |
| 68574 | if( (pIn1->flags & MEM_RowSet)==0 |
| 68575 | || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bz.val)==0 |
| 68576 | ){ |
| 68577 | /* The boolean index is empty */ |
| 68578 | sqlite3VdbeMemSetNull(pIn1); |
| 68579 | pc = pOp->p2 - 1; |
| 68580 | }else{ |
| 68581 | /* A value was pulled from the index */ |
| 68582 | sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bz.val); |
| 68583 | } |
| 68584 | break; |
| 68585 | } |
| 68586 | |
| 68587 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| @@ -68570,18 +68606,18 @@ | |
| 68606 | ** inserted, there is no need to search to see if the same value was |
| 68607 | ** previously inserted as part of set X (only if it was previously |
| 68608 | ** inserted as part of some other set). |
| 68609 | */ |
| 68610 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 68611 | #if 0 /* local variables moved into u.ca */ |
| 68612 | int iSet; |
| 68613 | int exists; |
| 68614 | #endif /* local variables moved into u.ca */ |
| 68615 | |
| 68616 | pIn1 = &aMem[pOp->p1]; |
| 68617 | pIn3 = &aMem[pOp->p3]; |
| 68618 | u.ca.iSet = pOp->p4.i; |
| 68619 | assert( pIn3->flags&MEM_Int ); |
| 68620 | |
| 68621 | /* If there is anything other than a rowset object in memory cell P1, |
| 68622 | ** delete it now and initialize P1 with an empty rowset |
| 68623 | */ |
| @@ -68589,21 +68625,21 @@ | |
| 68625 | sqlite3VdbeMemSetRowSet(pIn1); |
| 68626 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 68627 | } |
| 68628 | |
| 68629 | assert( pOp->p4type==P4_INT32 ); |
| 68630 | assert( u.ca.iSet==-1 || u.ca.iSet>=0 ); |
| 68631 | if( u.ca.iSet ){ |
| 68632 | u.ca.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 68633 | (u8)(u.ca.iSet>=0 ? u.ca.iSet & 0xf : 0xff), |
| 68634 | pIn3->u.i); |
| 68635 | if( u.ca.exists ){ |
| 68636 | pc = pOp->p2 - 1; |
| 68637 | break; |
| 68638 | } |
| 68639 | } |
| 68640 | if( u.ca.iSet>=0 ){ |
| 68641 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 68642 | } |
| 68643 | break; |
| 68644 | } |
| 68645 | |
| @@ -68622,25 +68658,25 @@ | |
| 68658 | ** memory required by the sub-vdbe at runtime. |
| 68659 | ** |
| 68660 | ** P4 is a pointer to the VM containing the trigger program. |
| 68661 | */ |
| 68662 | case OP_Program: { /* jump */ |
| 68663 | #if 0 /* local variables moved into u.cb */ |
| 68664 | int nMem; /* Number of memory registers for sub-program */ |
| 68665 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 68666 | Mem *pRt; /* Register to allocate runtime space */ |
| 68667 | Mem *pMem; /* Used to iterate through memory cells */ |
| 68668 | Mem *pEnd; /* Last memory cell in new array */ |
| 68669 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 68670 | SubProgram *pProgram; /* Sub-program to execute */ |
| 68671 | void *t; /* Token identifying trigger */ |
| 68672 | #endif /* local variables moved into u.cb */ |
| 68673 | |
| 68674 | u.cb.pProgram = pOp->p4.pProgram; |
| 68675 | u.cb.pRt = &aMem[pOp->p3]; |
| 68676 | assert( memIsValid(u.cb.pRt) ); |
| 68677 | assert( u.cb.pProgram->nOp>0 ); |
| 68678 | |
| 68679 | /* If the p5 flag is clear, then recursive invocation of triggers is |
| 68680 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 68681 | ** is really a trigger, not a foreign key action, and the flag set |
| 68682 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| @@ -68650,79 +68686,79 @@ | |
| 68686 | ** SubProgram (if the trigger may be executed with more than one different |
| 68687 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 68688 | ** single trigger all have the same value for the SubProgram.token |
| 68689 | ** variable. */ |
| 68690 | if( pOp->p5 ){ |
| 68691 | u.cb.t = u.cb.pProgram->token; |
| 68692 | for(u.cb.pFrame=p->pFrame; u.cb.pFrame && u.cb.pFrame->token!=u.cb.t; u.cb.pFrame=u.cb.pFrame->pParent); |
| 68693 | if( u.cb.pFrame ) break; |
| 68694 | } |
| 68695 | |
| 68696 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 68697 | rc = SQLITE_ERROR; |
| 68698 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 68699 | break; |
| 68700 | } |
| 68701 | |
| 68702 | /* Register u.cb.pRt is used to store the memory required to save the state |
| 68703 | ** of the current program, and the memory required at runtime to execute |
| 68704 | ** the trigger program. If this trigger has been fired before, then u.cb.pRt |
| 68705 | ** is already allocated. Otherwise, it must be initialized. */ |
| 68706 | if( (u.cb.pRt->flags&MEM_Frame)==0 ){ |
| 68707 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 68708 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 68709 | ** cell is required for each cursor used by the program. Set local |
| 68710 | ** variable u.cb.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68711 | */ |
| 68712 | u.cb.nMem = u.cb.pProgram->nMem + u.cb.pProgram->nCsr; |
| 68713 | u.cb.nByte = ROUND8(sizeof(VdbeFrame)) |
| 68714 | + u.cb.nMem * sizeof(Mem) |
| 68715 | + u.cb.pProgram->nCsr * sizeof(VdbeCursor *); |
| 68716 | u.cb.pFrame = sqlite3DbMallocZero(db, u.cb.nByte); |
| 68717 | if( !u.cb.pFrame ){ |
| 68718 | goto no_mem; |
| 68719 | } |
| 68720 | sqlite3VdbeMemRelease(u.cb.pRt); |
| 68721 | u.cb.pRt->flags = MEM_Frame; |
| 68722 | u.cb.pRt->u.pFrame = u.cb.pFrame; |
| 68723 | |
| 68724 | u.cb.pFrame->v = p; |
| 68725 | u.cb.pFrame->nChildMem = u.cb.nMem; |
| 68726 | u.cb.pFrame->nChildCsr = u.cb.pProgram->nCsr; |
| 68727 | u.cb.pFrame->pc = pc; |
| 68728 | u.cb.pFrame->aMem = p->aMem; |
| 68729 | u.cb.pFrame->nMem = p->nMem; |
| 68730 | u.cb.pFrame->apCsr = p->apCsr; |
| 68731 | u.cb.pFrame->nCursor = p->nCursor; |
| 68732 | u.cb.pFrame->aOp = p->aOp; |
| 68733 | u.cb.pFrame->nOp = p->nOp; |
| 68734 | u.cb.pFrame->token = u.cb.pProgram->token; |
| 68735 | |
| 68736 | u.cb.pEnd = &VdbeFrameMem(u.cb.pFrame)[u.cb.pFrame->nChildMem]; |
| 68737 | for(u.cb.pMem=VdbeFrameMem(u.cb.pFrame); u.cb.pMem!=u.cb.pEnd; u.cb.pMem++){ |
| 68738 | u.cb.pMem->flags = MEM_Null; |
| 68739 | u.cb.pMem->db = db; |
| 68740 | } |
| 68741 | }else{ |
| 68742 | u.cb.pFrame = u.cb.pRt->u.pFrame; |
| 68743 | assert( u.cb.pProgram->nMem+u.cb.pProgram->nCsr==u.cb.pFrame->nChildMem ); |
| 68744 | assert( u.cb.pProgram->nCsr==u.cb.pFrame->nChildCsr ); |
| 68745 | assert( pc==u.cb.pFrame->pc ); |
| 68746 | } |
| 68747 | |
| 68748 | p->nFrame++; |
| 68749 | u.cb.pFrame->pParent = p->pFrame; |
| 68750 | u.cb.pFrame->lastRowid = lastRowid; |
| 68751 | u.cb.pFrame->nChange = p->nChange; |
| 68752 | p->nChange = 0; |
| 68753 | p->pFrame = u.cb.pFrame; |
| 68754 | p->aMem = aMem = &VdbeFrameMem(u.cb.pFrame)[-1]; |
| 68755 | p->nMem = u.cb.pFrame->nChildMem; |
| 68756 | p->nCursor = (u16)u.cb.pFrame->nChildCsr; |
| 68757 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 68758 | p->aOp = aOp = u.cb.pProgram->aOp; |
| 68759 | p->nOp = u.cb.pProgram->nOp; |
| 68760 | pc = -1; |
| 68761 | |
| 68762 | break; |
| 68763 | } |
| 68764 | |
| @@ -68737,17 +68773,17 @@ | |
| 68773 | ** The address of the cell in the parent frame is determined by adding |
| 68774 | ** the value of the P1 argument to the value of the P1 argument to the |
| 68775 | ** calling OP_Program instruction. |
| 68776 | */ |
| 68777 | case OP_Param: { /* out2-prerelease */ |
| 68778 | #if 0 /* local variables moved into u.cc */ |
| 68779 | VdbeFrame *pFrame; |
| 68780 | Mem *pIn; |
| 68781 | #endif /* local variables moved into u.cc */ |
| 68782 | u.cc.pFrame = p->pFrame; |
| 68783 | u.cc.pIn = &u.cc.pFrame->aMem[pOp->p1 + u.cc.pFrame->aOp[u.cc.pFrame->pc].p1]; |
| 68784 | sqlite3VdbeMemShallowCopy(pOut, u.cc.pIn, MEM_Ephem); |
| 68785 | break; |
| 68786 | } |
| 68787 | |
| 68788 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 68789 | |
| @@ -68799,26 +68835,26 @@ | |
| 68835 | ** |
| 68836 | ** This instruction throws an error if the memory cell is not initially |
| 68837 | ** an integer. |
| 68838 | */ |
| 68839 | case OP_MemMax: { /* in2 */ |
| 68840 | #if 0 /* local variables moved into u.cd */ |
| 68841 | Mem *pIn1; |
| 68842 | VdbeFrame *pFrame; |
| 68843 | #endif /* local variables moved into u.cd */ |
| 68844 | if( p->pFrame ){ |
| 68845 | for(u.cd.pFrame=p->pFrame; u.cd.pFrame->pParent; u.cd.pFrame=u.cd.pFrame->pParent); |
| 68846 | u.cd.pIn1 = &u.cd.pFrame->aMem[pOp->p1]; |
| 68847 | }else{ |
| 68848 | u.cd.pIn1 = &aMem[pOp->p1]; |
| 68849 | } |
| 68850 | assert( memIsValid(u.cd.pIn1) ); |
| 68851 | sqlite3VdbeMemIntegerify(u.cd.pIn1); |
| 68852 | pIn2 = &aMem[pOp->p2]; |
| 68853 | sqlite3VdbeMemIntegerify(pIn2); |
| 68854 | if( u.cd.pIn1->u.i<pIn2->u.i){ |
| 68855 | u.cd.pIn1->u.i = pIn2->u.i; |
| 68856 | } |
| 68857 | break; |
| 68858 | } |
| 68859 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 68860 | |
| @@ -68881,54 +68917,54 @@ | |
| 68917 | ** |
| 68918 | ** The P5 arguments are taken from register P2 and its |
| 68919 | ** successors. |
| 68920 | */ |
| 68921 | case OP_AggStep: { |
| 68922 | #if 0 /* local variables moved into u.ce */ |
| 68923 | int n; |
| 68924 | int i; |
| 68925 | Mem *pMem; |
| 68926 | Mem *pRec; |
| 68927 | sqlite3_context ctx; |
| 68928 | sqlite3_value **apVal; |
| 68929 | #endif /* local variables moved into u.ce */ |
| 68930 | |
| 68931 | u.ce.n = pOp->p5; |
| 68932 | assert( u.ce.n>=0 ); |
| 68933 | u.ce.pRec = &aMem[pOp->p2]; |
| 68934 | u.ce.apVal = p->apArg; |
| 68935 | assert( u.ce.apVal || u.ce.n==0 ); |
| 68936 | for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ |
| 68937 | assert( memIsValid(u.ce.pRec) ); |
| 68938 | u.ce.apVal[u.ce.i] = u.ce.pRec; |
| 68939 | memAboutToChange(p, u.ce.pRec); |
| 68940 | sqlite3VdbeMemStoreType(u.ce.pRec); |
| 68941 | } |
| 68942 | u.ce.ctx.pFunc = pOp->p4.pFunc; |
| 68943 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68944 | u.ce.ctx.pMem = u.ce.pMem = &aMem[pOp->p3]; |
| 68945 | u.ce.pMem->n++; |
| 68946 | u.ce.ctx.s.flags = MEM_Null; |
| 68947 | u.ce.ctx.s.z = 0; |
| 68948 | u.ce.ctx.s.zMalloc = 0; |
| 68949 | u.ce.ctx.s.xDel = 0; |
| 68950 | u.ce.ctx.s.db = db; |
| 68951 | u.ce.ctx.isError = 0; |
| 68952 | u.ce.ctx.pColl = 0; |
| 68953 | if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 68954 | assert( pOp>p->aOp ); |
| 68955 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 68956 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 68957 | u.ce.ctx.pColl = pOp[-1].p4.pColl; |
| 68958 | } |
| 68959 | (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); /* IMP: R-24505-23230 */ |
| 68960 | if( u.ce.ctx.isError ){ |
| 68961 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); |
| 68962 | rc = u.ce.ctx.isError; |
| 68963 | } |
| 68964 | |
| 68965 | sqlite3VdbeMemRelease(&u.ce.ctx.s); |
| 68966 | |
| 68967 | break; |
| 68968 | } |
| 68969 | |
| 68970 | /* Opcode: AggFinal P1 P2 * P4 * |
| @@ -68942,23 +68978,23 @@ | |
| 68978 | ** functions that can take varying numbers of arguments. The |
| 68979 | ** P4 argument is only needed for the degenerate case where |
| 68980 | ** the step function was not previously called. |
| 68981 | */ |
| 68982 | case OP_AggFinal: { |
| 68983 | #if 0 /* local variables moved into u.cf */ |
| 68984 | Mem *pMem; |
| 68985 | #endif /* local variables moved into u.cf */ |
| 68986 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 68987 | u.cf.pMem = &aMem[pOp->p1]; |
| 68988 | assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 68989 | rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); |
| 68990 | if( rc ){ |
| 68991 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); |
| 68992 | } |
| 68993 | sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); |
| 68994 | UPDATE_MAX_BLOBSIZE(u.cf.pMem); |
| 68995 | if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ |
| 68996 | goto too_big; |
| 68997 | } |
| 68998 | break; |
| 68999 | } |
| 69000 | |
| @@ -68973,29 +69009,29 @@ | |
| 69009 | ** in the WAL that have been checkpointed after the checkpoint |
| 69010 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 69011 | ** mem[P3+2] are initialized to -1. |
| 69012 | */ |
| 69013 | case OP_Checkpoint: { |
| 69014 | #if 0 /* local variables moved into u.cg */ |
| 69015 | int i; /* Loop counter */ |
| 69016 | int aRes[3]; /* Results */ |
| 69017 | Mem *pMem; /* Write results here */ |
| 69018 | #endif /* local variables moved into u.cg */ |
| 69019 | |
| 69020 | u.cg.aRes[0] = 0; |
| 69021 | u.cg.aRes[1] = u.cg.aRes[2] = -1; |
| 69022 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 69023 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 69024 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 69025 | ); |
| 69026 | rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cg.aRes[1], &u.cg.aRes[2]); |
| 69027 | if( rc==SQLITE_BUSY ){ |
| 69028 | rc = SQLITE_OK; |
| 69029 | u.cg.aRes[0] = 1; |
| 69030 | } |
| 69031 | for(u.cg.i=0, u.cg.pMem = &aMem[pOp->p3]; u.cg.i<3; u.cg.i++, u.cg.pMem++){ |
| 69032 | sqlite3VdbeMemSetInt64(u.cg.pMem, (i64)u.cg.aRes[u.cg.i]); |
| 69033 | } |
| 69034 | break; |
| 69035 | }; |
| 69036 | #endif |
| 69037 | |
| @@ -69010,95 +69046,95 @@ | |
| 69046 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 69047 | ** |
| 69048 | ** Write a string containing the final journal-mode to register P2. |
| 69049 | */ |
| 69050 | case OP_JournalMode: { /* out2-prerelease */ |
| 69051 | #if 0 /* local variables moved into u.ch */ |
| 69052 | Btree *pBt; /* Btree to change journal mode of */ |
| 69053 | Pager *pPager; /* Pager associated with pBt */ |
| 69054 | int eNew; /* New journal mode */ |
| 69055 | int eOld; /* The old journal mode */ |
| 69056 | const char *zFilename; /* Name of database file for pPager */ |
| 69057 | #endif /* local variables moved into u.ch */ |
| 69058 | |
| 69059 | u.ch.eNew = pOp->p3; |
| 69060 | assert( u.ch.eNew==PAGER_JOURNALMODE_DELETE |
| 69061 | || u.ch.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 69062 | || u.ch.eNew==PAGER_JOURNALMODE_PERSIST |
| 69063 | || u.ch.eNew==PAGER_JOURNALMODE_OFF |
| 69064 | || u.ch.eNew==PAGER_JOURNALMODE_MEMORY |
| 69065 | || u.ch.eNew==PAGER_JOURNALMODE_WAL |
| 69066 | || u.ch.eNew==PAGER_JOURNALMODE_QUERY |
| 69067 | ); |
| 69068 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69069 | |
| 69070 | u.ch.pBt = db->aDb[pOp->p1].pBt; |
| 69071 | u.ch.pPager = sqlite3BtreePager(u.ch.pBt); |
| 69072 | u.ch.eOld = sqlite3PagerGetJournalMode(u.ch.pPager); |
| 69073 | if( u.ch.eNew==PAGER_JOURNALMODE_QUERY ) u.ch.eNew = u.ch.eOld; |
| 69074 | if( !sqlite3PagerOkToChangeJournalMode(u.ch.pPager) ) u.ch.eNew = u.ch.eOld; |
| 69075 | |
| 69076 | #ifndef SQLITE_OMIT_WAL |
| 69077 | u.ch.zFilename = sqlite3PagerFilename(u.ch.pPager); |
| 69078 | |
| 69079 | /* Do not allow a transition to journal_mode=WAL for a database |
| 69080 | ** in temporary storage or if the VFS does not support shared memory |
| 69081 | */ |
| 69082 | if( u.ch.eNew==PAGER_JOURNALMODE_WAL |
| 69083 | && (u.ch.zFilename[0]==0 /* Temp file */ |
| 69084 | || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */ |
| 69085 | ){ |
| 69086 | u.ch.eNew = u.ch.eOld; |
| 69087 | } |
| 69088 | |
| 69089 | if( (u.ch.eNew!=u.ch.eOld) |
| 69090 | && (u.ch.eOld==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_WAL) |
| 69091 | ){ |
| 69092 | if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 69093 | rc = SQLITE_ERROR; |
| 69094 | sqlite3SetString(&p->zErrMsg, db, |
| 69095 | "cannot change %s wal mode from within a transaction", |
| 69096 | (u.ch.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69097 | ); |
| 69098 | break; |
| 69099 | }else{ |
| 69100 | |
| 69101 | if( u.ch.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69102 | /* If leaving WAL mode, close the log file. If successful, the call |
| 69103 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 69104 | ** file. An EXCLUSIVE lock may still be held on the database file |
| 69105 | ** after a successful return. |
| 69106 | */ |
| 69107 | rc = sqlite3PagerCloseWal(u.ch.pPager); |
| 69108 | if( rc==SQLITE_OK ){ |
| 69109 | sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); |
| 69110 | } |
| 69111 | }else if( u.ch.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69112 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 69113 | ** as an intermediate */ |
| 69114 | sqlite3PagerSetJournalMode(u.ch.pPager, PAGER_JOURNALMODE_OFF); |
| 69115 | } |
| 69116 | |
| 69117 | /* Open a transaction on the database file. Regardless of the journal |
| 69118 | ** mode, this transaction always uses a rollback journal. |
| 69119 | */ |
| 69120 | assert( sqlite3BtreeIsInTrans(u.ch.pBt)==0 ); |
| 69121 | if( rc==SQLITE_OK ){ |
| 69122 | rc = sqlite3BtreeSetVersion(u.ch.pBt, (u.ch.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69123 | } |
| 69124 | } |
| 69125 | } |
| 69126 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 69127 | |
| 69128 | if( rc ){ |
| 69129 | u.ch.eNew = u.ch.eOld; |
| 69130 | } |
| 69131 | u.ch.eNew = sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); |
| 69132 | |
| 69133 | pOut = &aMem[pOp->p2]; |
| 69134 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 69135 | pOut->z = (char *)sqlite3JournalModename(u.ch.eNew); |
| 69136 | pOut->n = sqlite3Strlen30(pOut->z); |
| 69137 | pOut->enc = SQLITE_UTF8; |
| 69138 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 69139 | break; |
| 69140 | }; |
| @@ -69123,18 +69159,18 @@ | |
| 69159 | ** Perform a single step of the incremental vacuum procedure on |
| 69160 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 69161 | ** P2. Otherwise, fall through to the next instruction. |
| 69162 | */ |
| 69163 | case OP_IncrVacuum: { /* jump */ |
| 69164 | #if 0 /* local variables moved into u.ci */ |
| 69165 | Btree *pBt; |
| 69166 | #endif /* local variables moved into u.ci */ |
| 69167 | |
| 69168 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69169 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69170 | u.ci.pBt = db->aDb[pOp->p1].pBt; |
| 69171 | rc = sqlite3BtreeIncrVacuum(u.ci.pBt); |
| 69172 | if( rc==SQLITE_DONE ){ |
| 69173 | pc = pOp->p2 - 1; |
| 69174 | rc = SQLITE_OK; |
| 69175 | } |
| 69176 | break; |
| @@ -69200,16 +69236,16 @@ | |
| 69236 | ** Also, whether or not P4 is set, check that this is not being called from |
| 69237 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 69238 | ** code will be set to SQLITE_LOCKED. |
| 69239 | */ |
| 69240 | case OP_VBegin: { |
| 69241 | #if 0 /* local variables moved into u.cj */ |
| 69242 | VTable *pVTab; |
| 69243 | #endif /* local variables moved into u.cj */ |
| 69244 | u.cj.pVTab = pOp->p4.pVtab; |
| 69245 | rc = sqlite3VtabBegin(db, u.cj.pVTab); |
| 69246 | if( u.cj.pVTab ) importVtabErrMsg(p, u.cj.pVTab->pVtab); |
| 69247 | break; |
| 69248 | } |
| 69249 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69250 | |
| 69251 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| @@ -69244,36 +69280,36 @@ | |
| 69280 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69281 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 69282 | ** table and stores that cursor in P1. |
| 69283 | */ |
| 69284 | case OP_VOpen: { |
| 69285 | #if 0 /* local variables moved into u.ck */ |
| 69286 | VdbeCursor *pCur; |
| 69287 | sqlite3_vtab_cursor *pVtabCursor; |
| 69288 | sqlite3_vtab *pVtab; |
| 69289 | sqlite3_module *pModule; |
| 69290 | #endif /* local variables moved into u.ck */ |
| 69291 | |
| 69292 | u.ck.pCur = 0; |
| 69293 | u.ck.pVtabCursor = 0; |
| 69294 | u.ck.pVtab = pOp->p4.pVtab->pVtab; |
| 69295 | u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; |
| 69296 | assert(u.ck.pVtab && u.ck.pModule); |
| 69297 | rc = u.ck.pModule->xOpen(u.ck.pVtab, &u.ck.pVtabCursor); |
| 69298 | importVtabErrMsg(p, u.ck.pVtab); |
| 69299 | if( SQLITE_OK==rc ){ |
| 69300 | /* Initialize sqlite3_vtab_cursor base class */ |
| 69301 | u.ck.pVtabCursor->pVtab = u.ck.pVtab; |
| 69302 | |
| 69303 | /* Initialise vdbe cursor object */ |
| 69304 | u.ck.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 69305 | if( u.ck.pCur ){ |
| 69306 | u.ck.pCur->pVtabCursor = u.ck.pVtabCursor; |
| 69307 | u.ck.pCur->pModule = u.ck.pVtabCursor->pVtab->pModule; |
| 69308 | }else{ |
| 69309 | db->mallocFailed = 1; |
| 69310 | u.ck.pModule->xClose(u.ck.pVtabCursor); |
| 69311 | } |
| 69312 | } |
| 69313 | break; |
| 69314 | } |
| 69315 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69296,11 +69332,11 @@ | |
| 69332 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 69333 | ** |
| 69334 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 69335 | */ |
| 69336 | case OP_VFilter: { /* jump */ |
| 69337 | #if 0 /* local variables moved into u.cl */ |
| 69338 | int nArg; |
| 69339 | int iQuery; |
| 69340 | const sqlite3_module *pModule; |
| 69341 | Mem *pQuery; |
| 69342 | Mem *pArgc; |
| @@ -69308,49 +69344,49 @@ | |
| 69344 | sqlite3_vtab *pVtab; |
| 69345 | VdbeCursor *pCur; |
| 69346 | int res; |
| 69347 | int i; |
| 69348 | Mem **apArg; |
| 69349 | #endif /* local variables moved into u.cl */ |
| 69350 | |
| 69351 | u.cl.pQuery = &aMem[pOp->p3]; |
| 69352 | u.cl.pArgc = &u.cl.pQuery[1]; |
| 69353 | u.cl.pCur = p->apCsr[pOp->p1]; |
| 69354 | assert( memIsValid(u.cl.pQuery) ); |
| 69355 | REGISTER_TRACE(pOp->p3, u.cl.pQuery); |
| 69356 | assert( u.cl.pCur->pVtabCursor ); |
| 69357 | u.cl.pVtabCursor = u.cl.pCur->pVtabCursor; |
| 69358 | u.cl.pVtab = u.cl.pVtabCursor->pVtab; |
| 69359 | u.cl.pModule = u.cl.pVtab->pModule; |
| 69360 | |
| 69361 | /* Grab the index number and argc parameters */ |
| 69362 | assert( (u.cl.pQuery->flags&MEM_Int)!=0 && u.cl.pArgc->flags==MEM_Int ); |
| 69363 | u.cl.nArg = (int)u.cl.pArgc->u.i; |
| 69364 | u.cl.iQuery = (int)u.cl.pQuery->u.i; |
| 69365 | |
| 69366 | /* Invoke the xFilter method */ |
| 69367 | { |
| 69368 | u.cl.res = 0; |
| 69369 | u.cl.apArg = p->apArg; |
| 69370 | for(u.cl.i = 0; u.cl.i<u.cl.nArg; u.cl.i++){ |
| 69371 | u.cl.apArg[u.cl.i] = &u.cl.pArgc[u.cl.i+1]; |
| 69372 | sqlite3VdbeMemStoreType(u.cl.apArg[u.cl.i]); |
| 69373 | } |
| 69374 | |
| 69375 | p->inVtabMethod = 1; |
| 69376 | rc = u.cl.pModule->xFilter(u.cl.pVtabCursor, u.cl.iQuery, pOp->p4.z, u.cl.nArg, u.cl.apArg); |
| 69377 | p->inVtabMethod = 0; |
| 69378 | importVtabErrMsg(p, u.cl.pVtab); |
| 69379 | if( rc==SQLITE_OK ){ |
| 69380 | u.cl.res = u.cl.pModule->xEof(u.cl.pVtabCursor); |
| 69381 | } |
| 69382 | |
| 69383 | if( u.cl.res ){ |
| 69384 | pc = pOp->p2 - 1; |
| 69385 | } |
| 69386 | } |
| 69387 | u.cl.pCur->nullRow = 0; |
| 69388 | |
| 69389 | break; |
| 69390 | } |
| 69391 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69392 | |
| @@ -69360,55 +69396,55 @@ | |
| 69396 | ** Store the value of the P2-th column of |
| 69397 | ** the row of the virtual-table that the |
| 69398 | ** P1 cursor is pointing to into register P3. |
| 69399 | */ |
| 69400 | case OP_VColumn: { |
| 69401 | #if 0 /* local variables moved into u.cm */ |
| 69402 | sqlite3_vtab *pVtab; |
| 69403 | const sqlite3_module *pModule; |
| 69404 | Mem *pDest; |
| 69405 | sqlite3_context sContext; |
| 69406 | #endif /* local variables moved into u.cm */ |
| 69407 | |
| 69408 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 69409 | assert( pCur->pVtabCursor ); |
| 69410 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69411 | u.cm.pDest = &aMem[pOp->p3]; |
| 69412 | memAboutToChange(p, u.cm.pDest); |
| 69413 | if( pCur->nullRow ){ |
| 69414 | sqlite3VdbeMemSetNull(u.cm.pDest); |
| 69415 | break; |
| 69416 | } |
| 69417 | u.cm.pVtab = pCur->pVtabCursor->pVtab; |
| 69418 | u.cm.pModule = u.cm.pVtab->pModule; |
| 69419 | assert( u.cm.pModule->xColumn ); |
| 69420 | memset(&u.cm.sContext, 0, sizeof(u.cm.sContext)); |
| 69421 | |
| 69422 | /* The output cell may already have a buffer allocated. Move |
| 69423 | ** the current contents to u.cm.sContext.s so in case the user-function |
| 69424 | ** can use the already allocated buffer instead of allocating a |
| 69425 | ** new one. |
| 69426 | */ |
| 69427 | sqlite3VdbeMemMove(&u.cm.sContext.s, u.cm.pDest); |
| 69428 | MemSetTypeFlag(&u.cm.sContext.s, MEM_Null); |
| 69429 | |
| 69430 | rc = u.cm.pModule->xColumn(pCur->pVtabCursor, &u.cm.sContext, pOp->p2); |
| 69431 | importVtabErrMsg(p, u.cm.pVtab); |
| 69432 | if( u.cm.sContext.isError ){ |
| 69433 | rc = u.cm.sContext.isError; |
| 69434 | } |
| 69435 | |
| 69436 | /* Copy the result of the function to the P3 register. We |
| 69437 | ** do this regardless of whether or not an error occurred to ensure any |
| 69438 | ** dynamic allocation in u.cm.sContext.s (a Mem struct) is released. |
| 69439 | */ |
| 69440 | sqlite3VdbeChangeEncoding(&u.cm.sContext.s, encoding); |
| 69441 | sqlite3VdbeMemMove(u.cm.pDest, &u.cm.sContext.s); |
| 69442 | REGISTER_TRACE(pOp->p3, u.cm.pDest); |
| 69443 | UPDATE_MAX_BLOBSIZE(u.cm.pDest); |
| 69444 | |
| 69445 | if( sqlite3VdbeMemTooBig(u.cm.pDest) ){ |
| 69446 | goto too_big; |
| 69447 | } |
| 69448 | break; |
| 69449 | } |
| 69450 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -69419,42 +69455,42 @@ | |
| 69455 | ** Advance virtual table P1 to the next row in its result set and |
| 69456 | ** jump to instruction P2. Or, if the virtual table has reached |
| 69457 | ** the end of its result set, then fall through to the next instruction. |
| 69458 | */ |
| 69459 | case OP_VNext: { /* jump */ |
| 69460 | #if 0 /* local variables moved into u.cn */ |
| 69461 | sqlite3_vtab *pVtab; |
| 69462 | const sqlite3_module *pModule; |
| 69463 | int res; |
| 69464 | VdbeCursor *pCur; |
| 69465 | #endif /* local variables moved into u.cn */ |
| 69466 | |
| 69467 | u.cn.res = 0; |
| 69468 | u.cn.pCur = p->apCsr[pOp->p1]; |
| 69469 | assert( u.cn.pCur->pVtabCursor ); |
| 69470 | if( u.cn.pCur->nullRow ){ |
| 69471 | break; |
| 69472 | } |
| 69473 | u.cn.pVtab = u.cn.pCur->pVtabCursor->pVtab; |
| 69474 | u.cn.pModule = u.cn.pVtab->pModule; |
| 69475 | assert( u.cn.pModule->xNext ); |
| 69476 | |
| 69477 | /* Invoke the xNext() method of the module. There is no way for the |
| 69478 | ** underlying implementation to return an error if one occurs during |
| 69479 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 69480 | ** data is available) and the error code returned when xColumn or |
| 69481 | ** some other method is next invoked on the save virtual table cursor. |
| 69482 | */ |
| 69483 | p->inVtabMethod = 1; |
| 69484 | rc = u.cn.pModule->xNext(u.cn.pCur->pVtabCursor); |
| 69485 | p->inVtabMethod = 0; |
| 69486 | importVtabErrMsg(p, u.cn.pVtab); |
| 69487 | if( rc==SQLITE_OK ){ |
| 69488 | u.cn.res = u.cn.pModule->xEof(u.cn.pCur->pVtabCursor); |
| 69489 | } |
| 69490 | |
| 69491 | if( !u.cn.res ){ |
| 69492 | /* If there is data, jump to P2 */ |
| 69493 | pc = pOp->p2 - 1; |
| 69494 | } |
| 69495 | break; |
| 69496 | } |
| @@ -69466,23 +69502,23 @@ | |
| 69502 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69503 | ** This opcode invokes the corresponding xRename method. The value |
| 69504 | ** in register P1 is passed as the zName argument to the xRename method. |
| 69505 | */ |
| 69506 | case OP_VRename: { |
| 69507 | #if 0 /* local variables moved into u.co */ |
| 69508 | sqlite3_vtab *pVtab; |
| 69509 | Mem *pName; |
| 69510 | #endif /* local variables moved into u.co */ |
| 69511 | |
| 69512 | u.co.pVtab = pOp->p4.pVtab->pVtab; |
| 69513 | u.co.pName = &aMem[pOp->p1]; |
| 69514 | assert( u.co.pVtab->pModule->xRename ); |
| 69515 | assert( memIsValid(u.co.pName) ); |
| 69516 | REGISTER_TRACE(pOp->p1, u.co.pName); |
| 69517 | assert( u.co.pName->flags & MEM_Str ); |
| 69518 | rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z); |
| 69519 | importVtabErrMsg(p, u.co.pVtab); |
| 69520 | p->expired = 0; |
| 69521 | |
| 69522 | break; |
| 69523 | } |
| 69524 | #endif |
| @@ -69510,45 +69546,45 @@ | |
| 69546 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 69547 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 69548 | ** is set to the value of the rowid for the row just inserted. |
| 69549 | */ |
| 69550 | case OP_VUpdate: { |
| 69551 | #if 0 /* local variables moved into u.cp */ |
| 69552 | sqlite3_vtab *pVtab; |
| 69553 | sqlite3_module *pModule; |
| 69554 | int nArg; |
| 69555 | int i; |
| 69556 | sqlite_int64 rowid; |
| 69557 | Mem **apArg; |
| 69558 | Mem *pX; |
| 69559 | #endif /* local variables moved into u.cp */ |
| 69560 | |
| 69561 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 69562 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 69563 | ); |
| 69564 | u.cp.pVtab = pOp->p4.pVtab->pVtab; |
| 69565 | u.cp.pModule = (sqlite3_module *)u.cp.pVtab->pModule; |
| 69566 | u.cp.nArg = pOp->p2; |
| 69567 | assert( pOp->p4type==P4_VTAB ); |
| 69568 | if( ALWAYS(u.cp.pModule->xUpdate) ){ |
| 69569 | u8 vtabOnConflict = db->vtabOnConflict; |
| 69570 | u.cp.apArg = p->apArg; |
| 69571 | u.cp.pX = &aMem[pOp->p3]; |
| 69572 | for(u.cp.i=0; u.cp.i<u.cp.nArg; u.cp.i++){ |
| 69573 | assert( memIsValid(u.cp.pX) ); |
| 69574 | memAboutToChange(p, u.cp.pX); |
| 69575 | sqlite3VdbeMemStoreType(u.cp.pX); |
| 69576 | u.cp.apArg[u.cp.i] = u.cp.pX; |
| 69577 | u.cp.pX++; |
| 69578 | } |
| 69579 | db->vtabOnConflict = pOp->p5; |
| 69580 | rc = u.cp.pModule->xUpdate(u.cp.pVtab, u.cp.nArg, u.cp.apArg, &u.cp.rowid); |
| 69581 | db->vtabOnConflict = vtabOnConflict; |
| 69582 | importVtabErrMsg(p, u.cp.pVtab); |
| 69583 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 69584 | assert( u.cp.nArg>1 && u.cp.apArg[0] && (u.cp.apArg[0]->flags&MEM_Null) ); |
| 69585 | db->lastRowid = lastRowid = u.cp.rowid; |
| 69586 | } |
| 69587 | if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 69588 | if( pOp->p5==OE_Ignore ){ |
| 69589 | rc = SQLITE_OK; |
| 69590 | }else{ |
| @@ -69604,25 +69640,25 @@ | |
| 69640 | ** |
| 69641 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 69642 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 69643 | */ |
| 69644 | case OP_Trace: { |
| 69645 | #if 0 /* local variables moved into u.cq */ |
| 69646 | char *zTrace; |
| 69647 | char *z; |
| 69648 | #endif /* local variables moved into u.cq */ |
| 69649 | |
| 69650 | if( db->xTrace && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ |
| 69651 | u.cq.z = sqlite3VdbeExpandSql(p, u.cq.zTrace); |
| 69652 | db->xTrace(db->pTraceArg, u.cq.z); |
| 69653 | sqlite3DbFree(db, u.cq.z); |
| 69654 | } |
| 69655 | #ifdef SQLITE_DEBUG |
| 69656 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 69657 | && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69658 | ){ |
| 69659 | sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); |
| 69660 | } |
| 69661 | #endif /* SQLITE_DEBUG */ |
| 69662 | break; |
| 69663 | } |
| 69664 | #endif |
| @@ -70239,10 +70275,11 @@ | |
| 70275 | |
| 70276 | |
| 70277 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70278 | |
| 70279 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70280 | typedef struct SorterRecord SorterRecord; |
| 70281 | |
| 70282 | /* |
| 70283 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70284 | ** |
| 70285 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70310,19 +70347,23 @@ | |
| 70347 | ** In other words, each time we advance to the next sorter element, log2(N) |
| 70348 | ** key comparison operations are required, where N is the number of segments |
| 70349 | ** being merged (rounded up to the next power of 2). |
| 70350 | */ |
| 70351 | struct VdbeSorter { |
| 70352 | int nInMemory; /* Current size of pRecord list as PMA */ |
| 70353 | int nTree; /* Used size of aTree/aIter (power of 2) */ |
| 70354 | VdbeSorterIter *aIter; /* Array of iterators to merge */ |
| 70355 | int *aTree; /* Current state of incremental merge */ |
| 70356 | i64 iWriteOff; /* Current write offset within file pTemp1 */ |
| 70357 | i64 iReadOff; /* Current read offset within file pTemp1 */ |
| 70358 | sqlite3_file *pTemp1; /* PMA file 1 */ |
| 70359 | int nPMA; /* Number of PMAs stored in pTemp1 */ |
| 70360 | SorterRecord *pRecord; /* Head of in-memory record list */ |
| 70361 | int mnPmaSize; /* Minimum PMA size, in bytes */ |
| 70362 | int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ |
| 70363 | char *aSpace; /* Space for UnpackRecord() */ |
| 70364 | int nSpace; /* Size of aSpace in bytes */ |
| 70365 | }; |
| 70366 | |
| 70367 | /* |
| 70368 | ** The following type is an iterator for a PMA. It caches the current key in |
| 70369 | ** variables nKey/aKey. If the iterator is at EOF, pFile==0. |
| @@ -70334,10 +70375,21 @@ | |
| 70375 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70376 | u8 *aAlloc; /* Allocated space */ |
| 70377 | int nKey; /* Number of bytes in key */ |
| 70378 | u8 *aKey; /* Pointer to current key */ |
| 70379 | }; |
| 70380 | |
| 70381 | /* |
| 70382 | ** A structure to store a single record. All in-memory records are connected |
| 70383 | ** together into a linked list headed at VdbeSorter.pRecord using the |
| 70384 | ** SorterRecord.pNext pointer. |
| 70385 | */ |
| 70386 | struct SorterRecord { |
| 70387 | void *pVal; |
| 70388 | int nVal; |
| 70389 | SorterRecord *pNext; |
| 70390 | }; |
| 70391 | |
| 70392 | /* Minimum allowable value for the VdbeSorter.nWorking variable */ |
| 70393 | #define SORTER_MIN_WORKING 10 |
| 70394 | |
| 70395 | /* Maximum number of segments to merge in a single pass. */ |
| @@ -70360,12 +70412,12 @@ | |
| 70412 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70413 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70414 | ){ |
| 70415 | int rc; /* Return Code */ |
| 70416 | int nRead; /* Number of bytes read */ |
| 70417 | int nRec = 0; /* Size of record in bytes */ |
| 70418 | int iOff = 0; /* Size of serialized size varint in bytes */ |
| 70419 | |
| 70420 | nRead = pIter->iEof - pIter->iReadOff; |
| 70421 | if( nRead>5 ) nRead = 5; |
| 70422 | if( nRead<=0 ){ |
| 70423 | /* This is an EOF condition */ |
| @@ -70372,29 +70424,30 @@ | |
| 70424 | vdbeSorterIterZero(db, pIter); |
| 70425 | return SQLITE_OK; |
| 70426 | } |
| 70427 | |
| 70428 | rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); |
| 70429 | if( rc==SQLITE_OK ){ |
| 70430 | iOff = getVarint32(pIter->aAlloc, nRec); |
| 70431 | if( (iOff+nRec)>nRead ){ |
| 70432 | int nRead2; /* Number of extra bytes to read */ |
| 70433 | if( (iOff+nRec)>pIter->nAlloc ){ |
| 70434 | int nNew = pIter->nAlloc*2; |
| 70435 | while( (iOff+nRec)>nNew ) nNew = nNew*2; |
| 70436 | pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); |
| 70437 | if( !pIter->aAlloc ) return SQLITE_NOMEM; |
| 70438 | pIter->nAlloc = nNew; |
| 70439 | } |
| 70440 | |
| 70441 | nRead2 = iOff + nRec - nRead; |
| 70442 | rc = sqlite3OsRead( |
| 70443 | pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead |
| 70444 | ); |
| 70445 | } |
| 70446 | } |
| 70447 | |
| 70448 | assert( rc!=SQLITE_OK || nRec>0 ); |
| 70449 | pIter->iReadOff += iOff+nRec; |
| 70450 | pIter->nKey = nRec; |
| 70451 | pIter->aKey = &pIter->aAlloc[iOff]; |
| 70452 | return rc; |
| 70453 | } |
| @@ -70434,25 +70487,18 @@ | |
| 70487 | ** set to the integer value read. If an error occurs, the final values of |
| 70488 | ** both *piOffset and *piVal are undefined. |
| 70489 | */ |
| 70490 | static int vdbeSorterReadVarint( |
| 70491 | sqlite3_file *pFile, /* File to read from */ |
| 70492 | i64 *piOffset, /* IN/OUT: Read offset in pFile */ |
| 70493 | i64 *piVal /* OUT: Value read from file */ |
| 70494 | ){ |
| 70495 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70496 | i64 iOff = *piOffset; /* Offset in file to read from */ |
| 70497 | int rc; /* Return code */ |
| 70498 | |
| 70499 | rc = sqlite3OsRead(pFile, aVarint, 9, iOff); |
| 70500 | if( rc==SQLITE_OK ){ |
| 70501 | *piOffset += getVarint(aVarint, (u64 *)piVal); |
| 70502 | } |
| 70503 | |
| 70504 | return rc; |
| @@ -70480,22 +70526,85 @@ | |
| 70526 | pIter->nAlloc = 128; |
| 70527 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70528 | if( !pIter->aAlloc ){ |
| 70529 | rc = SQLITE_NOMEM; |
| 70530 | }else{ |
| 70531 | i64 nByte; /* Total size of PMA in bytes */ |
| 70532 | rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); |
| 70533 | *pnByte += nByte; |
| 70534 | pIter->iEof = pIter->iReadOff + nByte; |
| 70535 | } |
| 70536 | if( rc==SQLITE_OK ){ |
| 70537 | rc = vdbeSorterIterNext(db, pIter); |
| 70538 | } |
| 70539 | return rc; |
| 70540 | } |
| 70541 | |
| 70542 | |
| 70543 | /* |
| 70544 | ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, |
| 70545 | ** size nKey2 bytes). Argument pKeyInfo supplies the collation functions |
| 70546 | ** used by the comparison. If an error occurs, return an SQLite error code. |
| 70547 | ** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive |
| 70548 | ** value, depending on whether key1 is smaller, equal to or larger than key2. |
| 70549 | ** |
| 70550 | ** If the bOmitRowid argument is non-zero, assume both keys end in a rowid |
| 70551 | ** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid |
| 70552 | ** is true and key1 contains even a single NULL value, it is considered to |
| 70553 | ** be less than key2. Even if key2 also contains NULL values. |
| 70554 | ** |
| 70555 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 70556 | ** has been allocated and contains an unpacked record that is used as key2. |
| 70557 | */ |
| 70558 | static int vdbeSorterCompare( |
| 70559 | VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 70560 | int bOmitRowid, /* Ignore rowid field at end of keys */ |
| 70561 | void *pKey1, int nKey1, /* Left side of comparison */ |
| 70562 | void *pKey2, int nKey2, /* Right side of comparison */ |
| 70563 | int *pRes /* OUT: Result of comparison */ |
| 70564 | ){ |
| 70565 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 70566 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70567 | char *aSpace = pSorter->aSpace; |
| 70568 | int nSpace = pSorter->nSpace; |
| 70569 | UnpackedRecord *r2; |
| 70570 | int i; |
| 70571 | |
| 70572 | if( aSpace==0 ){ |
| 70573 | nSpace = ROUND8(sizeof(UnpackedRecord))+(pKeyInfo->nField+1)*sizeof(Mem); |
| 70574 | aSpace = (char *)sqlite3Malloc(nSpace); |
| 70575 | if( aSpace==0 ) return SQLITE_NOMEM; |
| 70576 | pSorter->aSpace = aSpace; |
| 70577 | pSorter->nSpace = nSpace; |
| 70578 | } |
| 70579 | |
| 70580 | if( pKey2 ){ |
| 70581 | /* This call cannot fail. As the memory is already allocated. */ |
| 70582 | r2 = sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, aSpace, nSpace); |
| 70583 | assert( r2 && (r2->flags & UNPACKED_NEED_FREE)==0 ); |
| 70584 | assert( r2==(UnpackedRecord*)aSpace ); |
| 70585 | }else{ |
| 70586 | r2 = (UnpackedRecord *)aSpace; |
| 70587 | assert( !bOmitRowid ); |
| 70588 | } |
| 70589 | |
| 70590 | if( bOmitRowid ){ |
| 70591 | for(i=0; i<r2->nField-1; i++){ |
| 70592 | if( r2->aMem[i].flags & MEM_Null ){ |
| 70593 | *pRes = -1; |
| 70594 | return SQLITE_OK; |
| 70595 | } |
| 70596 | } |
| 70597 | r2->flags |= UNPACKED_PREFIX_MATCH; |
| 70598 | r2->nField--; |
| 70599 | assert( r2->nField>0 ); |
| 70600 | } |
| 70601 | |
| 70602 | *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 70603 | return SQLITE_OK; |
| 70604 | } |
| 70605 | |
| 70606 | /* |
| 70607 | ** This function is called to compare two iterator keys when merging |
| 70608 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70609 | ** value to recalculate. |
| 70610 | */ |
| @@ -70523,24 +70632,25 @@ | |
| 70632 | if( p1->pFile==0 ){ |
| 70633 | iRes = i2; |
| 70634 | }else if( p2->pFile==0 ){ |
| 70635 | iRes = i1; |
| 70636 | }else{ |
| 70637 | int res; |
| 70638 | int rc; |
| 70639 | assert( pCsr->pSorter->aSpace!=0 ); /* allocated in vdbeSorterMerge() */ |
| 70640 | rc = vdbeSorterCompare( |
| 70641 | pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res |
| 70642 | ); |
| 70643 | /* The vdbeSorterCompare() call cannot fail since pCsr->pSorter->aSpace |
| 70644 | ** has already been allocated. */ |
| 70645 | assert( rc==SQLITE_OK ); |
| 70646 | |
| 70647 | if( res<=0 ){ |
| 70648 | iRes = i1; |
| 70649 | }else{ |
| 70650 | iRes = i2; |
| 70651 | } |
| 70652 | } |
| 70653 | |
| 70654 | pSorter->aTree[iOut] = iRes; |
| 70655 | return SQLITE_OK; |
| 70656 | } |
| @@ -70547,13 +70657,41 @@ | |
| 70657 | |
| 70658 | /* |
| 70659 | ** Initialize the temporary index cursor just opened as a sorter cursor. |
| 70660 | */ |
| 70661 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ |
| 70662 | int pgsz; /* Page size of main database */ |
| 70663 | int mxCache; /* Cache size */ |
| 70664 | VdbeSorter *pSorter; /* The new sorter */ |
| 70665 | |
| 70666 | assert( pCsr->pKeyInfo && pCsr->pBt==0 ); |
| 70667 | pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); |
| 70668 | if( pSorter==0 ){ |
| 70669 | return SQLITE_NOMEM; |
| 70670 | } |
| 70671 | |
| 70672 | if( !sqlite3TempInMemory(db) ){ |
| 70673 | pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 70674 | pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; |
| 70675 | mxCache = db->aDb[0].pSchema->cache_size; |
| 70676 | if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; |
| 70677 | pSorter->mxPmaSize = mxCache * pgsz; |
| 70678 | } |
| 70679 | |
| 70680 | return SQLITE_OK; |
| 70681 | } |
| 70682 | |
| 70683 | /* |
| 70684 | ** Free the list of sorted records starting at pRecord. |
| 70685 | */ |
| 70686 | static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ |
| 70687 | SorterRecord *p; |
| 70688 | SorterRecord *pNext; |
| 70689 | for(p=pRecord; p; p=pNext){ |
| 70690 | pNext = p->pNext; |
| 70691 | sqlite3DbFree(db, p); |
| 70692 | } |
| 70693 | } |
| 70694 | |
| 70695 | /* |
| 70696 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 70697 | */ |
| @@ -70568,10 +70706,12 @@ | |
| 70706 | sqlite3DbFree(db, pSorter->aIter); |
| 70707 | } |
| 70708 | if( pSorter->pTemp1 ){ |
| 70709 | sqlite3OsCloseFree(pSorter->pTemp1); |
| 70710 | } |
| 70711 | vdbeSorterRecordFree(db, pSorter->pRecord); |
| 70712 | sqlite3_free(pSorter->aSpace); |
| 70713 | sqlite3DbFree(db, pSorter); |
| 70714 | pCsr->pSorter = 0; |
| 70715 | } |
| 70716 | } |
| 70717 | |
| @@ -70587,14 +70727,107 @@ | |
| 70727 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| 70728 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy |
| 70729 | ); |
| 70730 | } |
| 70731 | |
| 70732 | /* |
| 70733 | ** Attemp to merge the two sorted lists p1 and p2 into a single list. If no |
| 70734 | ** error occurs set *ppOut to the head of the new list and return SQLITE_OK. |
| 70735 | */ |
| 70736 | static int vdbeSorterMerge( |
| 70737 | sqlite3 *db, /* Database handle */ |
| 70738 | VdbeCursor *pCsr, /* For pKeyInfo */ |
| 70739 | SorterRecord *p1, /* First list to merge */ |
| 70740 | SorterRecord *p2, /* Second list to merge */ |
| 70741 | SorterRecord **ppOut /* OUT: Head of merged list */ |
| 70742 | ){ |
| 70743 | int rc = SQLITE_OK; |
| 70744 | SorterRecord *pFinal = 0; |
| 70745 | SorterRecord **pp = &pFinal; |
| 70746 | void *pVal2 = p2 ? p2->pVal : 0; |
| 70747 | |
| 70748 | while( p1 && p2 ){ |
| 70749 | int res; |
| 70750 | rc = vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); |
| 70751 | if( rc!=SQLITE_OK ){ |
| 70752 | *pp = 0; |
| 70753 | vdbeSorterRecordFree(db, p1); |
| 70754 | vdbeSorterRecordFree(db, p2); |
| 70755 | vdbeSorterRecordFree(db, pFinal); |
| 70756 | *ppOut = 0; |
| 70757 | return rc; |
| 70758 | } |
| 70759 | if( res<=0 ){ |
| 70760 | *pp = p1; |
| 70761 | pp = &p1->pNext; |
| 70762 | p1 = p1->pNext; |
| 70763 | pVal2 = 0; |
| 70764 | }else{ |
| 70765 | *pp = p2; |
| 70766 | pp = &p2->pNext; |
| 70767 | p2 = p2->pNext; |
| 70768 | if( p2==0 ) break; |
| 70769 | pVal2 = p2->pVal; |
| 70770 | } |
| 70771 | } |
| 70772 | *pp = p1 ? p1 : p2; |
| 70773 | |
| 70774 | *ppOut = pFinal; |
| 70775 | return SQLITE_OK; |
| 70776 | } |
| 70777 | |
| 70778 | /* |
| 70779 | ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 70780 | ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 70781 | ** occurs. |
| 70782 | */ |
| 70783 | static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ |
| 70784 | int rc = SQLITE_OK; |
| 70785 | int i; |
| 70786 | SorterRecord **aSlot; |
| 70787 | SorterRecord *p; |
| 70788 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70789 | |
| 70790 | aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); |
| 70791 | if( !aSlot ){ |
| 70792 | return SQLITE_NOMEM; |
| 70793 | } |
| 70794 | |
| 70795 | p = pSorter->pRecord; |
| 70796 | while( p ){ |
| 70797 | SorterRecord *pNext = p->pNext; |
| 70798 | p->pNext = 0; |
| 70799 | for(i=0; rc==SQLITE_OK && aSlot[i]; i++){ |
| 70800 | rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); |
| 70801 | aSlot[i] = 0; |
| 70802 | } |
| 70803 | if( rc!=SQLITE_OK ){ |
| 70804 | vdbeSorterRecordFree(db, pNext); |
| 70805 | break; |
| 70806 | } |
| 70807 | aSlot[i] = p; |
| 70808 | p = pNext; |
| 70809 | } |
| 70810 | |
| 70811 | p = 0; |
| 70812 | for(i=0; i<64; i++){ |
| 70813 | if( rc==SQLITE_OK ){ |
| 70814 | rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); |
| 70815 | }else{ |
| 70816 | vdbeSorterRecordFree(db, aSlot[i]); |
| 70817 | } |
| 70818 | } |
| 70819 | pSorter->pRecord = p; |
| 70820 | |
| 70821 | sqlite3_free(aSlot); |
| 70822 | return rc; |
| 70823 | } |
| 70824 | |
| 70825 | |
| 70826 | /* |
| 70827 | ** Write the current contents of the in-memory linked-list to a PMA. Return |
| 70828 | ** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 70829 | ** |
| 70830 | ** The format of a PMA is: |
| 70831 | ** |
| 70832 | ** * A varint. This varint contains the total number of bytes of content |
| 70833 | ** in the PMA (not including the varint itself). |
| @@ -70601,153 +70834,111 @@ | |
| 70834 | ** |
| 70835 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70836 | ** Each record consists of a varint followed by a blob of data (the |
| 70837 | ** key). The varint is the number of bytes in the blob of data. |
| 70838 | */ |
| 70839 | static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ |
| 70840 | int rc = SQLITE_OK; /* Return code */ |
| 70841 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70842 | |
| 70843 | if( pSorter->nInMemory==0 ){ |
| 70844 | assert( pSorter->pRecord==0 ); |
| 70845 | return rc; |
| 70846 | } |
| 70847 | |
| 70848 | rc = vdbeSorterSort(db, pCsr); |
| 70849 | |
| 70850 | /* If the first temporary PMA file has not been opened, open it now. */ |
| 70851 | if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ |
| 70852 | rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); |
| 70853 | assert( rc!=SQLITE_OK || pSorter->pTemp1 ); |
| 70854 | assert( pSorter->iWriteOff==0 ); |
| 70855 | assert( pSorter->nPMA==0 ); |
| 70856 | } |
| 70857 | |
| 70858 | if( rc==SQLITE_OK ){ |
| 70859 | i64 iOff = pSorter->iWriteOff; |
| 70860 | SorterRecord *p; |
| 70861 | SorterRecord *pNext = 0; |
| 70862 | static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 70863 | |
| 70864 | pSorter->nPMA++; |
| 70865 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); |
| 70866 | for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ |
| 70867 | pNext = p->pNext; |
| 70868 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); |
| 70869 | |
| 70870 | if( rc==SQLITE_OK ){ |
| 70871 | rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); |
| 70872 | iOff += p->nVal; |
| 70873 | } |
| 70874 | |
| 70875 | sqlite3DbFree(db, p); |
| 70876 | } |
| 70877 | |
| 70878 | /* This assert verifies that unless an error has occurred, the size of |
| 70879 | ** the PMA on disk is the same as the expected size stored in |
| 70880 | ** pSorter->nInMemory. */ |
| 70881 | assert( rc!=SQLITE_OK || pSorter->nInMemory==( |
| 70882 | iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) |
| 70883 | )); |
| 70884 | |
| 70885 | pSorter->iWriteOff = iOff; |
| 70886 | if( rc==SQLITE_OK ){ |
| 70887 | /* Terminate each file with 8 extra bytes so that from any offset |
| 70888 | ** in the file we can always read 9 bytes without a SHORT_READ error */ |
| 70889 | rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); |
| 70890 | } |
| 70891 | pSorter->pRecord = p; |
| 70892 | } |
| 70893 | |
| 70894 | return rc; |
| 70895 | } |
| 70896 | |
| 70897 | /* |
| 70898 | ** Add a record to the sorter. |
| 70899 | */ |
| 70900 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 70901 | sqlite3 *db, /* Database handle */ |
| 70902 | VdbeCursor *pCsr, /* Sorter cursor */ |
| 70903 | Mem *pVal /* Memory cell containing record */ |
| 70904 | ){ |
| 70905 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70906 | int rc = SQLITE_OK; /* Return Code */ |
| 70907 | SorterRecord *pNew; /* New list element */ |
| 70908 | |
| 70909 | assert( pSorter ); |
| 70910 | pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; |
| 70911 | |
| 70912 | pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); |
| 70913 | if( pNew==0 ){ |
| 70914 | rc = SQLITE_NOMEM; |
| 70915 | }else{ |
| 70916 | pNew->pVal = (void *)&pNew[1]; |
| 70917 | memcpy(pNew->pVal, pVal->z, pVal->n); |
| 70918 | pNew->nVal = pVal->n; |
| 70919 | pNew->pNext = pSorter->pRecord; |
| 70920 | pSorter->pRecord = pNew; |
| 70921 | } |
| 70922 | |
| 70923 | /* See if the contents of the sorter should now be written out. They |
| 70924 | ** are written out when either of the following are true: |
| 70925 | ** |
| 70926 | ** * The total memory allocated for the in-memory list is greater |
| 70927 | ** than (page-size * cache-size), or |
| 70928 | ** |
| 70929 | ** * The total memory allocated for the in-memory list is greater |
| 70930 | ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. |
| 70931 | */ |
| 70932 | if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 70933 | (pSorter->nInMemory>pSorter->mxPmaSize) |
| 70934 | || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 70935 | )){ |
| 70936 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70937 | pSorter->nInMemory = 0; |
| 70938 | } |
| 70939 | |
| 70940 | return rc; |
| 70941 | } |
| 70942 | |
| 70943 | /* |
| 70944 | ** Helper function for sqlite3VdbeSorterRewind(). |
| @@ -70761,16 +70952,16 @@ | |
| 70952 | int rc = SQLITE_OK; /* Return code */ |
| 70953 | int i; /* Used to iterator through aIter[] */ |
| 70954 | i64 nByte = 0; /* Total bytes in all opened PMAs */ |
| 70955 | |
| 70956 | /* Initialize the iterators. */ |
| 70957 | for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){ |
| 70958 | VdbeSorterIter *pIter = &pSorter->aIter[i]; |
| 70959 | rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); |
| 70960 | pSorter->iReadOff = pIter->iEof; |
| 70961 | assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff ); |
| 70962 | if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break; |
| 70963 | } |
| 70964 | |
| 70965 | /* Initialize the aTree[] array. */ |
| 70966 | for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ |
| 70967 | rc = vdbeSorterDoCompare(pCsr, i); |
| @@ -70793,18 +70984,22 @@ | |
| 70984 | int nByte; /* Bytes of space required for aIter/aTree */ |
| 70985 | int N = 2; /* Power of 2 >= nIter */ |
| 70986 | |
| 70987 | assert( pSorter ); |
| 70988 | |
| 70989 | /* If no data has been written to disk, then do not do so now. Instead, |
| 70990 | ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly |
| 70991 | ** from the in-memory list. */ |
| 70992 | if( pSorter->nPMA==0 ){ |
| 70993 | *pbEof = !pSorter->pRecord; |
| 70994 | assert( pSorter->aTree==0 ); |
| 70995 | return vdbeSorterSort(db, pCsr); |
| 70996 | } |
| 70997 | |
| 70998 | /* Write the current b-tree to a PMA. Close the b-tree cursor. */ |
| 70999 | rc = vdbeSorterListToPMA(db, pCsr); |
| 71000 | if( rc!=SQLITE_OK ) return rc; |
| 71001 | |
| 71002 | /* Allocate space for aIter[] and aTree[]. */ |
| 71003 | nIter = pSorter->nPMA; |
| 71004 | if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; |
| 71005 | assert( nIter>0 ); |
| @@ -70888,47 +71083,96 @@ | |
| 71083 | /* |
| 71084 | ** Advance to the next element in the sorter. |
| 71085 | */ |
| 71086 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 71087 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71088 | int rc; /* Return code */ |
| 71089 | |
| 71090 | if( pSorter->aTree ){ |
| 71091 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| 71092 | int i; /* Index of aTree[] to recalculate */ |
| 71093 | |
| 71094 | rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 71095 | for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ |
| 71096 | rc = vdbeSorterDoCompare(pCsr, i); |
| 71097 | } |
| 71098 | |
| 71099 | *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 71100 | }else{ |
| 71101 | SorterRecord *pFree = pSorter->pRecord; |
| 71102 | pSorter->pRecord = pFree->pNext; |
| 71103 | pFree->pNext = 0; |
| 71104 | vdbeSorterRecordFree(db, pFree); |
| 71105 | *pbEof = !pSorter->pRecord; |
| 71106 | rc = SQLITE_OK; |
| 71107 | } |
| 71108 | return rc; |
| 71109 | } |
| 71110 | |
| 71111 | /* |
| 71112 | ** Return a pointer to a buffer owned by the sorter that contains the |
| 71113 | ** current key. |
| 71114 | */ |
| 71115 | static void *vdbeSorterRowkey( |
| 71116 | VdbeSorter *pSorter, /* Sorter object */ |
| 71117 | int *pnKey /* OUT: Size of current key in bytes */ |
| 71118 | ){ |
| 71119 | void *pKey; |
| 71120 | if( pSorter->aTree ){ |
| 71121 | VdbeSorterIter *pIter; |
| 71122 | pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 71123 | *pnKey = pIter->nKey; |
| 71124 | pKey = pIter->aKey; |
| 71125 | }else{ |
| 71126 | *pnKey = pSorter->pRecord->nVal; |
| 71127 | pKey = pSorter->pRecord->pVal; |
| 71128 | } |
| 71129 | return pKey; |
| 71130 | } |
| 71131 | |
| 71132 | /* |
| 71133 | ** Copy the current sorter key into the memory cell pOut. |
| 71134 | */ |
| 71135 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ |
| 71136 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71137 | void *pKey; int nKey; /* Sorter key to copy into pOut */ |
| 71138 | |
| 71139 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 71140 | if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ |
| 71141 | return SQLITE_NOMEM; |
| 71142 | } |
| 71143 | pOut->n = nKey; |
| 71144 | MemSetTypeFlag(pOut, MEM_Blob); |
| 71145 | memcpy(pOut->z, pKey, nKey); |
| 71146 | |
| 71147 | return SQLITE_OK; |
| 71148 | } |
| 71149 | |
| 71150 | /* |
| 71151 | ** Compare the key in memory cell pVal with the key that the sorter cursor |
| 71152 | ** passed as the first argument currently points to. For the purposes of |
| 71153 | ** the comparison, ignore the rowid field at the end of each record. |
| 71154 | ** |
| 71155 | ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). |
| 71156 | ** Otherwise, set *pRes to a negative, zero or positive value if the |
| 71157 | ** key in pVal is smaller than, equal to or larger than the current sorter |
| 71158 | ** key. |
| 71159 | */ |
| 71160 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 71161 | VdbeCursor *pCsr, /* Sorter cursor */ |
| 71162 | Mem *pVal, /* Value to compare to current sorter key */ |
| 71163 | int *pRes /* OUT: Result of comparison */ |
| 71164 | ){ |
| 71165 | int rc; |
| 71166 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71167 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 71168 | |
| 71169 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 71170 | rc = vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); |
| 71171 | assert( rc!=SQLITE_OK || pVal->db->mallocFailed || (*pRes)<=0 ); |
| 71172 | return rc; |
| 71173 | } |
| 71174 | |
| 71175 | #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ |
| 71176 | |
| 71177 | /************** End of vdbesort.c ********************************************/ |
| 71178 | /************** Begin file journal.c *****************************************/ |
| @@ -75077,11 +75321,11 @@ | |
| 75321 | if( !pAggInfo->directMode ){ |
| 75322 | assert( pCol->iMem>0 ); |
| 75323 | inReg = pCol->iMem; |
| 75324 | break; |
| 75325 | }else if( pAggInfo->useSortingIdx ){ |
| 75326 | sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, |
| 75327 | pCol->iSorterColumn, target); |
| 75328 | break; |
| 75329 | } |
| 75330 | /* Otherwise, fall thru into the TK_COLUMN case */ |
| 75331 | } |
| @@ -81235,27 +81479,19 @@ | |
| 81479 | Table *pTab = pIndex->pTable; /* The table that is indexed */ |
| 81480 | int iTab = pParse->nTab++; /* Btree cursor used for pTab */ |
| 81481 | int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ |
| 81482 | int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ |
| 81483 | int addr1; /* Address of top of loop */ |
| 81484 | int addr2; /* Address to jump to for next iteration */ |
| 81485 | int tnum; /* Root page of index */ |
| 81486 | Vdbe *v; /* Generate code into this virtual machine */ |
| 81487 | KeyInfo *pKey; /* KeyInfo for index */ |
| 81488 | int regIdxKey; /* Registers containing the index key */ |
| 81489 | int regRecord; /* Register holding assemblied index record */ |
| 81490 | sqlite3 *db = pParse->db; /* The database connection */ |
| 81491 | int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); |
| 81492 | |
| 81493 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 81494 | if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, |
| 81495 | db->aDb[iDb].zName ) ){ |
| 81496 | return; |
| 81497 | } |
| @@ -81277,32 +81513,44 @@ | |
| 81513 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81514 | if( memRootPage>=0 ){ |
| 81515 | sqlite3VdbeChangeP5(v, 1); |
| 81516 | } |
| 81517 | |
| 81518 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 81519 | /* Open the sorter cursor if we are to use one. */ |
| 81520 | iSorter = pParse->nTab++; |
| 81521 | sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| 81522 | #endif |
| 81523 | |
| 81524 | /* Open the table. Loop through all rows of the table, inserting index |
| 81525 | ** records into the sorter. */ |
| 81526 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| 81527 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); |
| 81528 | addr2 = addr1 + 1; |
| 81529 | regRecord = sqlite3GetTempReg(pParse); |
| 81530 | regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); |
| 81531 | |
| 81532 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 81533 | sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 81534 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); |
| 81535 | sqlite3VdbeJumpHere(v, addr1); |
| 81536 | addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); |
| 81537 | if( pIndex->onError!=OE_None ){ |
| 81538 | int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 81539 | sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 81540 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 81541 | sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); |
| 81542 | sqlite3HaltConstraint( |
| 81543 | pParse, OE_Abort, "indexed columns are not unique", P4_STATIC |
| 81544 | ); |
| 81545 | }else{ |
| 81546 | addr2 = sqlite3VdbeCurrentAddr(v); |
| 81547 | } |
| 81548 | sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| 81549 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); |
| 81550 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81551 | #else |
| 81552 | if( pIndex->onError!=OE_None ){ |
| 81553 | const int regRowid = regIdxKey + pIndex->nColumn; |
| 81554 | const int j2 = sqlite3VdbeCurrentAddr(v) + 2; |
| 81555 | void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); |
| 81556 | |
| @@ -81317,14 +81565,15 @@ | |
| 81565 | */ |
| 81566 | sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); |
| 81567 | sqlite3HaltConstraint( |
| 81568 | pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); |
| 81569 | } |
| 81570 | sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); |
| 81571 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81572 | #endif |
| 81573 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 81574 | sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); |
| 81575 | sqlite3VdbeJumpHere(v, addr1); |
| 81576 | |
| 81577 | sqlite3VdbeAddOp1(v, OP_Close, iTab); |
| 81578 | sqlite3VdbeAddOp1(v, OP_Close, iIdx); |
| 81579 | sqlite3VdbeAddOp1(v, OP_Close, iSorter); |
| @@ -92534,16 +92783,22 @@ | |
| 92783 | ){ |
| 92784 | Vdbe *v = pParse->pVdbe; |
| 92785 | int nExpr = pOrderBy->nExpr; |
| 92786 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 92787 | int regRecord = sqlite3GetTempReg(pParse); |
| 92788 | int op; |
| 92789 | sqlite3ExprCacheClear(pParse); |
| 92790 | sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 92791 | sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 92792 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 92793 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 92794 | if( pSelect->selFlags & SF_UseSorter ){ |
| 92795 | op = OP_SorterInsert; |
| 92796 | }else{ |
| 92797 | op = OP_IdxInsert; |
| 92798 | } |
| 92799 | sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); |
| 92800 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 92801 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 92802 | if( pSelect->iLimit ){ |
| 92803 | int addr1, addr2; |
| 92804 | int iLimit; |
| @@ -93008,13 +93263,24 @@ | |
| 93263 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 93264 | regRowid = 0; |
| 93265 | }else{ |
| 93266 | regRowid = sqlite3GetTempReg(pParse); |
| 93267 | } |
| 93268 | if( p->selFlags & SF_UseSorter ){ |
| 93269 | int regSortOut = ++pParse->nMem; |
| 93270 | int ptab2 = pParse->nTab++; |
| 93271 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); |
| 93272 | addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 93273 | codeOffset(v, p, addrContinue); |
| 93274 | sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 93275 | sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); |
| 93276 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 93277 | }else{ |
| 93278 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); |
| 93279 | codeOffset(v, p, addrContinue); |
| 93280 | sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); |
| 93281 | } |
| 93282 | switch( eDest ){ |
| 93283 | case SRT_Table: |
| 93284 | case SRT_EphemTab: { |
| 93285 | testcase( eDest==SRT_Table ); |
| 93286 | testcase( eDest==SRT_EphemTab ); |
| @@ -93063,11 +93329,15 @@ | |
| 93329 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 93330 | |
| 93331 | /* The bottom of the loop |
| 93332 | */ |
| 93333 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 93334 | if( p->selFlags & SF_UseSorter ){ |
| 93335 | sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); |
| 93336 | }else{ |
| 93337 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); |
| 93338 | } |
| 93339 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 93340 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 93341 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 93342 | } |
| 93343 | } |
| @@ -96029,10 +96299,14 @@ | |
| 96299 | /* Set the limiter. |
| 96300 | */ |
| 96301 | iEnd = sqlite3VdbeMakeLabel(v); |
| 96302 | p->nSelectRow = (double)LARGEST_INT64; |
| 96303 | computeLimitRegisters(pParse, p, iEnd); |
| 96304 | if( p->iLimit==0 && addrSortIndex>=0 ){ |
| 96305 | sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; |
| 96306 | p->selFlags |= SF_UseSorter; |
| 96307 | } |
| 96308 | |
| 96309 | /* Open a virtual index to use for the distinct set. |
| 96310 | */ |
| 96311 | if( p->selFlags & SF_Distinct ){ |
| 96312 | KeyInfo *pKeyInfo; |
| @@ -96064,11 +96338,11 @@ | |
| 96338 | } |
| 96339 | |
| 96340 | if( pWInfo->eDistinct ){ |
| 96341 | VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 96342 | |
| 96343 | assert( addrDistinctIndex>=0 ); |
| 96344 | pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); |
| 96345 | |
| 96346 | assert( isDistinct ); |
| 96347 | assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED |
| 96348 | || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE |
| @@ -96123,10 +96397,12 @@ | |
| 96397 | ** one row of the input to the aggregator has been |
| 96398 | ** processed */ |
| 96399 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 96400 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 96401 | int addrEnd; /* End of processing for this SELECT */ |
| 96402 | int sortPTab = 0; /* Pseudotable used to decode sorting results */ |
| 96403 | int sortOut = 0; /* Output register from the sorter */ |
| 96404 | |
| 96405 | /* Remove any and all aliases between the result set and the |
| 96406 | ** GROUP BY clause. |
| 96407 | */ |
| 96408 | if( pGroupBy ){ |
| @@ -96184,16 +96460,16 @@ | |
| 96460 | int addrReset; /* Subroutine for resetting the accumulator */ |
| 96461 | int regReset; /* Return address register for reset subroutine */ |
| 96462 | |
| 96463 | /* If there is a GROUP BY clause we might need a sorting index to |
| 96464 | ** implement it. Allocate that sorting index now. If it turns out |
| 96465 | ** that we do not need it after all, the OP_SorterOpen instruction |
| 96466 | ** will be converted into a Noop. |
| 96467 | */ |
| 96468 | sAggInfo.sortingIdx = pParse->nTab++; |
| 96469 | pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); |
| 96470 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, |
| 96471 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 96472 | 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); |
| 96473 | |
| 96474 | /* Initialize memory locations used by GROUP BY aggregate processing |
| 96475 | */ |
| @@ -96270,15 +96546,18 @@ | |
| 96546 | j++; |
| 96547 | } |
| 96548 | } |
| 96549 | regRecord = sqlite3GetTempReg(pParse); |
| 96550 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); |
| 96551 | sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); |
| 96552 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 96553 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 96554 | sqlite3WhereEnd(pWInfo); |
| 96555 | sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; |
| 96556 | sortOut = sqlite3GetTempReg(pParse); |
| 96557 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 96558 | sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); |
| 96559 | VdbeComment((v, "GROUP BY sort")); |
| 96560 | sAggInfo.useSortingIdx = 1; |
| 96561 | sqlite3ExprCacheClear(pParse); |
| 96562 | } |
| 96563 | |
| @@ -96287,13 +96566,17 @@ | |
| 96566 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| 96567 | ** from the previous row currently stored in a0, a1, a2... |
| 96568 | */ |
| 96569 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 96570 | sqlite3ExprCacheClear(pParse); |
| 96571 | if( groupBySort ){ |
| 96572 | sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); |
| 96573 | } |
| 96574 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 96575 | if( groupBySort ){ |
| 96576 | sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 96577 | if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 96578 | }else{ |
| 96579 | sAggInfo.directMode = 1; |
| 96580 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 96581 | } |
| 96582 | } |
| @@ -96328,11 +96611,11 @@ | |
| 96611 | VdbeComment((v, "indicate data in accumulator")); |
| 96612 | |
| 96613 | /* End of the loop |
| 96614 | */ |
| 96615 | if( groupBySort ){ |
| 96616 | sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); |
| 96617 | }else{ |
| 96618 | sqlite3WhereEnd(pWInfo); |
| 96619 | sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); |
| 96620 | } |
| 96621 | |
| 96622 |
+1
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.8" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007008 |
| 112 | -#define SQLITE_SOURCE_ID "2011-08-29 11:56:14 639cc85a911454bffdcccb33f2976c683953ae64" | |
| 112 | +#define SQLITE_SOURCE_ID "2011-09-04 01:27:00 6b657ae75035eb10b0ad640998d3c9eadfdffa6e" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3007008 |
| 112 | #define SQLITE_SOURCE_ID "2011-08-29 11:56:14 639cc85a911454bffdcccb33f2976c683953ae64" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3007008 |
| 112 | #define SQLITE_SOURCE_ID "2011-09-04 01:27:00 6b657ae75035eb10b0ad640998d3c9eadfdffa6e" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |