| | @@ -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-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177" |
| 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*); |
| | @@ -8383,106 +8374,109 @@ |
| 8383 | 8374 | #define OP_Jump 25 |
| 8384 | 8375 | #define OP_And 69 /* same as TK_AND */ |
| 8385 | 8376 | #define OP_Or 68 /* same as TK_OR */ |
| 8386 | 8377 | #define OP_Not 19 /* same as TK_NOT */ |
| 8387 | 8378 | #define OP_BitNot 93 /* same as TK_BITNOT */ |
| 8388 | | -#define OP_If 26 |
| 8389 | | -#define OP_IfNot 27 |
| 8379 | +#define OP_Once 26 |
| 8380 | +#define OP_If 27 |
| 8381 | +#define OP_IfNot 28 |
| 8390 | 8382 | #define OP_IsNull 73 /* same as TK_ISNULL */ |
| 8391 | 8383 | #define OP_NotNull 74 /* same as TK_NOTNULL */ |
| 8392 | | -#define OP_Column 28 |
| 8393 | | -#define OP_Affinity 29 |
| 8394 | | -#define OP_MakeRecord 30 |
| 8395 | | -#define OP_Count 31 |
| 8396 | | -#define OP_Savepoint 32 |
| 8397 | | -#define OP_AutoCommit 33 |
| 8398 | | -#define OP_Transaction 34 |
| 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 |
| 8384 | +#define OP_Column 29 |
| 8385 | +#define OP_Affinity 30 |
| 8386 | +#define OP_MakeRecord 31 |
| 8387 | +#define OP_Count 32 |
| 8388 | +#define OP_Savepoint 33 |
| 8389 | +#define OP_AutoCommit 34 |
| 8390 | +#define OP_Transaction 35 |
| 8391 | +#define OP_ReadCookie 36 |
| 8392 | +#define OP_SetCookie 37 |
| 8393 | +#define OP_VerifyCookie 38 |
| 8394 | +#define OP_OpenRead 39 |
| 8395 | +#define OP_OpenWrite 40 |
| 8405 | 8396 | #define OP_OpenAutoindex 41 |
| 8406 | 8397 | #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 |
| 8412 | | -#define OP_SeekGt 48 |
| 8413 | | -#define OP_Seek 49 |
| 8414 | | -#define OP_NotFound 50 |
| 8415 | | -#define OP_Found 51 |
| 8416 | | -#define OP_IsUnique 52 |
| 8417 | | -#define OP_NotExists 53 |
| 8418 | | -#define OP_Sequence 54 |
| 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 |
| 8398 | +#define OP_SorterOpen 43 |
| 8399 | +#define OP_OpenPseudo 44 |
| 8400 | +#define OP_Close 45 |
| 8401 | +#define OP_SeekLt 46 |
| 8402 | +#define OP_SeekLe 47 |
| 8403 | +#define OP_SeekGe 48 |
| 8404 | +#define OP_SeekGt 49 |
| 8405 | +#define OP_Seek 50 |
| 8406 | +#define OP_NotFound 51 |
| 8407 | +#define OP_Found 52 |
| 8408 | +#define OP_IsUnique 53 |
| 8409 | +#define OP_NotExists 54 |
| 8410 | +#define OP_Sequence 55 |
| 8411 | +#define OP_NewRowid 56 |
| 8412 | +#define OP_Insert 57 |
| 8413 | +#define OP_InsertInt 58 |
| 8414 | +#define OP_Delete 59 |
| 8415 | +#define OP_ResetCount 60 |
| 8416 | +#define OP_SorterCompare 61 |
| 8417 | +#define OP_SorterData 62 |
| 8418 | +#define OP_RowKey 63 |
| 8419 | +#define OP_RowData 64 |
| 8420 | +#define OP_Rowid 65 |
| 8421 | +#define OP_NullRow 66 |
| 8422 | +#define OP_Last 67 |
| 8423 | +#define OP_SorterSort 70 |
| 8424 | +#define OP_Sort 71 |
| 8425 | +#define OP_Rewind 72 |
| 8426 | +#define OP_SorterNext 81 |
| 8427 | +#define OP_Prev 92 |
| 8428 | +#define OP_Next 95 |
| 8429 | +#define OP_SorterInsert 96 |
| 8430 | +#define OP_IdxInsert 97 |
| 8431 | +#define OP_IdxDelete 98 |
| 8432 | +#define OP_IdxRowid 99 |
| 8433 | +#define OP_IdxLT 100 |
| 8434 | +#define OP_IdxGE 101 |
| 8435 | +#define OP_Destroy 102 |
| 8436 | +#define OP_Clear 103 |
| 8437 | +#define OP_CreateIndex 104 |
| 8438 | +#define OP_CreateTable 105 |
| 8439 | +#define OP_ParseSchema 106 |
| 8440 | +#define OP_LoadAnalysis 107 |
| 8441 | +#define OP_DropTable 108 |
| 8442 | +#define OP_DropIndex 109 |
| 8443 | +#define OP_DropTrigger 110 |
| 8444 | +#define OP_IntegrityCk 111 |
| 8445 | +#define OP_RowSetAdd 112 |
| 8446 | +#define OP_RowSetRead 113 |
| 8447 | +#define OP_RowSetTest 114 |
| 8448 | +#define OP_Program 115 |
| 8449 | +#define OP_Param 116 |
| 8450 | +#define OP_FkCounter 117 |
| 8451 | +#define OP_FkIfZero 118 |
| 8452 | +#define OP_MemMax 119 |
| 8453 | +#define OP_IfPos 120 |
| 8454 | +#define OP_IfNeg 121 |
| 8455 | +#define OP_IfZero 122 |
| 8456 | +#define OP_AggStep 123 |
| 8457 | +#define OP_AggFinal 124 |
| 8458 | +#define OP_Checkpoint 125 |
| 8459 | +#define OP_JournalMode 126 |
| 8460 | +#define OP_Vacuum 127 |
| 8461 | +#define OP_IncrVacuum 128 |
| 8462 | +#define OP_Expire 129 |
| 8463 | +#define OP_TableLock 131 |
| 8464 | +#define OP_VBegin 132 |
| 8465 | +#define OP_VCreate 133 |
| 8466 | +#define OP_VDestroy 134 |
| 8467 | +#define OP_VOpen 135 |
| 8468 | +#define OP_VFilter 136 |
| 8469 | +#define OP_VColumn 137 |
| 8470 | +#define OP_VNext 138 |
| 8471 | +#define OP_VRename 139 |
| 8472 | +#define OP_VUpdate 140 |
| 8473 | +#define OP_Pagecount 146 |
| 8474 | +#define OP_MaxPgcnt 147 |
| 8475 | +#define OP_Trace 148 |
| 8476 | +#define OP_Noop 149 |
| 8477 | +#define OP_Explain 150 |
| 8484 | 8478 | |
| 8485 | 8479 | |
| 8486 | 8480 | /* Properties such as "out2" or "jump" that are specified in |
| 8487 | 8481 | ** comments following the "case" for each opcode in the vdbe.c |
| 8488 | 8482 | ** are encoded into bitvectors as follows: |
| | @@ -8496,26 +8490,26 @@ |
| 8496 | 8490 | #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ |
| 8497 | 8491 | #define OPFLG_INITIALIZER {\ |
| 8498 | 8492 | /* 0 */ 0x00, 0x01, 0x05, 0x04, 0x04, 0x10, 0x00, 0x02,\ |
| 8499 | 8493 | /* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ |
| 8500 | 8494 | /* 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,\ |
| 8495 | +/* 24 */ 0x00, 0x01, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ |
| 8496 | +/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ |
| 8497 | +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ |
| 8498 | +/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ |
| 8499 | +/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 8500 | +/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ |
| 8501 | +/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ |
| 8502 | +/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ |
| 8509 | 8503 | /* 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,} |
| 8504 | +/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ |
| 8505 | +/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 8506 | +/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ |
| 8507 | +/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\ |
| 8508 | +/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 8509 | +/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\ |
| 8510 | +/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,} |
| 8517 | 8511 | |
| 8518 | 8512 | /************** End of opcodes.h *********************************************/ |
| 8519 | 8513 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 8520 | 8514 | |
| 8521 | 8515 | /* |
| | @@ -8534,11 +8528,11 @@ |
| 8534 | 8528 | SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); |
| 8535 | 8529 | SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); |
| 8536 | 8530 | SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); |
| 8537 | 8531 | SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); |
| 8538 | 8532 | SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); |
| 8539 | | -SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N); |
| 8533 | +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr); |
| 8540 | 8534 | SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); |
| 8541 | 8535 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); |
| 8542 | 8536 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8543 | 8537 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8544 | 8538 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| | @@ -8566,13 +8560,13 @@ |
| 8566 | 8560 | SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); |
| 8567 | 8561 | #ifndef SQLITE_OMIT_TRACE |
| 8568 | 8562 | SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); |
| 8569 | 8563 | #endif |
| 8570 | 8564 | |
| 8571 | | -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int); |
| 8572 | | -SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); |
| 8565 | +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); |
| 8573 | 8566 | SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| 8567 | +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); |
| 8574 | 8568 | |
| 8575 | 8569 | #ifndef SQLITE_OMIT_TRIGGER |
| 8576 | 8570 | SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); |
| 8577 | 8571 | #endif |
| 8578 | 8572 | |
| | @@ -8653,11 +8647,10 @@ |
| 8653 | 8647 | ** NOTE: These values must match the corresponding BTREE_ values in btree.h. |
| 8654 | 8648 | */ |
| 8655 | 8649 | #define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ |
| 8656 | 8650 | #define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ |
| 8657 | 8651 | #define PAGER_MEMORY 0x0004 /* In-memory database */ |
| 8658 | | -#define PAGER_SORTER 0x0020 /* Accumulator in external merge sort */ |
| 8659 | 8652 | |
| 8660 | 8653 | /* |
| 8661 | 8654 | ** Valid values for the second argument to sqlite3PagerLockingMode(). |
| 8662 | 8655 | */ |
| 8663 | 8656 | #define PAGER_LOCKINGMODE_QUERY -1 |
| | @@ -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 */ |
| | @@ -10495,11 +10486,12 @@ |
| 10495 | 10486 | char *zDatabase; /* Name of database holding this table */ |
| 10496 | 10487 | char *zName; /* Name of the table */ |
| 10497 | 10488 | char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ |
| 10498 | 10489 | Table *pTab; /* An SQL table corresponding to zName */ |
| 10499 | 10490 | Select *pSelect; /* A SELECT statement used in place of a table name */ |
| 10500 | | - u8 isPopulated; /* Temporary table associated with SELECT is populated */ |
| 10491 | + int addrFillSub; /* Address of subroutine to manifest a subquery */ |
| 10492 | + int regReturn; /* Register holding return address of addrFillSub */ |
| 10501 | 10493 | u8 jointype; /* Type of join between this able and the previous */ |
| 10502 | 10494 | u8 notIndexed; /* True if there is a NOT INDEXED clause */ |
| 10503 | 10495 | u8 isCorrelated; /* True if sub-query is correlated */ |
| 10504 | 10496 | #ifndef SQLITE_OMIT_EXPLAIN |
| 10505 | 10497 | u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ |
| | @@ -10718,10 +10710,11 @@ |
| 10718 | 10710 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ |
| 10719 | 10711 | #define SF_Aggregate 0x0004 /* Contains aggregate functions */ |
| 10720 | 10712 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 10721 | 10713 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 10722 | 10714 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 10715 | +#define SF_UseSorter 0x0040 /* Sort using a sorter */ |
| 10723 | 10716 | |
| 10724 | 10717 | |
| 10725 | 10718 | /* |
| 10726 | 10719 | ** The results of a select can be distributed in several ways. The |
| 10727 | 10720 | ** "SRT" prefix means "SELECT Result Type". |
| | @@ -12044,11 +12037,11 @@ |
| 12044 | 12037 | SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ |
| 12045 | 12038 | 1, /* bCoreMutex */ |
| 12046 | 12039 | SQLITE_THREADSAFE==1, /* bFullMutex */ |
| 12047 | 12040 | SQLITE_USE_URI, /* bOpenUri */ |
| 12048 | 12041 | 0x7ffffffe, /* mxStrlen */ |
| 12049 | | - 100, /* szLookaside */ |
| 12042 | + 128, /* szLookaside */ |
| 12050 | 12043 | 500, /* nLookaside */ |
| 12051 | 12044 | {0,0,0,0,0,0,0,0}, /* m */ |
| 12052 | 12045 | {0,0,0,0,0,0,0,0,0}, /* mutex */ |
| 12053 | 12046 | {0,0,0,0,0,0,0,0,0,0,0}, /* pcache */ |
| 12054 | 12047 | (void*)0, /* pHeap */ |
| | @@ -12267,10 +12260,13 @@ |
| 12267 | 12260 | "INT64_TYPE", |
| 12268 | 12261 | #endif |
| 12269 | 12262 | #ifdef SQLITE_LOCK_TRACE |
| 12270 | 12263 | "LOCK_TRACE", |
| 12271 | 12264 | #endif |
| 12265 | +#ifdef SQLITE_MAX_SCHEMA_RETRY |
| 12266 | + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 12267 | +#endif |
| 12272 | 12268 | #ifdef SQLITE_MEMDEBUG |
| 12273 | 12269 | "MEMDEBUG", |
| 12274 | 12270 | #endif |
| 12275 | 12271 | #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 12276 | 12272 | "MIXED_ENDIAN_64BIT_FLOAT", |
| | @@ -12601,16 +12597,17 @@ |
| 12601 | 12597 | Bool nullRow; /* True if pointing to a row with no data */ |
| 12602 | 12598 | Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 12603 | 12599 | Bool isTable; /* True if a table requiring integer keys */ |
| 12604 | 12600 | Bool isIndex; /* True if an index containing keys only - no data */ |
| 12605 | 12601 | Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ |
| 12602 | + Bool isSorter; /* True if a new-style sorter */ |
| 12606 | 12603 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 12607 | 12604 | const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ |
| 12608 | 12605 | i64 seqCount; /* Sequence counter */ |
| 12609 | 12606 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 12610 | 12607 | i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ |
| 12611 | | - VdbeSorter *pSorter; /* Sorter object for OP_OpenSorter cursors */ |
| 12608 | + VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 12612 | 12609 | |
| 12613 | 12610 | /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or |
| 12614 | 12611 | ** OP_IsUnique opcode on this cursor. */ |
| 12615 | 12612 | int seekResult; |
| 12616 | 12613 | |
| | @@ -12944,17 +12941,19 @@ |
| 12944 | 12941 | # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK |
| 12945 | 12942 | # define sqlite3VdbeSorterClose(Y,Z) |
| 12946 | 12943 | # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK |
| 12947 | 12944 | # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK |
| 12948 | 12945 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 12946 | +# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK |
| 12949 | 12947 | #else |
| 12950 | 12948 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 12951 | | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, int); |
| 12952 | 12949 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 12953 | 12950 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); |
| 12954 | | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); |
| 12955 | 12951 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); |
| 12952 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); |
| 12953 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); |
| 12954 | +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); |
| 12956 | 12955 | #endif |
| 12957 | 12956 | |
| 12958 | 12957 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 12959 | 12958 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 12960 | 12959 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| | @@ -14537,11 +14536,11 @@ |
| 14537 | 14536 | int flags, |
| 14538 | 14537 | int *pOutFlags |
| 14539 | 14538 | ){ |
| 14540 | 14539 | int rc = SQLITE_NOMEM; |
| 14541 | 14540 | sqlite3_file *pFile; |
| 14542 | | - pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); |
| 14541 | + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); |
| 14543 | 14542 | if( pFile ){ |
| 14544 | 14543 | rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); |
| 14545 | 14544 | if( rc!=SQLITE_OK ){ |
| 14546 | 14545 | sqlite3_free(pFile); |
| 14547 | 14546 | }else{ |
| | @@ -22100,66 +22099,66 @@ |
| 22100 | 22099 | /* 21 */ "MustBeInt", |
| 22101 | 22100 | /* 22 */ "RealAffinity", |
| 22102 | 22101 | /* 23 */ "Permutation", |
| 22103 | 22102 | /* 24 */ "Compare", |
| 22104 | 22103 | /* 25 */ "Jump", |
| 22105 | | - /* 26 */ "If", |
| 22106 | | - /* 27 */ "IfNot", |
| 22107 | | - /* 28 */ "Column", |
| 22108 | | - /* 29 */ "Affinity", |
| 22109 | | - /* 30 */ "MakeRecord", |
| 22110 | | - /* 31 */ "Count", |
| 22111 | | - /* 32 */ "Savepoint", |
| 22112 | | - /* 33 */ "AutoCommit", |
| 22113 | | - /* 34 */ "Transaction", |
| 22114 | | - /* 35 */ "ReadCookie", |
| 22115 | | - /* 36 */ "SetCookie", |
| 22116 | | - /* 37 */ "VerifyCookie", |
| 22117 | | - /* 38 */ "OpenRead", |
| 22118 | | - /* 39 */ "OpenWrite", |
| 22119 | | - /* 40 */ "OpenSorter", |
| 22104 | + /* 26 */ "Once", |
| 22105 | + /* 27 */ "If", |
| 22106 | + /* 28 */ "IfNot", |
| 22107 | + /* 29 */ "Column", |
| 22108 | + /* 30 */ "Affinity", |
| 22109 | + /* 31 */ "MakeRecord", |
| 22110 | + /* 32 */ "Count", |
| 22111 | + /* 33 */ "Savepoint", |
| 22112 | + /* 34 */ "AutoCommit", |
| 22113 | + /* 35 */ "Transaction", |
| 22114 | + /* 36 */ "ReadCookie", |
| 22115 | + /* 37 */ "SetCookie", |
| 22116 | + /* 38 */ "VerifyCookie", |
| 22117 | + /* 39 */ "OpenRead", |
| 22118 | + /* 40 */ "OpenWrite", |
| 22120 | 22119 | /* 41 */ "OpenAutoindex", |
| 22121 | 22120 | /* 42 */ "OpenEphemeral", |
| 22122 | | - /* 43 */ "OpenPseudo", |
| 22123 | | - /* 44 */ "Close", |
| 22124 | | - /* 45 */ "SeekLt", |
| 22125 | | - /* 46 */ "SeekLe", |
| 22126 | | - /* 47 */ "SeekGe", |
| 22127 | | - /* 48 */ "SeekGt", |
| 22128 | | - /* 49 */ "Seek", |
| 22129 | | - /* 50 */ "NotFound", |
| 22130 | | - /* 51 */ "Found", |
| 22131 | | - /* 52 */ "IsUnique", |
| 22132 | | - /* 53 */ "NotExists", |
| 22133 | | - /* 54 */ "Sequence", |
| 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", |
| 22121 | + /* 43 */ "SorterOpen", |
| 22122 | + /* 44 */ "OpenPseudo", |
| 22123 | + /* 45 */ "Close", |
| 22124 | + /* 46 */ "SeekLt", |
| 22125 | + /* 47 */ "SeekLe", |
| 22126 | + /* 48 */ "SeekGe", |
| 22127 | + /* 49 */ "SeekGt", |
| 22128 | + /* 50 */ "Seek", |
| 22129 | + /* 51 */ "NotFound", |
| 22130 | + /* 52 */ "Found", |
| 22131 | + /* 53 */ "IsUnique", |
| 22132 | + /* 54 */ "NotExists", |
| 22133 | + /* 55 */ "Sequence", |
| 22134 | + /* 56 */ "NewRowid", |
| 22135 | + /* 57 */ "Insert", |
| 22136 | + /* 58 */ "InsertInt", |
| 22137 | + /* 59 */ "Delete", |
| 22138 | + /* 60 */ "ResetCount", |
| 22139 | + /* 61 */ "SorterCompare", |
| 22140 | + /* 62 */ "SorterData", |
| 22141 | + /* 63 */ "RowKey", |
| 22142 | + /* 64 */ "RowData", |
| 22143 | + /* 65 */ "Rowid", |
| 22144 | + /* 66 */ "NullRow", |
| 22145 | + /* 67 */ "Last", |
| 22147 | 22146 | /* 68 */ "Or", |
| 22148 | 22147 | /* 69 */ "And", |
| 22149 | | - /* 70 */ "Next", |
| 22150 | | - /* 71 */ "IdxInsert", |
| 22151 | | - /* 72 */ "IdxDelete", |
| 22148 | + /* 70 */ "SorterSort", |
| 22149 | + /* 71 */ "Sort", |
| 22150 | + /* 72 */ "Rewind", |
| 22152 | 22151 | /* 73 */ "IsNull", |
| 22153 | 22152 | /* 74 */ "NotNull", |
| 22154 | 22153 | /* 75 */ "Ne", |
| 22155 | 22154 | /* 76 */ "Eq", |
| 22156 | 22155 | /* 77 */ "Gt", |
| 22157 | 22156 | /* 78 */ "Le", |
| 22158 | 22157 | /* 79 */ "Lt", |
| 22159 | 22158 | /* 80 */ "Ge", |
| 22160 | | - /* 81 */ "IdxRowid", |
| 22159 | + /* 81 */ "SorterNext", |
| 22161 | 22160 | /* 82 */ "BitAnd", |
| 22162 | 22161 | /* 83 */ "BitOr", |
| 22163 | 22162 | /* 84 */ "ShiftLeft", |
| 22164 | 22163 | /* 85 */ "ShiftRight", |
| 22165 | 22164 | /* 86 */ "Add", |
| | @@ -22166,64 +22165,69 @@ |
| 22166 | 22165 | /* 87 */ "Subtract", |
| 22167 | 22166 | /* 88 */ "Multiply", |
| 22168 | 22167 | /* 89 */ "Divide", |
| 22169 | 22168 | /* 90 */ "Remainder", |
| 22170 | 22169 | /* 91 */ "Concat", |
| 22171 | | - /* 92 */ "IdxLT", |
| 22170 | + /* 92 */ "Prev", |
| 22172 | 22171 | /* 93 */ "BitNot", |
| 22173 | 22172 | /* 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", |
| 22173 | + /* 95 */ "Next", |
| 22174 | + /* 96 */ "SorterInsert", |
| 22175 | + /* 97 */ "IdxInsert", |
| 22176 | + /* 98 */ "IdxDelete", |
| 22177 | + /* 99 */ "IdxRowid", |
| 22178 | + /* 100 */ "IdxLT", |
| 22179 | + /* 101 */ "IdxGE", |
| 22180 | + /* 102 */ "Destroy", |
| 22181 | + /* 103 */ "Clear", |
| 22182 | + /* 104 */ "CreateIndex", |
| 22183 | + /* 105 */ "CreateTable", |
| 22184 | + /* 106 */ "ParseSchema", |
| 22185 | + /* 107 */ "LoadAnalysis", |
| 22186 | + /* 108 */ "DropTable", |
| 22187 | + /* 109 */ "DropIndex", |
| 22188 | + /* 110 */ "DropTrigger", |
| 22189 | + /* 111 */ "IntegrityCk", |
| 22190 | + /* 112 */ "RowSetAdd", |
| 22191 | + /* 113 */ "RowSetRead", |
| 22192 | + /* 114 */ "RowSetTest", |
| 22193 | + /* 115 */ "Program", |
| 22194 | + /* 116 */ "Param", |
| 22195 | + /* 117 */ "FkCounter", |
| 22196 | + /* 118 */ "FkIfZero", |
| 22197 | + /* 119 */ "MemMax", |
| 22198 | + /* 120 */ "IfPos", |
| 22199 | + /* 121 */ "IfNeg", |
| 22200 | + /* 122 */ "IfZero", |
| 22201 | + /* 123 */ "AggStep", |
| 22202 | + /* 124 */ "AggFinal", |
| 22203 | + /* 125 */ "Checkpoint", |
| 22204 | + /* 126 */ "JournalMode", |
| 22205 | + /* 127 */ "Vacuum", |
| 22206 | + /* 128 */ "IncrVacuum", |
| 22207 | + /* 129 */ "Expire", |
| 22209 | 22208 | /* 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", |
| 22209 | + /* 131 */ "TableLock", |
| 22210 | + /* 132 */ "VBegin", |
| 22211 | + /* 133 */ "VCreate", |
| 22212 | + /* 134 */ "VDestroy", |
| 22213 | + /* 135 */ "VOpen", |
| 22214 | + /* 136 */ "VFilter", |
| 22215 | + /* 137 */ "VColumn", |
| 22216 | + /* 138 */ "VNext", |
| 22217 | + /* 139 */ "VRename", |
| 22218 | + /* 140 */ "VUpdate", |
| 22220 | 22219 | /* 141 */ "ToText", |
| 22221 | 22220 | /* 142 */ "ToBlob", |
| 22222 | 22221 | /* 143 */ "ToNumeric", |
| 22223 | 22222 | /* 144 */ "ToInt", |
| 22224 | 22223 | /* 145 */ "ToReal", |
| 22224 | + /* 146 */ "Pagecount", |
| 22225 | + /* 147 */ "MaxPgcnt", |
| 22226 | + /* 148 */ "Trace", |
| 22227 | + /* 149 */ "Noop", |
| 22228 | + /* 150 */ "Explain", |
| 22225 | 22229 | }; |
| 22226 | 22230 | return azName[i]; |
| 22227 | 22231 | } |
| 22228 | 22232 | #endif |
| 22229 | 22233 | |
| | @@ -22314,11 +22318,11 @@ |
| 22314 | 22318 | */ |
| 22315 | 22319 | #ifdef MEMORY_DEBUG |
| 22316 | 22320 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 22317 | 22321 | #endif |
| 22318 | 22322 | |
| 22319 | | -#ifdef SQLITE_DEBUG |
| 22323 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 22320 | 22324 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 22321 | 22325 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 22322 | 22326 | # endif |
| 22323 | 22327 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 22324 | 22328 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| | @@ -24656,11 +24660,11 @@ |
| 24656 | 24660 | */ |
| 24657 | 24661 | #ifdef MEMORY_DEBUG |
| 24658 | 24662 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 24659 | 24663 | #endif |
| 24660 | 24664 | |
| 24661 | | -#ifdef SQLITE_DEBUG |
| 24665 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 24662 | 24666 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 24663 | 24667 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 24664 | 24668 | # endif |
| 24665 | 24669 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 24666 | 24670 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| | @@ -27716,15 +27720,15 @@ |
| 27716 | 27720 | SQLITE_API int sqlite3_fullsync_count = 0; |
| 27717 | 27721 | #endif |
| 27718 | 27722 | |
| 27719 | 27723 | /* |
| 27720 | 27724 | ** 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, |
| 27725 | +** Others do no. To be safe, we will stick with the (slightly slower) |
| 27726 | +** fsync(). If you know that your system does support fdatasync() correctly, |
| 27723 | 27727 | ** then simply compile with -Dfdatasync=fdatasync |
| 27724 | 27728 | */ |
| 27725 | | -#if !defined(fdatasync) && !defined(__linux__) |
| 27729 | +#if !defined(fdatasync) |
| 27726 | 27730 | # define fdatasync fsync |
| 27727 | 27731 | #endif |
| 27728 | 27732 | |
| 27729 | 27733 | /* |
| 27730 | 27734 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| | @@ -28015,11 +28019,11 @@ |
| 28015 | 28019 | ** file-control operation. Enlarge the database to nBytes in size |
| 28016 | 28020 | ** (rounded up to the next chunk-size). If the database is already |
| 28017 | 28021 | ** nBytes or larger, this routine is a no-op. |
| 28018 | 28022 | */ |
| 28019 | 28023 | static int fcntlSizeHint(unixFile *pFile, i64 nByte){ |
| 28020 | | - if( pFile->szChunk ){ |
| 28024 | + if( pFile->szChunk>0 ){ |
| 28021 | 28025 | i64 nSize; /* Required file size */ |
| 28022 | 28026 | struct stat buf; /* Used to hold return values of fstat() */ |
| 28023 | 28027 | |
| 28024 | 28028 | if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT; |
| 28025 | 28029 | |
| | @@ -28210,15 +28214,13 @@ |
| 28210 | 28214 | */ |
| 28211 | 28215 | struct unixShm { |
| 28212 | 28216 | unixShmNode *pShmNode; /* The underlying unixShmNode object */ |
| 28213 | 28217 | unixShm *pNext; /* Next unixShm with the same unixShmNode */ |
| 28214 | 28218 | u8 hasMutex; /* True if holding the unixShmNode mutex */ |
| 28219 | + u8 id; /* Id of this connection within its unixShmNode */ |
| 28215 | 28220 | u16 sharedMask; /* Mask of shared locks held */ |
| 28216 | 28221 | u16 exclMask; /* Mask of exclusive locks held */ |
| 28217 | | -#ifdef SQLITE_DEBUG |
| 28218 | | - u8 id; /* Id of this connection within its unixShmNode */ |
| 28219 | | -#endif |
| 28220 | 28222 | }; |
| 28221 | 28223 | |
| 28222 | 28224 | /* |
| 28223 | 28225 | ** Constants used for locking |
| 28224 | 28226 | */ |
| | @@ -31435,11 +31437,11 @@ |
| 31435 | 31437 | */ |
| 31436 | 31438 | #ifdef MEMORY_DEBUG |
| 31437 | 31439 | # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
| 31438 | 31440 | #endif |
| 31439 | 31441 | |
| 31440 | | -#ifdef SQLITE_DEBUG |
| 31442 | +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) |
| 31441 | 31443 | # ifndef SQLITE_DEBUG_OS_TRACE |
| 31442 | 31444 | # define SQLITE_DEBUG_OS_TRACE 0 |
| 31443 | 31445 | # endif |
| 31444 | 31446 | int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; |
| 31445 | 31447 | # define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X |
| | @@ -32768,11 +32770,11 @@ |
| 32768 | 32770 | /* If the user has configured a chunk-size for this file, truncate the |
| 32769 | 32771 | ** file so that it consists of an integer number of chunks (i.e. the |
| 32770 | 32772 | ** actual file size after the operation may be larger than the requested |
| 32771 | 32773 | ** size). |
| 32772 | 32774 | */ |
| 32773 | | - if( pFile->szChunk ){ |
| 32775 | + if( pFile->szChunk>0 ){ |
| 32774 | 32776 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 32775 | 32777 | } |
| 32776 | 32778 | |
| 32777 | 32779 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 32778 | 32780 | if( seekWinFile(pFile, nByte) ){ |
| | @@ -32797,13 +32799,23 @@ |
| 32797 | 32799 | |
| 32798 | 32800 | /* |
| 32799 | 32801 | ** Make sure all writes to a particular file are committed to disk. |
| 32800 | 32802 | */ |
| 32801 | 32803 | static int winSync(sqlite3_file *id, int flags){ |
| 32802 | | -#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG) |
| 32803 | | - winFile *pFile = (winFile*)id; |
| 32804 | +#ifndef SQLITE_NO_SYNC |
| 32805 | + /* |
| 32806 | + ** Used only when SQLITE_NO_SYNC is not defined. |
| 32807 | + */ |
| 32804 | 32808 | BOOL rc; |
| 32809 | +#endif |
| 32810 | +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ |
| 32811 | + (defined(SQLITE_TEST) && defined(SQLITE_DEBUG)) |
| 32812 | + /* |
| 32813 | + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or |
| 32814 | + ** OSTRACE() macros. |
| 32815 | + */ |
| 32816 | + winFile *pFile = (winFile*)id; |
| 32805 | 32817 | #else |
| 32806 | 32818 | UNUSED_PARAMETER(id); |
| 32807 | 32819 | #endif |
| 32808 | 32820 | |
| 32809 | 32821 | assert( pFile ); |
| | @@ -33155,22 +33167,24 @@ |
| 33155 | 33167 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33156 | 33168 | pFile->szChunk = *(int *)pArg; |
| 33157 | 33169 | return SQLITE_OK; |
| 33158 | 33170 | } |
| 33159 | 33171 | 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 | + if( pFile->szChunk>0 ){ |
| 33173 | + sqlite3_int64 oldSz; |
| 33174 | + int rc = winFileSize(id, &oldSz); |
| 33175 | + if( rc==SQLITE_OK ){ |
| 33176 | + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; |
| 33177 | + if( newSz>oldSz ){ |
| 33178 | + SimulateIOErrorBenign(1); |
| 33179 | + rc = winTruncate(id, newSz); |
| 33180 | + SimulateIOErrorBenign(0); |
| 33181 | + } |
| 33182 | + } |
| 33183 | + return rc; |
| 33184 | + } |
| 33185 | + return SQLITE_OK; |
| 33172 | 33186 | } |
| 33173 | 33187 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33174 | 33188 | int bPersist = *(int*)pArg; |
| 33175 | 33189 | if( bPersist<0 ){ |
| 33176 | 33190 | *(int*)pArg = pFile->bPersistWal; |
| | @@ -38136,12 +38150,10 @@ |
| 38136 | 38150 | u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ |
| 38137 | 38151 | u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ |
| 38138 | 38152 | u8 tempFile; /* zFilename is a temporary file */ |
| 38139 | 38153 | u8 readOnly; /* True for a read-only database */ |
| 38140 | 38154 | 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 | 38155 | |
| 38144 | 38156 | /************************************************************************** |
| 38145 | 38157 | ** The following block contains those class members that change during |
| 38146 | 38158 | ** routine opertion. Class members not in this block are either fixed |
| 38147 | 38159 | ** when the pager is first created or else only change when there is a |
| | @@ -38361,19 +38373,10 @@ |
| 38361 | 38373 | ); |
| 38362 | 38374 | assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); |
| 38363 | 38375 | assert( pagerUseWal(p)==0 ); |
| 38364 | 38376 | } |
| 38365 | 38377 | |
| 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 | 38378 | /* If changeCountDone is set, a RESERVED lock or greater must be held |
| 38376 | 38379 | ** on the file. |
| 38377 | 38380 | */ |
| 38378 | 38381 | assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); |
| 38379 | 38382 | assert( p->eLock!=PENDING_LOCK ); |
| | @@ -41701,11 +41704,10 @@ |
| 41701 | 41704 | ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1 |
| 41702 | 41705 | ** while in the error state, hence it is impossible for this routine to |
| 41703 | 41706 | ** be called in the error state. Nevertheless, we include a NEVER() |
| 41704 | 41707 | ** test for the error state as a safeguard against future changes. |
| 41705 | 41708 | */ |
| 41706 | | - pPager->hasSeenStress = 1; |
| 41707 | 41709 | if( NEVER(pPager->errCode) ) return SQLITE_OK; |
| 41708 | 41710 | if( pPager->doNotSpill ) return SQLITE_OK; |
| 41709 | 41711 | if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ |
| 41710 | 41712 | return SQLITE_OK; |
| 41711 | 41713 | } |
| | @@ -42073,16 +42075,10 @@ |
| 42073 | 42075 | } |
| 42074 | 42076 | /* pPager->xBusyHandler = 0; */ |
| 42075 | 42077 | /* pPager->pBusyHandlerArg = 0; */ |
| 42076 | 42078 | pPager->xReiniter = xReinit; |
| 42077 | 42079 | /* 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 | 42080 | |
| 42085 | 42081 | *ppPager = pPager; |
| 42086 | 42082 | return SQLITE_OK; |
| 42087 | 42083 | } |
| 42088 | 42084 | |
| | @@ -43623,21 +43619,10 @@ |
| 43623 | 43619 | */ |
| 43624 | 43620 | SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ |
| 43625 | 43621 | return MEMDB; |
| 43626 | 43622 | } |
| 43627 | 43623 | |
| 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 | 43624 | /* |
| 43640 | 43625 | ** Check that there are at least nSavepoint savepoints open. If there are |
| 43641 | 43626 | ** currently less than nSavepoints open, then open one or more savepoints |
| 43642 | 43627 | ** to make up the difference. If the number of savepoints is already |
| 43643 | 43628 | ** equal to nSavepoint, then this function is a no-op. |
| | @@ -48924,22 +48909,25 @@ |
| 48924 | 48909 | int *pRes /* Write search results here */ |
| 48925 | 48910 | ){ |
| 48926 | 48911 | int rc; /* Status code */ |
| 48927 | 48912 | UnpackedRecord *pIdxKey; /* Unpacked index key */ |
| 48928 | 48913 | char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ |
| 48914 | + char *pFree = 0; |
| 48929 | 48915 | |
| 48930 | 48916 | if( pKey ){ |
| 48931 | 48917 | assert( nKey==(i64)(int)nKey ); |
| 48932 | | - pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, |
| 48933 | | - aSpace, sizeof(aSpace)); |
| 48918 | + pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 48919 | + pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree |
| 48920 | + ); |
| 48934 | 48921 | if( pIdxKey==0 ) return SQLITE_NOMEM; |
| 48922 | + sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); |
| 48935 | 48923 | }else{ |
| 48936 | 48924 | pIdxKey = 0; |
| 48937 | 48925 | } |
| 48938 | 48926 | rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); |
| 48939 | | - if( pKey ){ |
| 48940 | | - sqlite3VdbeDeleteUnpackedRecord(pIdxKey); |
| 48927 | + if( pFree ){ |
| 48928 | + sqlite3DbFree(pCur->pKeyInfo->db, pFree); |
| 48941 | 48929 | } |
| 48942 | 48930 | return rc; |
| 48943 | 48931 | } |
| 48944 | 48932 | |
| 48945 | 48933 | /* |
| | @@ -50002,26 +49990,15 @@ |
| 50002 | 49990 | assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); |
| 50003 | 49991 | |
| 50004 | 49992 | /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ |
| 50005 | 49993 | assert( (flags & BTREE_SINGLE)==0 || isTempDb ); |
| 50006 | 49994 | |
| 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 | 49995 | if( db->flags & SQLITE_NoReadlock ){ |
| 50018 | 49996 | flags |= BTREE_NO_READLOCK; |
| 50019 | 49997 | } |
| 50020 | 49998 | if( isMemdb ){ |
| 50021 | 49999 | flags |= BTREE_MEMORY; |
| 50022 | | - flags &= ~BTREE_SORTER; |
| 50023 | 50000 | } |
| 50024 | 50001 | if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ |
| 50025 | 50002 | vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; |
| 50026 | 50003 | } |
| 50027 | 50004 | p = sqlite3MallocZero(sizeof(Btree)); |
| | @@ -51022,15 +50999,16 @@ |
| 51022 | 50999 | for(i=0; i<nCell; i++){ |
| 51023 | 51000 | u8 *pCell = findCell(pPage, i); |
| 51024 | 51001 | if( eType==PTRMAP_OVERFLOW1 ){ |
| 51025 | 51002 | CellInfo info; |
| 51026 | 51003 | btreeParseCellPtr(pPage, pCell, &info); |
| 51027 | | - if( info.iOverflow ){ |
| 51028 | | - if( iFrom==get4byte(&pCell[info.iOverflow]) ){ |
| 51029 | | - put4byte(&pCell[info.iOverflow], iTo); |
| 51030 | | - break; |
| 51031 | | - } |
| 51004 | + if( info.iOverflow |
| 51005 | + && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage |
| 51006 | + && iFrom==get4byte(&pCell[info.iOverflow]) |
| 51007 | + ){ |
| 51008 | + put4byte(&pCell[info.iOverflow], iTo); |
| 51009 | + break; |
| 51032 | 51010 | } |
| 51033 | 51011 | }else{ |
| 51034 | 51012 | if( get4byte(pCell)==iFrom ){ |
| 51035 | 51013 | put4byte(pCell, iTo); |
| 51036 | 51014 | break; |
| | @@ -53458,10 +53436,13 @@ |
| 53458 | 53436 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 53459 | 53437 | btreeParseCellPtr(pPage, pCell, &info); |
| 53460 | 53438 | if( info.iOverflow==0 ){ |
| 53461 | 53439 | return SQLITE_OK; /* No overflow pages. Return without doing anything */ |
| 53462 | 53440 | } |
| 53441 | + if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){ |
| 53442 | + return SQLITE_CORRUPT; /* Cell extends past end of page */ |
| 53443 | + } |
| 53463 | 53444 | ovflPgno = get4byte(&pCell[info.iOverflow]); |
| 53464 | 53445 | assert( pBt->usableSize > 4 ); |
| 53465 | 53446 | ovflPageSize = pBt->usableSize - 4; |
| 53466 | 53447 | nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; |
| 53467 | 53448 | assert( ovflPgno==0 || nOvfl>0 ); |
| | @@ -55560,20 +55541,13 @@ |
| 55560 | 55541 | releasePage(pPage); |
| 55561 | 55542 | } |
| 55562 | 55543 | return rc; |
| 55563 | 55544 | } |
| 55564 | 55545 | SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ |
| 55565 | | - BtShared *pBt = p->pBt; |
| 55566 | 55546 | int rc; |
| 55567 | 55547 | 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 | | - } |
| 55548 | + rc = btreeDropTable(p, iTable, piMoved); |
| 55575 | 55549 | sqlite3BtreeLeave(p); |
| 55576 | 55550 | return rc; |
| 55577 | 55551 | } |
| 55578 | 55552 | |
| 55579 | 55553 | |
| | @@ -58758,11 +58732,11 @@ |
| 58758 | 58732 | assert( p->nOp - i >= 3 ); |
| 58759 | 58733 | assert( pOp[-1].opcode==OP_Integer ); |
| 58760 | 58734 | n = pOp[-1].p1; |
| 58761 | 58735 | if( n>nMaxArgs ) nMaxArgs = n; |
| 58762 | 58736 | #endif |
| 58763 | | - }else if( opcode==OP_Next ){ |
| 58737 | + }else if( opcode==OP_Next || opcode==OP_SorterNext ){ |
| 58764 | 58738 | pOp->p4.xAdvance = sqlite3BtreeNext; |
| 58765 | 58739 | pOp->p4type = P4_ADVANCE; |
| 58766 | 58740 | }else if( opcode==OP_Prev ){ |
| 58767 | 58741 | pOp->p4.xAdvance = sqlite3BtreePrevious; |
| 58768 | 58742 | pOp->p4type = P4_ADVANCE; |
| | @@ -58995,22 +58969,19 @@ |
| 58995 | 58969 | p->pNext = pVdbe->pProgram; |
| 58996 | 58970 | pVdbe->pProgram = p; |
| 58997 | 58971 | } |
| 58998 | 58972 | |
| 58999 | 58973 | /* |
| 59000 | | -** Change N opcodes starting at addr to No-ops. |
| 58974 | +** Change the opcode at addr into OP_Noop |
| 59001 | 58975 | */ |
| 59002 | | -SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ |
| 58976 | +SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ |
| 59003 | 58977 | if( p->aOp ){ |
| 59004 | 58978 | VdbeOp *pOp = &p->aOp[addr]; |
| 59005 | 58979 | sqlite3 *db = p->db; |
| 59006 | | - while( N-- ){ |
| 59007 | | - freeP4(db, pOp->p4type, pOp->p4.p); |
| 59008 | | - memset(pOp, 0, sizeof(pOp[0])); |
| 59009 | | - pOp->opcode = OP_Noop; |
| 59010 | | - pOp++; |
| 59011 | | - } |
| 58980 | + freeP4(db, pOp->p4type, pOp->p4.p); |
| 58981 | + memset(pOp, 0, sizeof(pOp[0])); |
| 58982 | + pOp->opcode = OP_Noop; |
| 59012 | 58983 | } |
| 59013 | 58984 | } |
| 59014 | 58985 | |
| 59015 | 58986 | /* |
| 59016 | 58987 | ** Change the value of the P4 operand for a specific instruction. |
| | @@ -59162,11 +59133,11 @@ |
| 59162 | 59133 | ** check the value of p->nOp-1 before continuing. |
| 59163 | 59134 | */ |
| 59164 | 59135 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ |
| 59165 | 59136 | /* C89 specifies that the constant "dummy" will be initialized to all |
| 59166 | 59137 | ** zeros, which is correct. MSVC generates a warning, nevertheless. */ |
| 59167 | | - static const VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ |
| 59138 | + static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ |
| 59168 | 59139 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 59169 | 59140 | if( addr<0 ){ |
| 59170 | 59141 | #ifdef SQLITE_OMIT_TRACE |
| 59171 | 59142 | if( p->nOp==0 ) return (VdbeOp*)&dummy; |
| 59172 | 59143 | #endif |
| | @@ -61155,61 +61126,74 @@ |
| 61155 | 61126 | } |
| 61156 | 61127 | } |
| 61157 | 61128 | return 0; |
| 61158 | 61129 | } |
| 61159 | 61130 | |
| 61160 | | - |
| 61161 | | -/* |
| 61162 | | -** Given the nKey-byte encoding of a record in pKey[], parse the |
| 61163 | | -** record into a UnpackedRecord structure. Return a pointer to |
| 61164 | | -** that structure. |
| 61165 | | -** |
| 61166 | | -** The calling function might provide szSpace bytes of memory |
| 61167 | | -** space at pSpace. This space can be used to hold the returned |
| 61168 | | -** VDbeParsedRecord structure if it is large enough. If it is |
| 61169 | | -** not big enough, space is obtained from sqlite3_malloc(). |
| 61170 | | -** |
| 61171 | | -** The returned structure should be closed by a call to |
| 61172 | | -** sqlite3VdbeDeleteUnpackedRecord(). |
| 61173 | | -*/ |
| 61174 | | -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( |
| 61175 | | - KeyInfo *pKeyInfo, /* Information about the record format */ |
| 61176 | | - int nKey, /* Size of the binary record */ |
| 61177 | | - const void *pKey, /* The binary record */ |
| 61178 | | - char *pSpace, /* Unaligned space available to hold the object */ |
| 61179 | | - int szSpace /* Size of pSpace[] in bytes */ |
| 61180 | | -){ |
| 61181 | | - const unsigned char *aKey = (const unsigned char *)pKey; |
| 61182 | | - UnpackedRecord *p; /* The unpacked record that we will return */ |
| 61183 | | - int nByte; /* Memory space needed to hold p, in bytes */ |
| 61184 | | - int d; |
| 61185 | | - u32 idx; |
| 61186 | | - u16 u; /* Unsigned loop counter */ |
| 61187 | | - u32 szHdr; |
| 61188 | | - Mem *pMem; |
| 61189 | | - int nOff; /* Increase pSpace by this much to 8-byte align it */ |
| 61190 | | - |
| 61191 | | - /* |
| 61192 | | - ** We want to shift the pointer pSpace up such that it is 8-byte aligned. |
| 61131 | +/* |
| 61132 | +** This routine is used to allocate sufficient space for an UnpackedRecord |
| 61133 | +** structure large enough to be used with sqlite3VdbeRecordUnpack() if |
| 61134 | +** the first argument is a pointer to KeyInfo structure pKeyInfo. |
| 61135 | +** |
| 61136 | +** The space is either allocated using sqlite3DbMallocRaw() or from within |
| 61137 | +** the unaligned buffer passed via the second and third arguments (presumably |
| 61138 | +** stack space). If the former, then *ppFree is set to a pointer that should |
| 61139 | +** be eventually freed by the caller using sqlite3DbFree(). Or, if the |
| 61140 | +** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL |
| 61141 | +** before returning. |
| 61142 | +** |
| 61143 | +** If an OOM error occurs, NULL is returned. |
| 61144 | +*/ |
| 61145 | +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( |
| 61146 | + KeyInfo *pKeyInfo, /* Description of the record */ |
| 61147 | + char *pSpace, /* Unaligned space available */ |
| 61148 | + int szSpace, /* Size of pSpace[] in bytes */ |
| 61149 | + char **ppFree /* OUT: Caller should free this pointer */ |
| 61150 | +){ |
| 61151 | + UnpackedRecord *p; /* Unpacked record to return */ |
| 61152 | + int nOff; /* Increment pSpace by nOff to align it */ |
| 61153 | + int nByte; /* Number of bytes required for *p */ |
| 61154 | + |
| 61155 | + /* We want to shift the pointer pSpace up such that it is 8-byte aligned. |
| 61193 | 61156 | ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift |
| 61194 | 61157 | ** it by. If pSpace is already 8-byte aligned, nOff should be zero. |
| 61195 | 61158 | */ |
| 61196 | 61159 | nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; |
| 61197 | | - pSpace += nOff; |
| 61198 | | - szSpace -= nOff; |
| 61199 | 61160 | nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); |
| 61200 | | - if( nByte>szSpace ){ |
| 61201 | | - p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 61202 | | - if( p==0 ) return 0; |
| 61203 | | - p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY; |
| 61161 | + if( nByte>szSpace+nOff ){ |
| 61162 | + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); |
| 61163 | + *ppFree = (char *)p; |
| 61164 | + if( !p ) return 0; |
| 61204 | 61165 | }else{ |
| 61205 | | - p = (UnpackedRecord*)pSpace; |
| 61206 | | - p->flags = UNPACKED_NEED_DESTROY; |
| 61166 | + p = (UnpackedRecord*)&pSpace[nOff]; |
| 61167 | + *ppFree = 0; |
| 61207 | 61168 | } |
| 61169 | + |
| 61170 | + p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; |
| 61208 | 61171 | p->pKeyInfo = pKeyInfo; |
| 61209 | 61172 | p->nField = pKeyInfo->nField + 1; |
| 61210 | | - p->aMem = pMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; |
| 61173 | + return p; |
| 61174 | +} |
| 61175 | + |
| 61176 | +/* |
| 61177 | +** Given the nKey-byte encoding of a record in pKey[], populate the |
| 61178 | +** UnpackedRecord structure indicated by the fourth argument with the |
| 61179 | +** contents of the decoded record. |
| 61180 | +*/ |
| 61181 | +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( |
| 61182 | + KeyInfo *pKeyInfo, /* Information about the record format */ |
| 61183 | + int nKey, /* Size of the binary record */ |
| 61184 | + const void *pKey, /* The binary record */ |
| 61185 | + UnpackedRecord *p /* Populate this structure before returning. */ |
| 61186 | +){ |
| 61187 | + const unsigned char *aKey = (const unsigned char *)pKey; |
| 61188 | + int d; |
| 61189 | + u32 idx; /* Offset in aKey[] to read from */ |
| 61190 | + u16 u; /* Unsigned loop counter */ |
| 61191 | + u32 szHdr; |
| 61192 | + Mem *pMem = p->aMem; |
| 61193 | + |
| 61194 | + p->flags = 0; |
| 61211 | 61195 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 61212 | 61196 | idx = getVarint32(aKey, szHdr); |
| 61213 | 61197 | d = szHdr; |
| 61214 | 61198 | u = 0; |
| 61215 | 61199 | while( idx<szHdr && u<p->nField && d<=nKey ){ |
| | @@ -61224,35 +61208,10 @@ |
| 61224 | 61208 | pMem++; |
| 61225 | 61209 | u++; |
| 61226 | 61210 | } |
| 61227 | 61211 | assert( u<=pKeyInfo->nField + 1 ); |
| 61228 | 61212 | p->nField = u; |
| 61229 | | - return (void*)p; |
| 61230 | | -} |
| 61231 | | - |
| 61232 | | -/* |
| 61233 | | -** This routine destroys a UnpackedRecord object. |
| 61234 | | -*/ |
| 61235 | | -SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ |
| 61236 | | -#ifdef SQLITE_DEBUG |
| 61237 | | - int i; |
| 61238 | | - Mem *pMem; |
| 61239 | | - |
| 61240 | | - assert( p!=0 ); |
| 61241 | | - assert( p->flags & UNPACKED_NEED_DESTROY ); |
| 61242 | | - for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){ |
| 61243 | | - /* The unpacked record is always constructed by the |
| 61244 | | - ** sqlite3VdbeUnpackRecord() function above, which makes all |
| 61245 | | - ** strings and blobs static. And none of the elements are |
| 61246 | | - ** ever transformed, so there is never anything to delete. |
| 61247 | | - */ |
| 61248 | | - if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); |
| 61249 | | - } |
| 61250 | | -#endif |
| 61251 | | - if( p->flags & UNPACKED_NEED_FREE ){ |
| 61252 | | - sqlite3DbFree(p->pKeyInfo->db, p); |
| 61253 | | - } |
| 61254 | 61213 | } |
| 61255 | 61214 | |
| 61256 | 61215 | /* |
| 61257 | 61216 | ** This function compares the two table rows or index records |
| 61258 | 61217 | ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero |
| | @@ -63871,55 +63830,59 @@ |
| 63871 | 63830 | Db *pDb; |
| 63872 | 63831 | } aw; |
| 63873 | 63832 | struct OP_OpenEphemeral_stack_vars { |
| 63874 | 63833 | VdbeCursor *pCx; |
| 63875 | 63834 | } ax; |
| 63876 | | - struct OP_OpenPseudo_stack_vars { |
| 63835 | + struct OP_SorterOpen_stack_vars { |
| 63877 | 63836 | VdbeCursor *pCx; |
| 63878 | 63837 | } ay; |
| 63838 | + struct OP_OpenPseudo_stack_vars { |
| 63839 | + VdbeCursor *pCx; |
| 63840 | + } az; |
| 63879 | 63841 | struct OP_SeekGt_stack_vars { |
| 63880 | 63842 | int res; |
| 63881 | 63843 | int oc; |
| 63882 | 63844 | VdbeCursor *pC; |
| 63883 | 63845 | UnpackedRecord r; |
| 63884 | 63846 | int nField; |
| 63885 | 63847 | i64 iKey; /* The rowid we are to seek to */ |
| 63886 | | - } az; |
| 63848 | + } ba; |
| 63887 | 63849 | struct OP_Seek_stack_vars { |
| 63888 | 63850 | VdbeCursor *pC; |
| 63889 | | - } ba; |
| 63851 | + } bb; |
| 63890 | 63852 | struct OP_Found_stack_vars { |
| 63891 | 63853 | int alreadyExists; |
| 63892 | 63854 | VdbeCursor *pC; |
| 63893 | 63855 | int res; |
| 63856 | + char *pFree; |
| 63894 | 63857 | UnpackedRecord *pIdxKey; |
| 63895 | 63858 | UnpackedRecord r; |
| 63896 | 63859 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 63897 | | - } bb; |
| 63860 | + } bc; |
| 63898 | 63861 | struct OP_IsUnique_stack_vars { |
| 63899 | 63862 | u16 ii; |
| 63900 | 63863 | VdbeCursor *pCx; |
| 63901 | 63864 | BtCursor *pCrsr; |
| 63902 | 63865 | u16 nField; |
| 63903 | 63866 | Mem *aMx; |
| 63904 | 63867 | UnpackedRecord r; /* B-Tree index search key */ |
| 63905 | 63868 | i64 R; /* Rowid stored in register P3 */ |
| 63906 | | - } bc; |
| 63869 | + } bd; |
| 63907 | 63870 | struct OP_NotExists_stack_vars { |
| 63908 | 63871 | VdbeCursor *pC; |
| 63909 | 63872 | BtCursor *pCrsr; |
| 63910 | 63873 | int res; |
| 63911 | 63874 | u64 iKey; |
| 63912 | | - } bd; |
| 63875 | + } be; |
| 63913 | 63876 | struct OP_NewRowid_stack_vars { |
| 63914 | 63877 | i64 v; /* The new rowid */ |
| 63915 | 63878 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 63916 | 63879 | int res; /* Result of an sqlite3BtreeLast() */ |
| 63917 | 63880 | int cnt; /* Counter to limit the number of searches */ |
| 63918 | 63881 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 63919 | 63882 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 63920 | | - } be; |
| 63883 | + } bf; |
| 63921 | 63884 | struct OP_InsertInt_stack_vars { |
| 63922 | 63885 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 63923 | 63886 | Mem *pKey; /* MEM cell holding key for the record */ |
| 63924 | 63887 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 63925 | 63888 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| | @@ -63926,154 +63889,161 @@ |
| 63926 | 63889 | int nZero; /* Number of zero-bytes to append */ |
| 63927 | 63890 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 63928 | 63891 | const char *zDb; /* database name - used by the update hook */ |
| 63929 | 63892 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 63930 | 63893 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 63931 | | - } bf; |
| 63894 | + } bg; |
| 63932 | 63895 | struct OP_Delete_stack_vars { |
| 63933 | 63896 | i64 iKey; |
| 63934 | 63897 | VdbeCursor *pC; |
| 63935 | | - } bg; |
| 63898 | + } bh; |
| 63899 | + struct OP_SorterCompare_stack_vars { |
| 63900 | + VdbeCursor *pC; |
| 63901 | + int res; |
| 63902 | + } bi; |
| 63903 | + struct OP_SorterData_stack_vars { |
| 63904 | + VdbeCursor *pC; |
| 63905 | + } bj; |
| 63936 | 63906 | struct OP_RowData_stack_vars { |
| 63937 | 63907 | VdbeCursor *pC; |
| 63938 | 63908 | BtCursor *pCrsr; |
| 63939 | 63909 | u32 n; |
| 63940 | 63910 | i64 n64; |
| 63941 | | - } bh; |
| 63911 | + } bk; |
| 63942 | 63912 | struct OP_Rowid_stack_vars { |
| 63943 | 63913 | VdbeCursor *pC; |
| 63944 | 63914 | i64 v; |
| 63945 | 63915 | sqlite3_vtab *pVtab; |
| 63946 | 63916 | const sqlite3_module *pModule; |
| 63947 | | - } bi; |
| 63917 | + } bl; |
| 63948 | 63918 | struct OP_NullRow_stack_vars { |
| 63949 | 63919 | VdbeCursor *pC; |
| 63950 | | - } bj; |
| 63920 | + } bm; |
| 63951 | 63921 | struct OP_Last_stack_vars { |
| 63952 | 63922 | VdbeCursor *pC; |
| 63953 | 63923 | BtCursor *pCrsr; |
| 63954 | 63924 | int res; |
| 63955 | | - } bk; |
| 63925 | + } bn; |
| 63956 | 63926 | struct OP_Rewind_stack_vars { |
| 63957 | 63927 | VdbeCursor *pC; |
| 63958 | 63928 | BtCursor *pCrsr; |
| 63959 | 63929 | int res; |
| 63960 | | - } bl; |
| 63930 | + } bo; |
| 63961 | 63931 | struct OP_Next_stack_vars { |
| 63962 | 63932 | VdbeCursor *pC; |
| 63963 | 63933 | int res; |
| 63964 | | - } bm; |
| 63934 | + } bp; |
| 63965 | 63935 | struct OP_IdxInsert_stack_vars { |
| 63966 | 63936 | VdbeCursor *pC; |
| 63967 | 63937 | BtCursor *pCrsr; |
| 63968 | 63938 | int nKey; |
| 63969 | 63939 | const char *zKey; |
| 63970 | | - } bn; |
| 63940 | + } bq; |
| 63971 | 63941 | struct OP_IdxDelete_stack_vars { |
| 63972 | 63942 | VdbeCursor *pC; |
| 63973 | 63943 | BtCursor *pCrsr; |
| 63974 | 63944 | int res; |
| 63975 | 63945 | UnpackedRecord r; |
| 63976 | | - } bo; |
| 63946 | + } br; |
| 63977 | 63947 | struct OP_IdxRowid_stack_vars { |
| 63978 | 63948 | BtCursor *pCrsr; |
| 63979 | 63949 | VdbeCursor *pC; |
| 63980 | 63950 | i64 rowid; |
| 63981 | | - } bp; |
| 63951 | + } bs; |
| 63982 | 63952 | struct OP_IdxGE_stack_vars { |
| 63983 | 63953 | VdbeCursor *pC; |
| 63984 | 63954 | int res; |
| 63985 | 63955 | UnpackedRecord r; |
| 63986 | | - } bq; |
| 63956 | + } bt; |
| 63987 | 63957 | struct OP_Destroy_stack_vars { |
| 63988 | 63958 | int iMoved; |
| 63989 | 63959 | int iCnt; |
| 63990 | 63960 | Vdbe *pVdbe; |
| 63991 | 63961 | int iDb; |
| 63992 | | - } br; |
| 63962 | + } bu; |
| 63993 | 63963 | struct OP_Clear_stack_vars { |
| 63994 | 63964 | int nChange; |
| 63995 | | - } bs; |
| 63965 | + } bv; |
| 63996 | 63966 | struct OP_CreateTable_stack_vars { |
| 63997 | 63967 | int pgno; |
| 63998 | 63968 | int flags; |
| 63999 | 63969 | Db *pDb; |
| 64000 | | - } bt; |
| 63970 | + } bw; |
| 64001 | 63971 | struct OP_ParseSchema_stack_vars { |
| 64002 | 63972 | int iDb; |
| 64003 | 63973 | const char *zMaster; |
| 64004 | 63974 | char *zSql; |
| 64005 | 63975 | InitData initData; |
| 64006 | | - } bu; |
| 63976 | + } bx; |
| 64007 | 63977 | struct OP_IntegrityCk_stack_vars { |
| 64008 | 63978 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 64009 | 63979 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 64010 | 63980 | int j; /* Loop counter */ |
| 64011 | 63981 | int nErr; /* Number of errors reported */ |
| 64012 | 63982 | char *z; /* Text of the error report */ |
| 64013 | 63983 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 64014 | | - } bv; |
| 63984 | + } by; |
| 64015 | 63985 | struct OP_RowSetRead_stack_vars { |
| 64016 | 63986 | i64 val; |
| 64017 | | - } bw; |
| 63987 | + } bz; |
| 64018 | 63988 | struct OP_RowSetTest_stack_vars { |
| 64019 | 63989 | int iSet; |
| 64020 | 63990 | int exists; |
| 64021 | | - } bx; |
| 63991 | + } ca; |
| 64022 | 63992 | struct OP_Program_stack_vars { |
| 64023 | 63993 | int nMem; /* Number of memory registers for sub-program */ |
| 64024 | 63994 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 64025 | 63995 | Mem *pRt; /* Register to allocate runtime space */ |
| 64026 | 63996 | Mem *pMem; /* Used to iterate through memory cells */ |
| 64027 | 63997 | Mem *pEnd; /* Last memory cell in new array */ |
| 64028 | 63998 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 64029 | 63999 | SubProgram *pProgram; /* Sub-program to execute */ |
| 64030 | 64000 | void *t; /* Token identifying trigger */ |
| 64031 | | - } by; |
| 64001 | + } cb; |
| 64032 | 64002 | struct OP_Param_stack_vars { |
| 64033 | 64003 | VdbeFrame *pFrame; |
| 64034 | 64004 | Mem *pIn; |
| 64035 | | - } bz; |
| 64005 | + } cc; |
| 64036 | 64006 | struct OP_MemMax_stack_vars { |
| 64037 | 64007 | Mem *pIn1; |
| 64038 | 64008 | VdbeFrame *pFrame; |
| 64039 | | - } ca; |
| 64009 | + } cd; |
| 64040 | 64010 | struct OP_AggStep_stack_vars { |
| 64041 | 64011 | int n; |
| 64042 | 64012 | int i; |
| 64043 | 64013 | Mem *pMem; |
| 64044 | 64014 | Mem *pRec; |
| 64045 | 64015 | sqlite3_context ctx; |
| 64046 | 64016 | sqlite3_value **apVal; |
| 64047 | | - } cb; |
| 64017 | + } ce; |
| 64048 | 64018 | struct OP_AggFinal_stack_vars { |
| 64049 | 64019 | Mem *pMem; |
| 64050 | | - } cc; |
| 64020 | + } cf; |
| 64051 | 64021 | struct OP_Checkpoint_stack_vars { |
| 64052 | 64022 | int i; /* Loop counter */ |
| 64053 | 64023 | int aRes[3]; /* Results */ |
| 64054 | 64024 | Mem *pMem; /* Write results here */ |
| 64055 | | - } cd; |
| 64025 | + } cg; |
| 64056 | 64026 | struct OP_JournalMode_stack_vars { |
| 64057 | 64027 | Btree *pBt; /* Btree to change journal mode of */ |
| 64058 | 64028 | Pager *pPager; /* Pager associated with pBt */ |
| 64059 | 64029 | int eNew; /* New journal mode */ |
| 64060 | 64030 | int eOld; /* The old journal mode */ |
| 64061 | 64031 | const char *zFilename; /* Name of database file for pPager */ |
| 64062 | | - } ce; |
| 64032 | + } ch; |
| 64063 | 64033 | struct OP_IncrVacuum_stack_vars { |
| 64064 | 64034 | Btree *pBt; |
| 64065 | | - } cf; |
| 64035 | + } ci; |
| 64066 | 64036 | struct OP_VBegin_stack_vars { |
| 64067 | 64037 | VTable *pVTab; |
| 64068 | | - } cg; |
| 64038 | + } cj; |
| 64069 | 64039 | struct OP_VOpen_stack_vars { |
| 64070 | 64040 | VdbeCursor *pCur; |
| 64071 | 64041 | sqlite3_vtab_cursor *pVtabCursor; |
| 64072 | 64042 | sqlite3_vtab *pVtab; |
| 64073 | 64043 | sqlite3_module *pModule; |
| 64074 | | - } ch; |
| 64044 | + } ck; |
| 64075 | 64045 | struct OP_VFilter_stack_vars { |
| 64076 | 64046 | int nArg; |
| 64077 | 64047 | int iQuery; |
| 64078 | 64048 | const sqlite3_module *pModule; |
| 64079 | 64049 | Mem *pQuery; |
| | @@ -64082,40 +64052,40 @@ |
| 64082 | 64052 | sqlite3_vtab *pVtab; |
| 64083 | 64053 | VdbeCursor *pCur; |
| 64084 | 64054 | int res; |
| 64085 | 64055 | int i; |
| 64086 | 64056 | Mem **apArg; |
| 64087 | | - } ci; |
| 64057 | + } cl; |
| 64088 | 64058 | struct OP_VColumn_stack_vars { |
| 64089 | 64059 | sqlite3_vtab *pVtab; |
| 64090 | 64060 | const sqlite3_module *pModule; |
| 64091 | 64061 | Mem *pDest; |
| 64092 | 64062 | sqlite3_context sContext; |
| 64093 | | - } cj; |
| 64063 | + } cm; |
| 64094 | 64064 | struct OP_VNext_stack_vars { |
| 64095 | 64065 | sqlite3_vtab *pVtab; |
| 64096 | 64066 | const sqlite3_module *pModule; |
| 64097 | 64067 | int res; |
| 64098 | 64068 | VdbeCursor *pCur; |
| 64099 | | - } ck; |
| 64069 | + } cn; |
| 64100 | 64070 | struct OP_VRename_stack_vars { |
| 64101 | 64071 | sqlite3_vtab *pVtab; |
| 64102 | 64072 | Mem *pName; |
| 64103 | | - } cl; |
| 64073 | + } co; |
| 64104 | 64074 | struct OP_VUpdate_stack_vars { |
| 64105 | 64075 | sqlite3_vtab *pVtab; |
| 64106 | 64076 | sqlite3_module *pModule; |
| 64107 | 64077 | int nArg; |
| 64108 | 64078 | int i; |
| 64109 | 64079 | sqlite_int64 rowid; |
| 64110 | 64080 | Mem **apArg; |
| 64111 | 64081 | Mem *pX; |
| 64112 | | - } cm; |
| 64082 | + } cp; |
| 64113 | 64083 | struct OP_Trace_stack_vars { |
| 64114 | 64084 | char *zTrace; |
| 64115 | 64085 | char *z; |
| 64116 | | - } cn; |
| 64086 | + } cq; |
| 64117 | 64087 | } u; |
| 64118 | 64088 | /* End automatically generated code |
| 64119 | 64089 | ********************************************************************/ |
| 64120 | 64090 | |
| 64121 | 64091 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| | @@ -65581,10 +65551,20 @@ |
| 65581 | 65551 | sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); |
| 65582 | 65552 | } |
| 65583 | 65553 | break; |
| 65584 | 65554 | } |
| 65585 | 65555 | |
| 65556 | +/* Opcode: Once P1 P2 * * * |
| 65557 | +** |
| 65558 | +** Jump to P2 if the value in register P1 is a not null or zero. If |
| 65559 | +** the value is NULL or zero, fall through and change the P1 register |
| 65560 | +** to an integer 1. |
| 65561 | +** |
| 65562 | +** When P1 is not used otherwise in a program, this opcode falls through |
| 65563 | +** once and jumps on all subsequent invocations. It is the equivalent |
| 65564 | +** of "OP_If P1 P2", followed by "OP_Integer 1 P1". |
| 65565 | +*/ |
| 65586 | 65566 | /* Opcode: If P1 P2 P3 * * |
| 65587 | 65567 | ** |
| 65588 | 65568 | ** Jump to P2 if the value in register P1 is true. The value |
| 65589 | 65569 | ** is considered true if it is numeric and non-zero. If the value |
| 65590 | 65570 | ** in P1 is NULL then take the jump if P3 is true. |
| | @@ -65593,10 +65573,11 @@ |
| 65593 | 65573 | ** |
| 65594 | 65574 | ** Jump to P2 if the value in register P1 is False. The value |
| 65595 | 65575 | ** is considered true if it has a numeric value of zero. If the value |
| 65596 | 65576 | ** in P1 is NULL then take the jump if P3 is true. |
| 65597 | 65577 | */ |
| 65578 | +case OP_Once: /* jump, in1 */ |
| 65598 | 65579 | case OP_If: /* jump, in1 */ |
| 65599 | 65580 | case OP_IfNot: { /* jump, in1 */ |
| 65600 | 65581 | #if 0 /* local variables moved into u.al */ |
| 65601 | 65582 | int c; |
| 65602 | 65583 | #endif /* local variables moved into u.al */ |
| | @@ -65611,10 +65592,16 @@ |
| 65611 | 65592 | #endif |
| 65612 | 65593 | if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c; |
| 65613 | 65594 | } |
| 65614 | 65595 | if( u.al.c ){ |
| 65615 | 65596 | pc = pOp->p2-1; |
| 65597 | + }else if( pOp->opcode==OP_Once ){ |
| 65598 | + assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); |
| 65599 | + memAboutToChange(p, pIn1); |
| 65600 | + pIn1->flags = MEM_Int; |
| 65601 | + pIn1->u.i = 1; |
| 65602 | + REGISTER_TRACE(pOp->p1, pIn1); |
| 65616 | 65603 | } |
| 65617 | 65604 | break; |
| 65618 | 65605 | } |
| 65619 | 65606 | |
| 65620 | 65607 | /* Opcode: IsNull P1 P2 * * * |
| | @@ -66746,17 +66733,10 @@ |
| 66746 | 66733 | ** This opcode works the same as OP_OpenEphemeral. It has a |
| 66747 | 66734 | ** different name to distinguish its use. Tables created using |
| 66748 | 66735 | ** by this opcode will be used for automatically created transient |
| 66749 | 66736 | ** indices in joins. |
| 66750 | 66737 | */ |
| 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 | 66738 | case OP_OpenAutoindex: |
| 66759 | 66739 | case OP_OpenEphemeral: { |
| 66760 | 66740 | #if 0 /* local variables moved into u.ax */ |
| 66761 | 66741 | VdbeCursor *pCx; |
| 66762 | 66742 | #endif /* local variables moved into u.ax */ |
| | @@ -66766,11 +66746,10 @@ |
| 66766 | 66746 | SQLITE_OPEN_EXCLUSIVE | |
| 66767 | 66747 | SQLITE_OPEN_DELETEONCLOSE | |
| 66768 | 66748 | SQLITE_OPEN_TRANSIENT_DB; |
| 66769 | 66749 | |
| 66770 | 66750 | assert( pOp->p1>=0 ); |
| 66771 | | - assert( (pOp->opcode==OP_OpenSorter)==((pOp->p5 & BTREE_SORTER)!=0) ); |
| 66772 | 66751 | u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66773 | 66752 | if( u.ax.pCx==0 ) goto no_mem; |
| 66774 | 66753 | u.ax.pCx->nullRow = 1; |
| 66775 | 66754 | rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, |
| 66776 | 66755 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| | @@ -66800,14 +66779,33 @@ |
| 66800 | 66779 | u.ax.pCx->isTable = 1; |
| 66801 | 66780 | } |
| 66802 | 66781 | } |
| 66803 | 66782 | u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 66804 | 66783 | u.ax.pCx->isIndex = !u.ax.pCx->isTable; |
| 66784 | + break; |
| 66785 | +} |
| 66786 | + |
| 66787 | +/* Opcode: OpenSorter P1 P2 * P4 * |
| 66788 | +** |
| 66789 | +** This opcode works like OP_OpenEphemeral except that it opens |
| 66790 | +** a transient index that is specifically designed to sort large |
| 66791 | +** tables using an external merge-sort algorithm. |
| 66792 | +*/ |
| 66793 | +case OP_SorterOpen: { |
| 66794 | +#if 0 /* local variables moved into u.ay */ |
| 66795 | + VdbeCursor *pCx; |
| 66796 | +#endif /* local variables moved into u.ay */ |
| 66805 | 66797 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 66806 | | - if( rc==SQLITE_OK && pOp->opcode==OP_OpenSorter ){ |
| 66807 | | - rc = sqlite3VdbeSorterInit(db, u.ax.pCx); |
| 66808 | | - } |
| 66798 | + u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 66799 | + if( u.ay.pCx==0 ) goto no_mem; |
| 66800 | + u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 66801 | + u.ay.pCx->pKeyInfo->enc = ENC(p->db); |
| 66802 | + u.ay.pCx->isSorter = 1; |
| 66803 | + rc = sqlite3VdbeSorterInit(db, u.ay.pCx); |
| 66804 | +#else |
| 66805 | + pOp->opcode = OP_OpenEphemeral; |
| 66806 | + pc--; |
| 66809 | 66807 | #endif |
| 66810 | 66808 | break; |
| 66811 | 66809 | } |
| 66812 | 66810 | |
| 66813 | 66811 | /* Opcode: OpenPseudo P1 P2 P3 * * |
| | @@ -66824,21 +66822,21 @@ |
| 66824 | 66822 | ** |
| 66825 | 66823 | ** P3 is the number of fields in the records that will be stored by |
| 66826 | 66824 | ** the pseudo-table. |
| 66827 | 66825 | */ |
| 66828 | 66826 | case OP_OpenPseudo: { |
| 66829 | | -#if 0 /* local variables moved into u.ay */ |
| 66827 | +#if 0 /* local variables moved into u.az */ |
| 66830 | 66828 | VdbeCursor *pCx; |
| 66831 | | -#endif /* local variables moved into u.ay */ |
| 66829 | +#endif /* local variables moved into u.az */ |
| 66832 | 66830 | |
| 66833 | 66831 | 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; |
| 66832 | + u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 66833 | + if( u.az.pCx==0 ) goto no_mem; |
| 66834 | + u.az.pCx->nullRow = 1; |
| 66835 | + u.az.pCx->pseudoTableReg = pOp->p2; |
| 66836 | + u.az.pCx->isTable = 1; |
| 66837 | + u.az.pCx->isIndex = 0; |
| 66840 | 66838 | break; |
| 66841 | 66839 | } |
| 66842 | 66840 | |
| 66843 | 66841 | /* Opcode: Close P1 * * * * |
| 66844 | 66842 | ** |
| | @@ -66906,39 +66904,39 @@ |
| 66906 | 66904 | */ |
| 66907 | 66905 | case OP_SeekLt: /* jump, in3 */ |
| 66908 | 66906 | case OP_SeekLe: /* jump, in3 */ |
| 66909 | 66907 | case OP_SeekGe: /* jump, in3 */ |
| 66910 | 66908 | case OP_SeekGt: { /* jump, in3 */ |
| 66911 | | -#if 0 /* local variables moved into u.az */ |
| 66909 | +#if 0 /* local variables moved into u.ba */ |
| 66912 | 66910 | int res; |
| 66913 | 66911 | int oc; |
| 66914 | 66912 | VdbeCursor *pC; |
| 66915 | 66913 | UnpackedRecord r; |
| 66916 | 66914 | int nField; |
| 66917 | 66915 | i64 iKey; /* The rowid we are to seek to */ |
| 66918 | | -#endif /* local variables moved into u.az */ |
| 66916 | +#endif /* local variables moved into u.ba */ |
| 66919 | 66917 | |
| 66920 | 66918 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 66921 | 66919 | 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 ); |
| 66920 | + u.ba.pC = p->apCsr[pOp->p1]; |
| 66921 | + assert( u.ba.pC!=0 ); |
| 66922 | + assert( u.ba.pC->pseudoTableReg==0 ); |
| 66925 | 66923 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 66926 | 66924 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 66927 | 66925 | 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 ){ |
| 66926 | + assert( u.ba.pC->isOrdered ); |
| 66927 | + if( ALWAYS(u.ba.pC->pCursor!=0) ){ |
| 66928 | + u.ba.oc = pOp->opcode; |
| 66929 | + u.ba.pC->nullRow = 0; |
| 66930 | + if( u.ba.pC->isTable ){ |
| 66933 | 66931 | /* The input value in P3 might be of any type: integer, real, string, |
| 66934 | 66932 | ** blob, or NULL. But it needs to be an integer before we can do |
| 66935 | 66933 | ** the seek, so covert it. */ |
| 66936 | 66934 | pIn3 = &aMem[pOp->p3]; |
| 66937 | 66935 | applyNumericAffinity(pIn3); |
| 66938 | | - u.az.iKey = sqlite3VdbeIntValue(pIn3); |
| 66939 | | - u.az.pC->rowidIsValid = 0; |
| 66936 | + u.ba.iKey = sqlite3VdbeIntValue(pIn3); |
| 66937 | + u.ba.pC->rowidIsValid = 0; |
| 66940 | 66938 | |
| 66941 | 66939 | /* If the P3 value could not be converted into an integer without |
| 66942 | 66940 | ** loss of information, then special processing is required... */ |
| 66943 | 66941 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 66944 | 66942 | if( (pIn3->flags & MEM_Real)==0 ){ |
| | @@ -66949,105 +66947,105 @@ |
| 66949 | 66947 | } |
| 66950 | 66948 | /* If we reach this point, then the P3 value must be a floating |
| 66951 | 66949 | ** point number. */ |
| 66952 | 66950 | assert( (pIn3->flags & MEM_Real)!=0 ); |
| 66953 | 66951 | |
| 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 ){ |
| 66952 | + if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ |
| 66953 | + /* The P3 value is too large in magnitude to be expressed as an |
| 66954 | + ** integer. */ |
| 66955 | + u.ba.res = 1; |
| 66956 | + if( pIn3->r<0 ){ |
| 66957 | + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); |
| 66958 | + rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); |
| 66959 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66960 | + } |
| 66961 | + }else{ |
| 66962 | + if( u.ba.oc<=OP_SeekLe ){ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); |
| 66963 | + rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); |
| 66964 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 66965 | + } |
| 66966 | + } |
| 66967 | + if( u.ba.res ){ |
| 66968 | + pc = pOp->p2 - 1; |
| 66969 | + } |
| 66970 | + break; |
| 66971 | + }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ |
| 66972 | + /* Use the ceiling() function to convert real->int */ |
| 66973 | + if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; |
| 66974 | + }else{ |
| 66975 | + /* Use the floor() function to convert real->int */ |
| 66976 | + assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); |
| 66977 | + if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; |
| 66978 | + } |
| 66979 | + } |
| 66980 | + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); |
| 66981 | + if( rc!=SQLITE_OK ){ |
| 66982 | + goto abort_due_to_error; |
| 66983 | + } |
| 66984 | + if( u.ba.res==0 ){ |
| 66985 | + u.ba.pC->rowidIsValid = 1; |
| 66986 | + u.ba.pC->lastRowid = u.ba.iKey; |
| 66987 | + } |
| 66988 | + }else{ |
| 66989 | + u.ba.nField = pOp->p4.i; |
| 66990 | + assert( pOp->p4type==P4_INT32 ); |
| 66991 | + assert( u.ba.nField>0 ); |
| 66992 | + u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; |
| 66993 | + u.ba.r.nField = (u16)u.ba.nField; |
| 66994 | + |
| 66995 | + /* The next line of code computes as follows, only faster: |
| 66996 | + ** if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ |
| 66997 | + ** u.ba.r.flags = UNPACKED_INCRKEY; |
| 66998 | + ** }else{ |
| 66999 | + ** u.ba.r.flags = 0; |
| 67000 | + ** } |
| 67001 | + */ |
| 67002 | + u.ba.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.ba.oc - OP_SeekLt))); |
| 67003 | + assert( u.ba.oc!=OP_SeekGt || u.ba.r.flags==UNPACKED_INCRKEY ); |
| 67004 | + assert( u.ba.oc!=OP_SeekLe || u.ba.r.flags==UNPACKED_INCRKEY ); |
| 67005 | + assert( u.ba.oc!=OP_SeekGe || u.ba.r.flags==0 ); |
| 67006 | + assert( u.ba.oc!=OP_SeekLt || u.ba.r.flags==0 ); |
| 67007 | + |
| 67008 | + u.ba.r.aMem = &aMem[pOp->p3]; |
| 67009 | +#ifdef SQLITE_DEBUG |
| 67010 | + { int i; for(i=0; i<u.ba.r.nField; i++) assert( memIsValid(&u.ba.r.aMem[i]) ); } |
| 67011 | +#endif |
| 67012 | + ExpandBlob(u.ba.r.aMem); |
| 67013 | + rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); |
| 67014 | + if( rc!=SQLITE_OK ){ |
| 67015 | + goto abort_due_to_error; |
| 67016 | + } |
| 67017 | + u.ba.pC->rowidIsValid = 0; |
| 67018 | + } |
| 67019 | + u.ba.pC->deferredMoveto = 0; |
| 67020 | + u.ba.pC->cacheStatus = CACHE_STALE; |
| 67021 | +#ifdef SQLITE_TEST |
| 67022 | + sqlite3_search_count++; |
| 67023 | +#endif |
| 67024 | + if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); |
| 67025 | + if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ |
| 67026 | + rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); |
| 67027 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67028 | + u.ba.pC->rowidIsValid = 0; |
| 67029 | + }else{ |
| 67030 | + u.ba.res = 0; |
| 67031 | + } |
| 67032 | + }else{ |
| 67033 | + assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); |
| 67034 | + if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ |
| 67035 | + rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); |
| 67036 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 67037 | + u.ba.pC->rowidIsValid = 0; |
| 67038 | + }else{ |
| 67039 | + /* u.ba.res might be negative because the table is empty. Check to |
| 67040 | + ** see if this is the case. |
| 67041 | + */ |
| 67042 | + u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); |
| 67043 | + } |
| 67044 | + } |
| 67045 | + assert( pOp->p2>0 ); |
| 67046 | + if( u.ba.res ){ |
| 67049 | 67047 | pc = pOp->p2 - 1; |
| 67050 | 67048 | } |
| 67051 | 67049 | }else{ |
| 67052 | 67050 | /* This happens when attempting to open the sqlite3_master table |
| 67053 | 67051 | ** for read access returns SQLITE_EMPTY. In this case always |
| | @@ -67066,24 +67064,24 @@ |
| 67066 | 67064 | ** This is actually a deferred seek. Nothing actually happens until |
| 67067 | 67065 | ** the cursor is used to read a record. That way, if no reads |
| 67068 | 67066 | ** occur, no unnecessary I/O happens. |
| 67069 | 67067 | */ |
| 67070 | 67068 | case OP_Seek: { /* in2 */ |
| 67071 | | -#if 0 /* local variables moved into u.ba */ |
| 67069 | +#if 0 /* local variables moved into u.bb */ |
| 67072 | 67070 | VdbeCursor *pC; |
| 67073 | | -#endif /* local variables moved into u.ba */ |
| 67071 | +#endif /* local variables moved into u.bb */ |
| 67074 | 67072 | |
| 67075 | 67073 | 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; |
| 67074 | + u.bb.pC = p->apCsr[pOp->p1]; |
| 67075 | + assert( u.bb.pC!=0 ); |
| 67076 | + if( ALWAYS(u.bb.pC->pCursor!=0) ){ |
| 67077 | + assert( u.bb.pC->isTable ); |
| 67078 | + u.bb.pC->nullRow = 0; |
| 67081 | 67079 | pIn2 = &aMem[pOp->p2]; |
| 67082 | | - u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67083 | | - u.ba.pC->rowidIsValid = 0; |
| 67084 | | - u.ba.pC->deferredMoveto = 1; |
| 67080 | + u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 67081 | + u.bb.pC->rowidIsValid = 0; |
| 67082 | + u.bb.pC->deferredMoveto = 1; |
| 67085 | 67083 | } |
| 67086 | 67084 | break; |
| 67087 | 67085 | } |
| 67088 | 67086 | |
| 67089 | 67087 | |
| | @@ -67111,66 +67109,67 @@ |
| 67111 | 67109 | ** |
| 67112 | 67110 | ** See also: Found, NotExists, IsUnique |
| 67113 | 67111 | */ |
| 67114 | 67112 | case OP_NotFound: /* jump, in3 */ |
| 67115 | 67113 | case OP_Found: { /* jump, in3 */ |
| 67116 | | -#if 0 /* local variables moved into u.bb */ |
| 67114 | +#if 0 /* local variables moved into u.bc */ |
| 67117 | 67115 | int alreadyExists; |
| 67118 | 67116 | VdbeCursor *pC; |
| 67119 | 67117 | int res; |
| 67118 | + char *pFree; |
| 67120 | 67119 | UnpackedRecord *pIdxKey; |
| 67121 | 67120 | UnpackedRecord r; |
| 67122 | 67121 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
| 67123 | | -#endif /* local variables moved into u.bb */ |
| 67122 | +#endif /* local variables moved into u.bc */ |
| 67124 | 67123 | |
| 67125 | 67124 | #ifdef SQLITE_TEST |
| 67126 | 67125 | sqlite3_found_count++; |
| 67127 | 67126 | #endif |
| 67128 | 67127 | |
| 67129 | | - u.bb.alreadyExists = 0; |
| 67128 | + u.bc.alreadyExists = 0; |
| 67130 | 67129 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67131 | 67130 | assert( pOp->p4type==P4_INT32 ); |
| 67132 | | - u.bb.pC = p->apCsr[pOp->p1]; |
| 67133 | | - assert( u.bb.pC!=0 ); |
| 67131 | + u.bc.pC = p->apCsr[pOp->p1]; |
| 67132 | + assert( u.bc.pC!=0 ); |
| 67134 | 67133 | pIn3 = &aMem[pOp->p3]; |
| 67135 | | - if( ALWAYS(u.bb.pC->pCursor!=0) ){ |
| 67134 | + if( ALWAYS(u.bc.pC->pCursor!=0) ){ |
| 67136 | 67135 | |
| 67137 | | - assert( u.bb.pC->isTable==0 ); |
| 67136 | + assert( u.bc.pC->isTable==0 ); |
| 67138 | 67137 | 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; |
| 67138 | + u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; |
| 67139 | + u.bc.r.nField = (u16)pOp->p4.i; |
| 67140 | + u.bc.r.aMem = pIn3; |
| 67142 | 67141 | #ifdef SQLITE_DEBUG |
| 67143 | | - { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); } |
| 67142 | + { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } |
| 67144 | 67143 | #endif |
| 67145 | | - u.bb.r.flags = UNPACKED_PREFIX_MATCH; |
| 67146 | | - u.bb.pIdxKey = &u.bb.r; |
| 67144 | + u.bc.r.flags = UNPACKED_PREFIX_MATCH; |
| 67145 | + u.bc.pIdxKey = &u.bc.r; |
| 67147 | 67146 | }else{ |
| 67147 | + u.bc.pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 67148 | + u.bc.pC->pKeyInfo, u.bc.aTempRec, sizeof(u.bc.aTempRec), &u.bc.pFree |
| 67149 | + ); |
| 67150 | + if( u.bc.pIdxKey==0 ) goto no_mem; |
| 67148 | 67151 | assert( pIn3->flags & MEM_Blob ); |
| 67149 | 67152 | 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); |
| 67153 | + sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, u.bc.pIdxKey); |
| 67154 | + u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 67155 | + } |
| 67156 | + rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); |
| 67158 | 67157 | if( pOp->p4.i==0 ){ |
| 67159 | | - sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey); |
| 67158 | + sqlite3DbFree(db, u.bc.pFree); |
| 67160 | 67159 | } |
| 67161 | 67160 | if( rc!=SQLITE_OK ){ |
| 67162 | 67161 | break; |
| 67163 | 67162 | } |
| 67164 | | - u.bb.alreadyExists = (u.bb.res==0); |
| 67165 | | - u.bb.pC->deferredMoveto = 0; |
| 67166 | | - u.bb.pC->cacheStatus = CACHE_STALE; |
| 67163 | + u.bc.alreadyExists = (u.bc.res==0); |
| 67164 | + u.bc.pC->deferredMoveto = 0; |
| 67165 | + u.bc.pC->cacheStatus = CACHE_STALE; |
| 67167 | 67166 | } |
| 67168 | 67167 | if( pOp->opcode==OP_Found ){ |
| 67169 | | - if( u.bb.alreadyExists ) pc = pOp->p2 - 1; |
| 67168 | + if( u.bc.alreadyExists ) pc = pOp->p2 - 1; |
| 67170 | 67169 | }else{ |
| 67171 | | - if( !u.bb.alreadyExists ) pc = pOp->p2 - 1; |
| 67170 | + if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; |
| 67172 | 67171 | } |
| 67173 | 67172 | break; |
| 67174 | 67173 | } |
| 67175 | 67174 | |
| 67176 | 67175 | /* Opcode: IsUnique P1 P2 P3 P4 * |
| | @@ -67198,67 +67197,67 @@ |
| 67198 | 67197 | ** instruction. |
| 67199 | 67198 | ** |
| 67200 | 67199 | ** See also: NotFound, NotExists, Found |
| 67201 | 67200 | */ |
| 67202 | 67201 | case OP_IsUnique: { /* jump, in3 */ |
| 67203 | | -#if 0 /* local variables moved into u.bc */ |
| 67202 | +#if 0 /* local variables moved into u.bd */ |
| 67204 | 67203 | u16 ii; |
| 67205 | 67204 | VdbeCursor *pCx; |
| 67206 | 67205 | BtCursor *pCrsr; |
| 67207 | 67206 | u16 nField; |
| 67208 | 67207 | Mem *aMx; |
| 67209 | 67208 | UnpackedRecord r; /* B-Tree index search key */ |
| 67210 | 67209 | i64 R; /* Rowid stored in register P3 */ |
| 67211 | | -#endif /* local variables moved into u.bc */ |
| 67210 | +#endif /* local variables moved into u.bd */ |
| 67212 | 67211 | |
| 67213 | 67212 | pIn3 = &aMem[pOp->p3]; |
| 67214 | | - u.bc.aMx = &aMem[pOp->p4.i]; |
| 67213 | + u.bd.aMx = &aMem[pOp->p4.i]; |
| 67215 | 67214 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 67216 | 67215 | assert( pOp->p4type==P4_INT32 ); |
| 67217 | 67216 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 67218 | 67217 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67219 | 67218 | |
| 67220 | 67219 | /* 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; |
| 67220 | + u.bd.pCx = p->apCsr[pOp->p1]; |
| 67221 | + assert( u.bd.pCx->deferredMoveto==0 ); |
| 67222 | + u.bd.pCx->seekResult = 0; |
| 67223 | + u.bd.pCx->cacheStatus = CACHE_STALE; |
| 67224 | + u.bd.pCrsr = u.bd.pCx->pCursor; |
| 67226 | 67225 | |
| 67227 | 67226 | /* 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 ){ |
| 67227 | + u.bd.nField = u.bd.pCx->pKeyInfo->nField; |
| 67228 | + for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ |
| 67229 | + if( u.bd.aMx[u.bd.ii].flags & MEM_Null ){ |
| 67231 | 67230 | pc = pOp->p2 - 1; |
| 67232 | | - u.bc.pCrsr = 0; |
| 67231 | + u.bd.pCrsr = 0; |
| 67233 | 67232 | break; |
| 67234 | 67233 | } |
| 67235 | 67234 | } |
| 67236 | | - assert( (u.bc.aMx[u.bc.nField].flags & MEM_Null)==0 ); |
| 67235 | + assert( (u.bd.aMx[u.bd.nField].flags & MEM_Null)==0 ); |
| 67237 | 67236 | |
| 67238 | | - if( u.bc.pCrsr!=0 ){ |
| 67237 | + if( u.bd.pCrsr!=0 ){ |
| 67239 | 67238 | /* 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; |
| 67239 | + u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; |
| 67240 | + u.bd.r.nField = u.bd.nField + 1; |
| 67241 | + u.bd.r.flags = UNPACKED_PREFIX_SEARCH; |
| 67242 | + u.bd.r.aMem = u.bd.aMx; |
| 67244 | 67243 | #ifdef SQLITE_DEBUG |
| 67245 | | - { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } |
| 67244 | + { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } |
| 67246 | 67245 | #endif |
| 67247 | 67246 | |
| 67248 | | - /* Extract the value of u.bc.R from register P3. */ |
| 67247 | + /* Extract the value of u.bd.R from register P3. */ |
| 67249 | 67248 | sqlite3VdbeMemIntegerify(pIn3); |
| 67250 | | - u.bc.R = pIn3->u.i; |
| 67249 | + u.bd.R = pIn3->u.i; |
| 67251 | 67250 | |
| 67252 | 67251 | /* Search the B-Tree index. If no conflicting record is found, jump |
| 67253 | 67252 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
| 67254 | 67253 | ** 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 ){ |
| 67254 | + rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); |
| 67255 | + if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ |
| 67257 | 67256 | pc = pOp->p2 - 1; |
| 67258 | 67257 | }else{ |
| 67259 | | - pIn3->u.i = u.bc.r.rowid; |
| 67258 | + pIn3->u.i = u.bd.r.rowid; |
| 67260 | 67259 | } |
| 67261 | 67260 | } |
| 67262 | 67261 | break; |
| 67263 | 67262 | } |
| 67264 | 67263 | |
| | @@ -67275,46 +67274,46 @@ |
| 67275 | 67274 | ** P1 is an index. |
| 67276 | 67275 | ** |
| 67277 | 67276 | ** See also: Found, NotFound, IsUnique |
| 67278 | 67277 | */ |
| 67279 | 67278 | case OP_NotExists: { /* jump, in3 */ |
| 67280 | | -#if 0 /* local variables moved into u.bd */ |
| 67279 | +#if 0 /* local variables moved into u.be */ |
| 67281 | 67280 | VdbeCursor *pC; |
| 67282 | 67281 | BtCursor *pCrsr; |
| 67283 | 67282 | int res; |
| 67284 | 67283 | u64 iKey; |
| 67285 | | -#endif /* local variables moved into u.bd */ |
| 67284 | +#endif /* local variables moved into u.be */ |
| 67286 | 67285 | |
| 67287 | 67286 | pIn3 = &aMem[pOp->p3]; |
| 67288 | 67287 | assert( pIn3->flags & MEM_Int ); |
| 67289 | 67288 | 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 ){ |
| 67289 | + u.be.pC = p->apCsr[pOp->p1]; |
| 67290 | + assert( u.be.pC!=0 ); |
| 67291 | + assert( u.be.pC->isTable ); |
| 67292 | + assert( u.be.pC->pseudoTableReg==0 ); |
| 67293 | + u.be.pCrsr = u.be.pC->pCursor; |
| 67294 | + if( ALWAYS(u.be.pCrsr!=0) ){ |
| 67295 | + u.be.res = 0; |
| 67296 | + u.be.iKey = pIn3->u.i; |
| 67297 | + rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); |
| 67298 | + u.be.pC->lastRowid = pIn3->u.i; |
| 67299 | + u.be.pC->rowidIsValid = u.be.res==0 ?1:0; |
| 67300 | + u.be.pC->nullRow = 0; |
| 67301 | + u.be.pC->cacheStatus = CACHE_STALE; |
| 67302 | + u.be.pC->deferredMoveto = 0; |
| 67303 | + if( u.be.res!=0 ){ |
| 67305 | 67304 | pc = pOp->p2 - 1; |
| 67306 | | - assert( u.bd.pC->rowidIsValid==0 ); |
| 67305 | + assert( u.be.pC->rowidIsValid==0 ); |
| 67307 | 67306 | } |
| 67308 | | - u.bd.pC->seekResult = u.bd.res; |
| 67307 | + u.be.pC->seekResult = u.be.res; |
| 67309 | 67308 | }else{ |
| 67310 | 67309 | /* This happens when an attempt to open a read cursor on the |
| 67311 | 67310 | ** sqlite_master table returns SQLITE_EMPTY. |
| 67312 | 67311 | */ |
| 67313 | 67312 | pc = pOp->p2 - 1; |
| 67314 | | - assert( u.bd.pC->rowidIsValid==0 ); |
| 67315 | | - u.bd.pC->seekResult = 0; |
| 67313 | + assert( u.be.pC->rowidIsValid==0 ); |
| 67314 | + u.be.pC->seekResult = 0; |
| 67316 | 67315 | } |
| 67317 | 67316 | break; |
| 67318 | 67317 | } |
| 67319 | 67318 | |
| 67320 | 67319 | /* Opcode: Sequence P1 P2 * * * |
| | @@ -67345,25 +67344,25 @@ |
| 67345 | 67344 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 67346 | 67345 | ** generated record number. This P3 mechanism is used to help implement the |
| 67347 | 67346 | ** AUTOINCREMENT feature. |
| 67348 | 67347 | */ |
| 67349 | 67348 | case OP_NewRowid: { /* out2-prerelease */ |
| 67350 | | -#if 0 /* local variables moved into u.be */ |
| 67349 | +#if 0 /* local variables moved into u.bf */ |
| 67351 | 67350 | i64 v; /* The new rowid */ |
| 67352 | 67351 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 67353 | 67352 | int res; /* Result of an sqlite3BtreeLast() */ |
| 67354 | 67353 | int cnt; /* Counter to limit the number of searches */ |
| 67355 | 67354 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 67356 | 67355 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 67357 | | -#endif /* local variables moved into u.be */ |
| 67356 | +#endif /* local variables moved into u.bf */ |
| 67358 | 67357 | |
| 67359 | | - u.be.v = 0; |
| 67360 | | - u.be.res = 0; |
| 67358 | + u.bf.v = 0; |
| 67359 | + u.bf.res = 0; |
| 67361 | 67360 | 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) ){ |
| 67361 | + u.bf.pC = p->apCsr[pOp->p1]; |
| 67362 | + assert( u.bf.pC!=0 ); |
| 67363 | + if( NEVER(u.bf.pC->pCursor==0) ){ |
| 67365 | 67364 | /* The zero initialization above is all that is needed */ |
| 67366 | 67365 | }else{ |
| 67367 | 67366 | /* The next rowid or record number (different terms for the same |
| 67368 | 67367 | ** thing) is obtained in a two-step algorithm. |
| 67369 | 67368 | ** |
| | @@ -67375,11 +67374,11 @@ |
| 67375 | 67374 | ** The second algorithm is to select a rowid at random and see if |
| 67376 | 67375 | ** it already exists in the table. If it does not exist, we have |
| 67377 | 67376 | ** succeeded. If the random rowid does exist, we select a new one |
| 67378 | 67377 | ** and try again, up to 100 times. |
| 67379 | 67378 | */ |
| 67380 | | - assert( u.be.pC->isTable ); |
| 67379 | + assert( u.bf.pC->isTable ); |
| 67381 | 67380 | |
| 67382 | 67381 | #ifdef SQLITE_32BIT_ROWID |
| 67383 | 67382 | # define MAX_ROWID 0x7fffffff |
| 67384 | 67383 | #else |
| 67385 | 67384 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| | @@ -67387,101 +67386,101 @@ |
| 67387 | 67386 | ** to provide the constant while making all compilers happy. |
| 67388 | 67387 | */ |
| 67389 | 67388 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 67390 | 67389 | #endif |
| 67391 | 67390 | |
| 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); |
| 67391 | + if( !u.bf.pC->useRandomRowid ){ |
| 67392 | + u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); |
| 67393 | + if( u.bf.v==0 ){ |
| 67394 | + rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); |
| 67396 | 67395 | if( rc!=SQLITE_OK ){ |
| 67397 | 67396 | goto abort_due_to_error; |
| 67398 | 67397 | } |
| 67399 | | - if( u.be.res ){ |
| 67400 | | - u.be.v = 1; /* IMP: R-61914-48074 */ |
| 67398 | + if( u.bf.res ){ |
| 67399 | + u.bf.v = 1; /* IMP: R-61914-48074 */ |
| 67401 | 67400 | }else{ |
| 67402 | | - assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) ); |
| 67403 | | - rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v); |
| 67401 | + assert( sqlite3BtreeCursorIsValid(u.bf.pC->pCursor) ); |
| 67402 | + rc = sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); |
| 67404 | 67403 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 67405 | | - if( u.be.v==MAX_ROWID ){ |
| 67406 | | - u.be.pC->useRandomRowid = 1; |
| 67404 | + if( u.bf.v==MAX_ROWID ){ |
| 67405 | + u.bf.pC->useRandomRowid = 1; |
| 67407 | 67406 | }else{ |
| 67408 | | - u.be.v++; /* IMP: R-29538-34987 */ |
| 67407 | + u.bf.v++; /* IMP: R-29538-34987 */ |
| 67409 | 67408 | } |
| 67410 | 67409 | } |
| 67411 | 67410 | } |
| 67412 | 67411 | |
| 67413 | 67412 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 67414 | 67413 | if( pOp->p3 ){ |
| 67415 | 67414 | /* Assert that P3 is a valid memory cell. */ |
| 67416 | 67415 | assert( pOp->p3>0 ); |
| 67417 | 67416 | if( p->pFrame ){ |
| 67418 | | - for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent); |
| 67417 | + for(u.bf.pFrame=p->pFrame; u.bf.pFrame->pParent; u.bf.pFrame=u.bf.pFrame->pParent); |
| 67419 | 67418 | /* 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]; |
| 67419 | + assert( pOp->p3<=u.bf.pFrame->nMem ); |
| 67420 | + u.bf.pMem = &u.bf.pFrame->aMem[pOp->p3]; |
| 67422 | 67421 | }else{ |
| 67423 | 67422 | /* Assert that P3 is a valid memory cell. */ |
| 67424 | 67423 | 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 ){ |
| 67424 | + u.bf.pMem = &aMem[pOp->p3]; |
| 67425 | + memAboutToChange(p, u.bf.pMem); |
| 67426 | + } |
| 67427 | + assert( memIsValid(u.bf.pMem) ); |
| 67428 | + |
| 67429 | + REGISTER_TRACE(pOp->p3, u.bf.pMem); |
| 67430 | + sqlite3VdbeMemIntegerify(u.bf.pMem); |
| 67431 | + assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 67432 | + if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ |
| 67434 | 67433 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 67435 | 67434 | goto abort_due_to_error; |
| 67436 | 67435 | } |
| 67437 | | - if( u.be.v<u.be.pMem->u.i+1 ){ |
| 67438 | | - u.be.v = u.be.pMem->u.i + 1; |
| 67436 | + if( u.bf.v<u.bf.pMem->u.i+1 ){ |
| 67437 | + u.bf.v = u.bf.pMem->u.i + 1; |
| 67439 | 67438 | } |
| 67440 | | - u.be.pMem->u.i = u.be.v; |
| 67439 | + u.bf.pMem->u.i = u.bf.v; |
| 67441 | 67440 | } |
| 67442 | 67441 | #endif |
| 67443 | 67442 | |
| 67444 | | - sqlite3BtreeSetCachedRowid(u.be.pC->pCursor, u.be.v<MAX_ROWID ? u.be.v+1 : 0); |
| 67443 | + sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); |
| 67445 | 67444 | } |
| 67446 | | - if( u.be.pC->useRandomRowid ){ |
| 67445 | + if( u.bf.pC->useRandomRowid ){ |
| 67447 | 67446 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 67448 | 67447 | ** largest possible integer (9223372036854775807) then the database |
| 67449 | 67448 | ** engine starts picking positive candidate ROWIDs at random until |
| 67450 | 67449 | ** it finds one that is not previously used. */ |
| 67451 | 67450 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 67452 | 67451 | ** an AUTOINCREMENT table. */ |
| 67453 | 67452 | /* 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)){ |
| 67453 | + u.bf.v = lastRowid; |
| 67454 | + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67455 | + u.bf.v++; /* ensure non-zero */ |
| 67456 | + u.bf.cnt = 0; |
| 67457 | + while( ((rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, |
| 67458 | + 0, &u.bf.res))==SQLITE_OK) |
| 67459 | + && (u.bf.res==0) |
| 67460 | + && (++u.bf.cnt<100)){ |
| 67462 | 67461 | /* collision - try another random rowid */ |
| 67463 | | - sqlite3_randomness(sizeof(u.be.v), &u.be.v); |
| 67464 | | - if( u.be.cnt<5 ){ |
| 67462 | + sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); |
| 67463 | + if( u.bf.cnt<5 ){ |
| 67465 | 67464 | /* try "small" random rowids for the initial attempts */ |
| 67466 | | - u.be.v &= 0xffffff; |
| 67465 | + u.bf.v &= 0xffffff; |
| 67467 | 67466 | }else{ |
| 67468 | | - u.be.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67467 | + u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 67469 | 67468 | } |
| 67470 | | - u.be.v++; /* ensure non-zero */ |
| 67469 | + u.bf.v++; /* ensure non-zero */ |
| 67471 | 67470 | } |
| 67472 | | - if( rc==SQLITE_OK && u.be.res==0 ){ |
| 67471 | + if( rc==SQLITE_OK && u.bf.res==0 ){ |
| 67473 | 67472 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 67474 | 67473 | goto abort_due_to_error; |
| 67475 | 67474 | } |
| 67476 | | - assert( u.be.v>0 ); /* EV: R-40812-03570 */ |
| 67475 | + assert( u.bf.v>0 ); /* EV: R-40812-03570 */ |
| 67477 | 67476 | } |
| 67478 | | - u.be.pC->rowidIsValid = 0; |
| 67479 | | - u.be.pC->deferredMoveto = 0; |
| 67480 | | - u.be.pC->cacheStatus = CACHE_STALE; |
| 67477 | + u.bf.pC->rowidIsValid = 0; |
| 67478 | + u.bf.pC->deferredMoveto = 0; |
| 67479 | + u.bf.pC->cacheStatus = CACHE_STALE; |
| 67481 | 67480 | } |
| 67482 | | - pOut->u.i = u.be.v; |
| 67481 | + pOut->u.i = u.bf.v; |
| 67483 | 67482 | break; |
| 67484 | 67483 | } |
| 67485 | 67484 | |
| 67486 | 67485 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 67487 | 67486 | ** |
| | @@ -67527,74 +67526,74 @@ |
| 67527 | 67526 | ** This works exactly like OP_Insert except that the key is the |
| 67528 | 67527 | ** integer value P3, not the value of the integer stored in register P3. |
| 67529 | 67528 | */ |
| 67530 | 67529 | case OP_Insert: |
| 67531 | 67530 | case OP_InsertInt: { |
| 67532 | | -#if 0 /* local variables moved into u.bf */ |
| 67531 | +#if 0 /* local variables moved into u.bg */ |
| 67533 | 67532 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 67534 | 67533 | Mem *pKey; /* MEM cell holding key for the record */ |
| 67535 | 67534 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 67536 | 67535 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 67537 | 67536 | int nZero; /* Number of zero-bytes to append */ |
| 67538 | 67537 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 67539 | 67538 | const char *zDb; /* database name - used by the update hook */ |
| 67540 | 67539 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 67541 | 67540 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 67542 | | -#endif /* local variables moved into u.bf */ |
| 67541 | +#endif /* local variables moved into u.bg */ |
| 67543 | 67542 | |
| 67544 | | - u.bf.pData = &aMem[pOp->p2]; |
| 67543 | + u.bg.pData = &aMem[pOp->p2]; |
| 67545 | 67544 | 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); |
| 67545 | + assert( memIsValid(u.bg.pData) ); |
| 67546 | + u.bg.pC = p->apCsr[pOp->p1]; |
| 67547 | + assert( u.bg.pC!=0 ); |
| 67548 | + assert( u.bg.pC->pCursor!=0 ); |
| 67549 | + assert( u.bg.pC->pseudoTableReg==0 ); |
| 67550 | + assert( u.bg.pC->isTable ); |
| 67551 | + REGISTER_TRACE(pOp->p2, u.bg.pData); |
| 67553 | 67552 | |
| 67554 | 67553 | 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; |
| 67554 | + u.bg.pKey = &aMem[pOp->p3]; |
| 67555 | + assert( u.bg.pKey->flags & MEM_Int ); |
| 67556 | + assert( memIsValid(u.bg.pKey) ); |
| 67557 | + REGISTER_TRACE(pOp->p3, u.bg.pKey); |
| 67558 | + u.bg.iKey = u.bg.pKey->u.i; |
| 67560 | 67559 | }else{ |
| 67561 | 67560 | assert( pOp->opcode==OP_InsertInt ); |
| 67562 | | - u.bf.iKey = pOp->p3; |
| 67561 | + u.bg.iKey = pOp->p3; |
| 67563 | 67562 | } |
| 67564 | 67563 | |
| 67565 | 67564 | 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 |
| 67565 | + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey; |
| 67566 | + if( u.bg.pData->flags & MEM_Null ){ |
| 67567 | + u.bg.pData->z = 0; |
| 67568 | + u.bg.pData->n = 0; |
| 67569 | + }else{ |
| 67570 | + assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); |
| 67571 | + } |
| 67572 | + u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); |
| 67573 | + if( u.bg.pData->flags & MEM_Zero ){ |
| 67574 | + u.bg.nZero = u.bg.pData->u.nZero; |
| 67575 | + }else{ |
| 67576 | + u.bg.nZero = 0; |
| 67577 | + } |
| 67578 | + sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); |
| 67579 | + rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, |
| 67580 | + u.bg.pData->z, u.bg.pData->n, u.bg.nZero, |
| 67581 | + pOp->p5 & OPFLAG_APPEND, u.bg.seekResult |
| 67583 | 67582 | ); |
| 67584 | | - u.bf.pC->rowidIsValid = 0; |
| 67585 | | - u.bf.pC->deferredMoveto = 0; |
| 67586 | | - u.bf.pC->cacheStatus = CACHE_STALE; |
| 67583 | + u.bg.pC->rowidIsValid = 0; |
| 67584 | + u.bg.pC->deferredMoveto = 0; |
| 67585 | + u.bg.pC->cacheStatus = CACHE_STALE; |
| 67587 | 67586 | |
| 67588 | 67587 | /* Invoke the update-hook if required. */ |
| 67589 | 67588 | 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 ); |
| 67589 | + u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; |
| 67590 | + u.bg.zTbl = pOp->p4.z; |
| 67591 | + u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 67592 | + assert( u.bg.pC->isTable ); |
| 67593 | + db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); |
| 67594 | + assert( u.bg.pC->iDb>=0 ); |
| 67596 | 67595 | } |
| 67597 | 67596 | break; |
| 67598 | 67597 | } |
| 67599 | 67598 | |
| 67600 | 67599 | /* Opcode: Delete P1 P2 * P4 * |
| | @@ -67616,51 +67615,51 @@ |
| 67616 | 67615 | ** pointing to. The update hook will be invoked, if it exists. |
| 67617 | 67616 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 67618 | 67617 | ** using OP_NotFound prior to invoking this opcode. |
| 67619 | 67618 | */ |
| 67620 | 67619 | case OP_Delete: { |
| 67621 | | -#if 0 /* local variables moved into u.bg */ |
| 67620 | +#if 0 /* local variables moved into u.bh */ |
| 67622 | 67621 | i64 iKey; |
| 67623 | 67622 | VdbeCursor *pC; |
| 67624 | | -#endif /* local variables moved into u.bg */ |
| 67623 | +#endif /* local variables moved into u.bh */ |
| 67625 | 67624 | |
| 67626 | | - u.bg.iKey = 0; |
| 67625 | + u.bh.iKey = 0; |
| 67627 | 67626 | 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 */ |
| 67627 | + u.bh.pC = p->apCsr[pOp->p1]; |
| 67628 | + assert( u.bh.pC!=0 ); |
| 67629 | + assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 67631 | 67630 | |
| 67632 | | - /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the |
| 67631 | + /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the |
| 67633 | 67632 | ** row being deleted. |
| 67634 | 67633 | */ |
| 67635 | 67634 | 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; |
| 67635 | + assert( u.bh.pC->isTable ); |
| 67636 | + assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 67637 | + u.bh.iKey = u.bh.pC->lastRowid; |
| 67639 | 67638 | } |
| 67640 | 67639 | |
| 67641 | 67640 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 67642 | 67641 | ** 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 |
| 67642 | + ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing |
| 67644 | 67643 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 67645 | 67644 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 67646 | 67645 | ** to guard against future changes to the code generator. |
| 67647 | 67646 | **/ |
| 67648 | | - assert( u.bg.pC->deferredMoveto==0 ); |
| 67649 | | - rc = sqlite3VdbeCursorMoveto(u.bg.pC); |
| 67647 | + assert( u.bh.pC->deferredMoveto==0 ); |
| 67648 | + rc = sqlite3VdbeCursorMoveto(u.bh.pC); |
| 67650 | 67649 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67651 | 67650 | |
| 67652 | | - sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); |
| 67653 | | - rc = sqlite3BtreeDelete(u.bg.pC->pCursor); |
| 67654 | | - u.bg.pC->cacheStatus = CACHE_STALE; |
| 67651 | + sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); |
| 67652 | + rc = sqlite3BtreeDelete(u.bh.pC->pCursor); |
| 67653 | + u.bh.pC->cacheStatus = CACHE_STALE; |
| 67655 | 67654 | |
| 67656 | 67655 | /* Invoke the update-hook if required. */ |
| 67657 | 67656 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 67658 | | - const char *zDb = db->aDb[u.bg.pC->iDb].zName; |
| 67657 | + const char *zDb = db->aDb[u.bh.pC->iDb].zName; |
| 67659 | 67658 | 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 ); |
| 67659 | + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); |
| 67660 | + assert( u.bh.pC->iDb>=0 ); |
| 67662 | 67661 | } |
| 67663 | 67662 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 67664 | 67663 | break; |
| 67665 | 67664 | } |
| 67666 | 67665 | /* Opcode: ResetCount * * * * * |
| | @@ -67673,10 +67672,53 @@ |
| 67673 | 67672 | case OP_ResetCount: { |
| 67674 | 67673 | sqlite3VdbeSetChanges(db, p->nChange); |
| 67675 | 67674 | p->nChange = 0; |
| 67676 | 67675 | break; |
| 67677 | 67676 | } |
| 67677 | + |
| 67678 | +/* Opcode: SorterCompare P1 P2 P3 |
| 67679 | +** |
| 67680 | +** P1 is a sorter cursor. This instruction compares the record blob in |
| 67681 | +** register P3 with the entry that the sorter cursor currently points to. |
| 67682 | +** If, excluding the rowid fields at the end, the two records are a match, |
| 67683 | +** fall through to the next instruction. Otherwise, jump to instruction P2. |
| 67684 | +*/ |
| 67685 | +case OP_SorterCompare: { |
| 67686 | +#if 0 /* local variables moved into u.bi */ |
| 67687 | + VdbeCursor *pC; |
| 67688 | + int res; |
| 67689 | +#endif /* local variables moved into u.bi */ |
| 67690 | + |
| 67691 | + u.bi.pC = p->apCsr[pOp->p1]; |
| 67692 | + assert( isSorter(u.bi.pC) ); |
| 67693 | + pIn3 = &aMem[pOp->p3]; |
| 67694 | + rc = sqlite3VdbeSorterCompare(u.bi.pC, pIn3, &u.bi.res); |
| 67695 | + if( u.bi.res ){ |
| 67696 | + pc = pOp->p2-1; |
| 67697 | + } |
| 67698 | + break; |
| 67699 | +}; |
| 67700 | + |
| 67701 | +/* Opcode: SorterData P1 P2 * * * |
| 67702 | +** |
| 67703 | +** Write into register P2 the current sorter data for sorter cursor P1. |
| 67704 | +*/ |
| 67705 | +case OP_SorterData: { |
| 67706 | +#if 0 /* local variables moved into u.bj */ |
| 67707 | + VdbeCursor *pC; |
| 67708 | +#endif /* local variables moved into u.bj */ |
| 67709 | +#ifndef SQLITE_OMIT_MERGE_SORT |
| 67710 | + pOut = &aMem[pOp->p2]; |
| 67711 | + u.bj.pC = p->apCsr[pOp->p1]; |
| 67712 | + assert( u.bj.pC->isSorter ); |
| 67713 | + rc = sqlite3VdbeSorterRowkey(u.bj.pC, pOut); |
| 67714 | +#else |
| 67715 | + pOp->opcode = OP_RowKey; |
| 67716 | + pc--; |
| 67717 | +#endif |
| 67718 | + break; |
| 67719 | +} |
| 67678 | 67720 | |
| 67679 | 67721 | /* Opcode: RowData P1 P2 * * * |
| 67680 | 67722 | ** |
| 67681 | 67723 | ** Write into register P2 the complete row data for cursor P1. |
| 67682 | 67724 | ** There is no interpretation of the data. |
| | @@ -67696,72 +67738,67 @@ |
| 67696 | 67738 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 67697 | 67739 | ** of a real table, not a pseudo-table. |
| 67698 | 67740 | */ |
| 67699 | 67741 | case OP_RowKey: |
| 67700 | 67742 | case OP_RowData: { |
| 67701 | | -#if 0 /* local variables moved into u.bh */ |
| 67743 | +#if 0 /* local variables moved into u.bk */ |
| 67702 | 67744 | VdbeCursor *pC; |
| 67703 | 67745 | BtCursor *pCrsr; |
| 67704 | 67746 | u32 n; |
| 67705 | 67747 | i64 n64; |
| 67706 | | -#endif /* local variables moved into u.bh */ |
| 67748 | +#endif /* local variables moved into u.bk */ |
| 67707 | 67749 | |
| 67708 | 67750 | pOut = &aMem[pOp->p2]; |
| 67709 | 67751 | memAboutToChange(p, pOut); |
| 67710 | 67752 | |
| 67711 | 67753 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 67712 | 67754 | 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) ); |
| 67755 | + u.bk.pC = p->apCsr[pOp->p1]; |
| 67756 | + assert( u.bk.pC->isSorter==0 ); |
| 67757 | + assert( u.bk.pC->isTable || pOp->opcode!=OP_RowData ); |
| 67758 | + assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); |
| 67759 | + assert( u.bk.pC!=0 ); |
| 67760 | + assert( u.bk.pC->nullRow==0 ); |
| 67761 | + assert( u.bk.pC->pseudoTableReg==0 ); |
| 67762 | + assert( !u.bk.pC->isSorter ); |
| 67763 | + assert( u.bk.pC->pCursor!=0 ); |
| 67764 | + u.bk.pCrsr = u.bk.pC->pCursor; |
| 67765 | + assert( sqlite3BtreeCursorIsValid(u.bk.pCrsr) ); |
| 67729 | 67766 | |
| 67730 | 67767 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 67731 | 67768 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 67732 | 67769 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 67733 | 67770 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 67734 | 67771 | */ |
| 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); |
| 67772 | + assert( u.bk.pC->deferredMoveto==0 ); |
| 67773 | + rc = sqlite3VdbeCursorMoveto(u.bk.pC); |
| 67774 | + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 67775 | + |
| 67776 | + if( u.bk.pC->isIndex ){ |
| 67777 | + assert( !u.bk.pC->isTable ); |
| 67778 | + rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); |
| 67779 | + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 67780 | + if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67781 | + goto too_big; |
| 67782 | + } |
| 67783 | + u.bk.n = (u32)u.bk.n64; |
| 67784 | + }else{ |
| 67785 | + rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); |
| 67786 | + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 67787 | + if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67788 | + goto too_big; |
| 67789 | + } |
| 67790 | + } |
| 67791 | + if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ |
| 67792 | + goto no_mem; |
| 67793 | + } |
| 67794 | + pOut->n = u.bk.n; |
| 67795 | + MemSetTypeFlag(pOut, MEM_Blob); |
| 67796 | + if( u.bk.pC->isIndex ){ |
| 67797 | + rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); |
| 67798 | + }else{ |
| 67799 | + rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); |
| 67763 | 67800 | } |
| 67764 | 67801 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 67765 | 67802 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67766 | 67803 | break; |
| 67767 | 67804 | } |
| | @@ -67774,46 +67811,46 @@ |
| 67774 | 67811 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 67775 | 67812 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 67776 | 67813 | ** one opcode now works for both table types. |
| 67777 | 67814 | */ |
| 67778 | 67815 | case OP_Rowid: { /* out2-prerelease */ |
| 67779 | | -#if 0 /* local variables moved into u.bi */ |
| 67816 | +#if 0 /* local variables moved into u.bl */ |
| 67780 | 67817 | VdbeCursor *pC; |
| 67781 | 67818 | i64 v; |
| 67782 | 67819 | sqlite3_vtab *pVtab; |
| 67783 | 67820 | const sqlite3_module *pModule; |
| 67784 | | -#endif /* local variables moved into u.bi */ |
| 67821 | +#endif /* local variables moved into u.bl */ |
| 67785 | 67822 | |
| 67786 | 67823 | 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 ){ |
| 67824 | + u.bl.pC = p->apCsr[pOp->p1]; |
| 67825 | + assert( u.bl.pC!=0 ); |
| 67826 | + assert( u.bl.pC->pseudoTableReg==0 ); |
| 67827 | + if( u.bl.pC->nullRow ){ |
| 67791 | 67828 | pOut->flags = MEM_Null; |
| 67792 | 67829 | break; |
| 67793 | | - }else if( u.bi.pC->deferredMoveto ){ |
| 67794 | | - u.bi.v = u.bi.pC->movetoTarget; |
| 67830 | + }else if( u.bl.pC->deferredMoveto ){ |
| 67831 | + u.bl.v = u.bl.pC->movetoTarget; |
| 67795 | 67832 | #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); |
| 67833 | + }else if( u.bl.pC->pVtabCursor ){ |
| 67834 | + u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; |
| 67835 | + u.bl.pModule = u.bl.pVtab->pModule; |
| 67836 | + assert( u.bl.pModule->xRowid ); |
| 67837 | + rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); |
| 67838 | + importVtabErrMsg(p, u.bl.pVtab); |
| 67802 | 67839 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 67803 | 67840 | }else{ |
| 67804 | | - assert( u.bi.pC->pCursor!=0 ); |
| 67805 | | - rc = sqlite3VdbeCursorMoveto(u.bi.pC); |
| 67841 | + assert( u.bl.pC->pCursor!=0 ); |
| 67842 | + rc = sqlite3VdbeCursorMoveto(u.bl.pC); |
| 67806 | 67843 | if( rc ) goto abort_due_to_error; |
| 67807 | | - if( u.bi.pC->rowidIsValid ){ |
| 67808 | | - u.bi.v = u.bi.pC->lastRowid; |
| 67844 | + if( u.bl.pC->rowidIsValid ){ |
| 67845 | + u.bl.v = u.bl.pC->lastRowid; |
| 67809 | 67846 | }else{ |
| 67810 | | - rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v); |
| 67847 | + rc = sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); |
| 67811 | 67848 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 67812 | 67849 | } |
| 67813 | 67850 | } |
| 67814 | | - pOut->u.i = u.bi.v; |
| 67851 | + pOut->u.i = u.bl.v; |
| 67815 | 67852 | break; |
| 67816 | 67853 | } |
| 67817 | 67854 | |
| 67818 | 67855 | /* Opcode: NullRow P1 * * * * |
| 67819 | 67856 | ** |
| | @@ -67820,22 +67857,22 @@ |
| 67820 | 67857 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 67821 | 67858 | ** that occur while the cursor is on the null row will always |
| 67822 | 67859 | ** write a NULL. |
| 67823 | 67860 | */ |
| 67824 | 67861 | case OP_NullRow: { |
| 67825 | | -#if 0 /* local variables moved into u.bj */ |
| 67862 | +#if 0 /* local variables moved into u.bm */ |
| 67826 | 67863 | VdbeCursor *pC; |
| 67827 | | -#endif /* local variables moved into u.bj */ |
| 67864 | +#endif /* local variables moved into u.bm */ |
| 67828 | 67865 | |
| 67829 | 67866 | 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); |
| 67867 | + u.bm.pC = p->apCsr[pOp->p1]; |
| 67868 | + assert( u.bm.pC!=0 ); |
| 67869 | + u.bm.pC->nullRow = 1; |
| 67870 | + u.bm.pC->rowidIsValid = 0; |
| 67871 | + assert( u.bm.pC->pCursor || u.bm.pC->pVtabCursor ); |
| 67872 | + if( u.bm.pC->pCursor ){ |
| 67873 | + sqlite3BtreeClearCursor(u.bm.pC->pCursor); |
| 67837 | 67874 | } |
| 67838 | 67875 | break; |
| 67839 | 67876 | } |
| 67840 | 67877 | |
| 67841 | 67878 | /* Opcode: Last P1 P2 * * * |
| | @@ -67845,30 +67882,30 @@ |
| 67845 | 67882 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67846 | 67883 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67847 | 67884 | ** to the following instruction. |
| 67848 | 67885 | */ |
| 67849 | 67886 | case OP_Last: { /* jump */ |
| 67850 | | -#if 0 /* local variables moved into u.bk */ |
| 67887 | +#if 0 /* local variables moved into u.bn */ |
| 67851 | 67888 | VdbeCursor *pC; |
| 67852 | 67889 | BtCursor *pCrsr; |
| 67853 | 67890 | int res; |
| 67854 | | -#endif /* local variables moved into u.bk */ |
| 67891 | +#endif /* local variables moved into u.bn */ |
| 67855 | 67892 | |
| 67856 | 67893 | 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; |
| 67894 | + u.bn.pC = p->apCsr[pOp->p1]; |
| 67895 | + assert( u.bn.pC!=0 ); |
| 67896 | + u.bn.pCrsr = u.bn.pC->pCursor; |
| 67897 | + if( NEVER(u.bn.pCrsr==0) ){ |
| 67898 | + u.bn.res = 1; |
| 67862 | 67899 | }else{ |
| 67863 | | - rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res); |
| 67900 | + rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); |
| 67864 | 67901 | } |
| 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 ){ |
| 67902 | + u.bn.pC->nullRow = (u8)u.bn.res; |
| 67903 | + u.bn.pC->deferredMoveto = 0; |
| 67904 | + u.bn.pC->rowidIsValid = 0; |
| 67905 | + u.bn.pC->cacheStatus = CACHE_STALE; |
| 67906 | + if( pOp->p2>0 && u.bn.res ){ |
| 67870 | 67907 | pc = pOp->p2 - 1; |
| 67871 | 67908 | } |
| 67872 | 67909 | break; |
| 67873 | 67910 | } |
| 67874 | 67911 | |
| | @@ -67883,10 +67920,14 @@ |
| 67883 | 67920 | ** end. We use the OP_Sort opcode instead of OP_Rewind to do the |
| 67884 | 67921 | ** rewinding so that the global variable will be incremented and |
| 67885 | 67922 | ** regression tests can determine whether or not the optimizer is |
| 67886 | 67923 | ** correctly optimizing out sorts. |
| 67887 | 67924 | */ |
| 67925 | +case OP_SorterSort: /* jump */ |
| 67926 | +#ifdef SQLITE_OMIT_MERGE_SORT |
| 67927 | + pOp->opcode = OP_Sort; |
| 67928 | +#endif |
| 67888 | 67929 | case OP_Sort: { /* jump */ |
| 67889 | 67930 | #ifdef SQLITE_TEST |
| 67890 | 67931 | sqlite3_sort_count++; |
| 67891 | 67932 | sqlite3_search_count--; |
| 67892 | 67933 | #endif |
| | @@ -67900,34 +67941,35 @@ |
| 67900 | 67941 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 67901 | 67942 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 67902 | 67943 | ** to the following instruction. |
| 67903 | 67944 | */ |
| 67904 | 67945 | case OP_Rewind: { /* jump */ |
| 67905 | | -#if 0 /* local variables moved into u.bl */ |
| 67946 | +#if 0 /* local variables moved into u.bo */ |
| 67906 | 67947 | VdbeCursor *pC; |
| 67907 | 67948 | BtCursor *pCrsr; |
| 67908 | 67949 | int res; |
| 67909 | | -#endif /* local variables moved into u.bl */ |
| 67950 | +#endif /* local variables moved into u.bo */ |
| 67910 | 67951 | |
| 67911 | 67952 | 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); |
| 67953 | + u.bo.pC = p->apCsr[pOp->p1]; |
| 67954 | + assert( u.bo.pC!=0 ); |
| 67955 | + assert( u.bo.pC->isSorter==(pOp->opcode==OP_SorterSort) ); |
| 67956 | + u.bo.res = 1; |
| 67957 | + if( isSorter(u.bo.pC) ){ |
| 67958 | + rc = sqlite3VdbeSorterRewind(db, u.bo.pC, &u.bo.res); |
| 67917 | 67959 | }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; |
| 67960 | + u.bo.pCrsr = u.bo.pC->pCursor; |
| 67961 | + assert( u.bo.pCrsr ); |
| 67962 | + rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); |
| 67963 | + u.bo.pC->atFirst = u.bo.res==0 ?1:0; |
| 67964 | + u.bo.pC->deferredMoveto = 0; |
| 67965 | + u.bo.pC->cacheStatus = CACHE_STALE; |
| 67966 | + u.bo.pC->rowidIsValid = 0; |
| 67967 | + } |
| 67968 | + u.bo.pC->nullRow = (u8)u.bo.res; |
| 67927 | 67969 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 67928 | | - if( u.bl.res ){ |
| 67970 | + if( u.bo.res ){ |
| 67929 | 67971 | pc = pOp->p2 - 1; |
| 67930 | 67972 | } |
| 67931 | 67973 | break; |
| 67932 | 67974 | } |
| 67933 | 67975 | |
| | @@ -67961,45 +68003,50 @@ |
| 67961 | 68003 | ** sqlite3BtreePrevious(). |
| 67962 | 68004 | ** |
| 67963 | 68005 | ** If P5 is positive and the jump is taken, then event counter |
| 67964 | 68006 | ** number P5-1 in the prepared statement is incremented. |
| 67965 | 68007 | */ |
| 68008 | +case OP_SorterNext: /* jump */ |
| 68009 | +#ifdef SQLITE_OMIT_MERGE_SORT |
| 68010 | + pOp->opcode = OP_Next; |
| 68011 | +#endif |
| 67966 | 68012 | case OP_Prev: /* jump */ |
| 67967 | 68013 | case OP_Next: { /* jump */ |
| 67968 | | -#if 0 /* local variables moved into u.bm */ |
| 68014 | +#if 0 /* local variables moved into u.bp */ |
| 67969 | 68015 | VdbeCursor *pC; |
| 67970 | 68016 | int res; |
| 67971 | | -#endif /* local variables moved into u.bm */ |
| 68017 | +#endif /* local variables moved into u.bp */ |
| 67972 | 68018 | |
| 67973 | 68019 | CHECK_FOR_INTERRUPT; |
| 67974 | 68020 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 67975 | 68021 | assert( pOp->p5<=ArraySize(p->aCounter) ); |
| 67976 | | - u.bm.pC = p->apCsr[pOp->p1]; |
| 67977 | | - if( u.bm.pC==0 ){ |
| 68022 | + u.bp.pC = p->apCsr[pOp->p1]; |
| 68023 | + if( u.bp.pC==0 ){ |
| 67978 | 68024 | break; /* See ticket #2273 */ |
| 67979 | 68025 | } |
| 67980 | | - if( isSorter(u.bm.pC) ){ |
| 67981 | | - assert( pOp->opcode==OP_Next ); |
| 67982 | | - rc = sqlite3VdbeSorterNext(db, u.bm.pC, &u.bm.res); |
| 68026 | + assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 68027 | + if( isSorter(u.bp.pC) ){ |
| 68028 | + assert( pOp->opcode==OP_SorterNext ); |
| 68029 | + rc = sqlite3VdbeSorterNext(db, u.bp.pC, &u.bp.res); |
| 67983 | 68030 | }else{ |
| 67984 | | - u.bm.res = 1; |
| 67985 | | - assert( u.bm.pC->deferredMoveto==0 ); |
| 67986 | | - assert( u.bm.pC->pCursor ); |
| 68031 | + u.bp.res = 1; |
| 68032 | + assert( u.bp.pC->deferredMoveto==0 ); |
| 68033 | + assert( u.bp.pC->pCursor ); |
| 67987 | 68034 | assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 67988 | 68035 | assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 67989 | | - rc = pOp->p4.xAdvance(u.bm.pC->pCursor, &u.bm.res); |
| 68036 | + rc = pOp->p4.xAdvance(u.bp.pC->pCursor, &u.bp.res); |
| 67990 | 68037 | } |
| 67991 | | - u.bm.pC->nullRow = (u8)u.bm.res; |
| 67992 | | - u.bm.pC->cacheStatus = CACHE_STALE; |
| 67993 | | - if( u.bm.res==0 ){ |
| 68038 | + u.bp.pC->nullRow = (u8)u.bp.res; |
| 68039 | + u.bp.pC->cacheStatus = CACHE_STALE; |
| 68040 | + if( u.bp.res==0 ){ |
| 67994 | 68041 | pc = pOp->p2 - 1; |
| 67995 | 68042 | if( pOp->p5 ) p->aCounter[pOp->p5-1]++; |
| 67996 | 68043 | #ifdef SQLITE_TEST |
| 67997 | 68044 | sqlite3_search_count++; |
| 67998 | 68045 | #endif |
| 67999 | 68046 | } |
| 68000 | | - u.bm.pC->rowidIsValid = 0; |
| 68047 | + u.bp.pC->rowidIsValid = 0; |
| 68001 | 68048 | break; |
| 68002 | 68049 | } |
| 68003 | 68050 | |
| 68004 | 68051 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 68005 | 68052 | ** |
| | @@ -68011,38 +68058,44 @@ |
| 68011 | 68058 | ** insert is likely to be an append. |
| 68012 | 68059 | ** |
| 68013 | 68060 | ** This instruction only works for indices. The equivalent instruction |
| 68014 | 68061 | ** for tables is OP_Insert. |
| 68015 | 68062 | */ |
| 68063 | +case OP_SorterInsert: /* in2 */ |
| 68064 | +#ifdef SQLITE_OMIT_MERGE_SORT |
| 68065 | + pOp->opcode = OP_IdxInsert; |
| 68066 | +#endif |
| 68016 | 68067 | case OP_IdxInsert: { /* in2 */ |
| 68017 | | -#if 0 /* local variables moved into u.bn */ |
| 68068 | +#if 0 /* local variables moved into u.bq */ |
| 68018 | 68069 | VdbeCursor *pC; |
| 68019 | 68070 | BtCursor *pCrsr; |
| 68020 | 68071 | int nKey; |
| 68021 | 68072 | const char *zKey; |
| 68022 | | -#endif /* local variables moved into u.bn */ |
| 68073 | +#endif /* local variables moved into u.bq */ |
| 68023 | 68074 | |
| 68024 | 68075 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68025 | | - u.bn.pC = p->apCsr[pOp->p1]; |
| 68026 | | - assert( u.bn.pC!=0 ); |
| 68076 | + u.bq.pC = p->apCsr[pOp->p1]; |
| 68077 | + assert( u.bq.pC!=0 ); |
| 68078 | + assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); |
| 68027 | 68079 | pIn2 = &aMem[pOp->p2]; |
| 68028 | 68080 | 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 ); |
| 68081 | + u.bq.pCrsr = u.bq.pC->pCursor; |
| 68082 | + if( ALWAYS(u.bq.pCrsr!=0) ){ |
| 68083 | + assert( u.bq.pC->isTable==0 ); |
| 68032 | 68084 | rc = ExpandBlob(pIn2); |
| 68033 | 68085 | 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; |
| 68086 | + if( isSorter(u.bq.pC) ){ |
| 68087 | + rc = sqlite3VdbeSorterWrite(db, u.bq.pC, pIn2); |
| 68088 | + }else{ |
| 68089 | + u.bq.nKey = pIn2->n; |
| 68090 | + u.bq.zKey = pIn2->z; |
| 68091 | + rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, |
| 68092 | + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) |
| 68093 | + ); |
| 68094 | + assert( u.bq.pC->deferredMoveto==0 ); |
| 68095 | + u.bq.pC->cacheStatus = CACHE_STALE; |
| 68096 | + } |
| 68044 | 68097 | } |
| 68045 | 68098 | } |
| 68046 | 68099 | break; |
| 68047 | 68100 | } |
| 68048 | 68101 | |
| | @@ -68051,37 +68104,37 @@ |
| 68051 | 68104 | ** The content of P3 registers starting at register P2 form |
| 68052 | 68105 | ** an unpacked index key. This opcode removes that entry from the |
| 68053 | 68106 | ** index opened by cursor P1. |
| 68054 | 68107 | */ |
| 68055 | 68108 | case OP_IdxDelete: { |
| 68056 | | -#if 0 /* local variables moved into u.bo */ |
| 68109 | +#if 0 /* local variables moved into u.br */ |
| 68057 | 68110 | VdbeCursor *pC; |
| 68058 | 68111 | BtCursor *pCrsr; |
| 68059 | 68112 | int res; |
| 68060 | 68113 | UnpackedRecord r; |
| 68061 | | -#endif /* local variables moved into u.bo */ |
| 68114 | +#endif /* local variables moved into u.br */ |
| 68062 | 68115 | |
| 68063 | 68116 | assert( pOp->p3>0 ); |
| 68064 | 68117 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 68065 | 68118 | 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]; |
| 68119 | + u.br.pC = p->apCsr[pOp->p1]; |
| 68120 | + assert( u.br.pC!=0 ); |
| 68121 | + u.br.pCrsr = u.br.pC->pCursor; |
| 68122 | + if( ALWAYS(u.br.pCrsr!=0) ){ |
| 68123 | + u.br.r.pKeyInfo = u.br.pC->pKeyInfo; |
| 68124 | + u.br.r.nField = (u16)pOp->p3; |
| 68125 | + u.br.r.flags = 0; |
| 68126 | + u.br.r.aMem = &aMem[pOp->p2]; |
| 68074 | 68127 | #ifdef SQLITE_DEBUG |
| 68075 | | - { int i; for(i=0; i<u.bo.r.nField; i++) assert( memIsValid(&u.bo.r.aMem[i]) ); } |
| 68128 | + { int i; for(i=0; i<u.br.r.nField; i++) assert( memIsValid(&u.br.r.aMem[i]) ); } |
| 68076 | 68129 | #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); |
| 68130 | + rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &u.br.r, 0, 0, &u.br.res); |
| 68131 | + if( rc==SQLITE_OK && u.br.res==0 ){ |
| 68132 | + rc = sqlite3BtreeDelete(u.br.pCrsr); |
| 68080 | 68133 | } |
| 68081 | | - assert( u.bo.pC->deferredMoveto==0 ); |
| 68082 | | - u.bo.pC->cacheStatus = CACHE_STALE; |
| 68134 | + assert( u.br.pC->deferredMoveto==0 ); |
| 68135 | + u.br.pC->cacheStatus = CACHE_STALE; |
| 68083 | 68136 | } |
| 68084 | 68137 | break; |
| 68085 | 68138 | } |
| 68086 | 68139 | |
| 68087 | 68140 | /* Opcode: IdxRowid P1 P2 * * * |
| | @@ -68091,32 +68144,32 @@ |
| 68091 | 68144 | ** the rowid of the table entry to which this index entry points. |
| 68092 | 68145 | ** |
| 68093 | 68146 | ** See also: Rowid, MakeRecord. |
| 68094 | 68147 | */ |
| 68095 | 68148 | case OP_IdxRowid: { /* out2-prerelease */ |
| 68096 | | -#if 0 /* local variables moved into u.bp */ |
| 68149 | +#if 0 /* local variables moved into u.bs */ |
| 68097 | 68150 | BtCursor *pCrsr; |
| 68098 | 68151 | VdbeCursor *pC; |
| 68099 | 68152 | i64 rowid; |
| 68100 | | -#endif /* local variables moved into u.bp */ |
| 68153 | +#endif /* local variables moved into u.bs */ |
| 68101 | 68154 | |
| 68102 | 68155 | 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; |
| 68156 | + u.bs.pC = p->apCsr[pOp->p1]; |
| 68157 | + assert( u.bs.pC!=0 ); |
| 68158 | + u.bs.pCrsr = u.bs.pC->pCursor; |
| 68106 | 68159 | pOut->flags = MEM_Null; |
| 68107 | | - if( ALWAYS(u.bp.pCrsr!=0) ){ |
| 68108 | | - rc = sqlite3VdbeCursorMoveto(u.bp.pC); |
| 68160 | + if( ALWAYS(u.bs.pCrsr!=0) ){ |
| 68161 | + rc = sqlite3VdbeCursorMoveto(u.bs.pC); |
| 68109 | 68162 | 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); |
| 68163 | + assert( u.bs.pC->deferredMoveto==0 ); |
| 68164 | + assert( u.bs.pC->isTable==0 ); |
| 68165 | + if( !u.bs.pC->nullRow ){ |
| 68166 | + rc = sqlite3VdbeIdxRowid(db, u.bs.pCrsr, &u.bs.rowid); |
| 68114 | 68167 | if( rc!=SQLITE_OK ){ |
| 68115 | 68168 | goto abort_due_to_error; |
| 68116 | 68169 | } |
| 68117 | | - pOut->u.i = u.bp.rowid; |
| 68170 | + pOut->u.i = u.bs.rowid; |
| 68118 | 68171 | pOut->flags = MEM_Int; |
| 68119 | 68172 | } |
| 68120 | 68173 | } |
| 68121 | 68174 | break; |
| 68122 | 68175 | } |
| | @@ -68147,43 +68200,43 @@ |
| 68147 | 68200 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 68148 | 68201 | ** to the comparison. This makes the opcode work like IdxLE. |
| 68149 | 68202 | */ |
| 68150 | 68203 | case OP_IdxLT: /* jump */ |
| 68151 | 68204 | case OP_IdxGE: { /* jump */ |
| 68152 | | -#if 0 /* local variables moved into u.bq */ |
| 68205 | +#if 0 /* local variables moved into u.bt */ |
| 68153 | 68206 | VdbeCursor *pC; |
| 68154 | 68207 | int res; |
| 68155 | 68208 | UnpackedRecord r; |
| 68156 | | -#endif /* local variables moved into u.bq */ |
| 68209 | +#endif /* local variables moved into u.bt */ |
| 68157 | 68210 | |
| 68158 | 68211 | 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 ); |
| 68212 | + u.bt.pC = p->apCsr[pOp->p1]; |
| 68213 | + assert( u.bt.pC!=0 ); |
| 68214 | + assert( u.bt.pC->isOrdered ); |
| 68215 | + if( ALWAYS(u.bt.pC->pCursor!=0) ){ |
| 68216 | + assert( u.bt.pC->deferredMoveto==0 ); |
| 68164 | 68217 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 68165 | 68218 | assert( pOp->p4type==P4_INT32 ); |
| 68166 | | - u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo; |
| 68167 | | - u.bq.r.nField = (u16)pOp->p4.i; |
| 68219 | + u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; |
| 68220 | + u.bt.r.nField = (u16)pOp->p4.i; |
| 68168 | 68221 | if( pOp->p5 ){ |
| 68169 | | - u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
| 68222 | + u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
| 68170 | 68223 | }else{ |
| 68171 | | - u.bq.r.flags = UNPACKED_IGNORE_ROWID; |
| 68224 | + u.bt.r.flags = UNPACKED_IGNORE_ROWID; |
| 68172 | 68225 | } |
| 68173 | | - u.bq.r.aMem = &aMem[pOp->p3]; |
| 68226 | + u.bt.r.aMem = &aMem[pOp->p3]; |
| 68174 | 68227 | #ifdef SQLITE_DEBUG |
| 68175 | | - { int i; for(i=0; i<u.bq.r.nField; i++) assert( memIsValid(&u.bq.r.aMem[i]) ); } |
| 68228 | + { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } |
| 68176 | 68229 | #endif |
| 68177 | | - rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res); |
| 68230 | + rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); |
| 68178 | 68231 | if( pOp->opcode==OP_IdxLT ){ |
| 68179 | | - u.bq.res = -u.bq.res; |
| 68232 | + u.bt.res = -u.bt.res; |
| 68180 | 68233 | }else{ |
| 68181 | 68234 | assert( pOp->opcode==OP_IdxGE ); |
| 68182 | | - u.bq.res++; |
| 68235 | + u.bt.res++; |
| 68183 | 68236 | } |
| 68184 | | - if( u.bq.res>0 ){ |
| 68237 | + if( u.bt.res>0 ){ |
| 68185 | 68238 | pc = pOp->p2 - 1 ; |
| 68186 | 68239 | } |
| 68187 | 68240 | } |
| 68188 | 68241 | break; |
| 68189 | 68242 | } |
| | @@ -68207,43 +68260,43 @@ |
| 68207 | 68260 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 68208 | 68261 | ** |
| 68209 | 68262 | ** See also: Clear |
| 68210 | 68263 | */ |
| 68211 | 68264 | case OP_Destroy: { /* out2-prerelease */ |
| 68212 | | -#if 0 /* local variables moved into u.br */ |
| 68265 | +#if 0 /* local variables moved into u.bu */ |
| 68213 | 68266 | int iMoved; |
| 68214 | 68267 | int iCnt; |
| 68215 | 68268 | Vdbe *pVdbe; |
| 68216 | 68269 | int iDb; |
| 68217 | | -#endif /* local variables moved into u.br */ |
| 68270 | +#endif /* local variables moved into u.bu */ |
| 68218 | 68271 | #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++; |
| 68272 | + u.bu.iCnt = 0; |
| 68273 | + for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ |
| 68274 | + if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ |
| 68275 | + u.bu.iCnt++; |
| 68223 | 68276 | } |
| 68224 | 68277 | } |
| 68225 | 68278 | #else |
| 68226 | | - u.br.iCnt = db->activeVdbeCnt; |
| 68279 | + u.bu.iCnt = db->activeVdbeCnt; |
| 68227 | 68280 | #endif |
| 68228 | 68281 | pOut->flags = MEM_Null; |
| 68229 | | - if( u.br.iCnt>1 ){ |
| 68282 | + if( u.bu.iCnt>1 ){ |
| 68230 | 68283 | rc = SQLITE_LOCKED; |
| 68231 | 68284 | p->errorAction = OE_Abort; |
| 68232 | 68285 | }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); |
| 68286 | + u.bu.iDb = pOp->p3; |
| 68287 | + assert( u.bu.iCnt==1 ); |
| 68288 | + assert( (p->btreeMask & (((yDbMask)1)<<u.bu.iDb))!=0 ); |
| 68289 | + rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); |
| 68237 | 68290 | pOut->flags = MEM_Int; |
| 68238 | | - pOut->u.i = u.br.iMoved; |
| 68291 | + pOut->u.i = u.bu.iMoved; |
| 68239 | 68292 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 68240 | | - if( rc==SQLITE_OK && u.br.iMoved!=0 ){ |
| 68241 | | - sqlite3RootPageMoved(db, u.br.iDb, u.br.iMoved, pOp->p1); |
| 68293 | + if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ |
| 68294 | + sqlite3RootPageMoved(db, u.bu.iDb, u.bu.iMoved, pOp->p1); |
| 68242 | 68295 | /* All OP_Destroy operations occur on the same btree */ |
| 68243 | | - assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.br.iDb+1 ); |
| 68244 | | - resetSchemaOnFault = u.br.iDb+1; |
| 68296 | + assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bu.iDb+1 ); |
| 68297 | + resetSchemaOnFault = u.bu.iDb+1; |
| 68245 | 68298 | } |
| 68246 | 68299 | #endif |
| 68247 | 68300 | } |
| 68248 | 68301 | break; |
| 68249 | 68302 | } |
| | @@ -68265,25 +68318,25 @@ |
| 68265 | 68318 | ** also incremented by the number of rows in the table being cleared. |
| 68266 | 68319 | ** |
| 68267 | 68320 | ** See also: Destroy |
| 68268 | 68321 | */ |
| 68269 | 68322 | case OP_Clear: { |
| 68270 | | -#if 0 /* local variables moved into u.bs */ |
| 68323 | +#if 0 /* local variables moved into u.bv */ |
| 68271 | 68324 | int nChange; |
| 68272 | | -#endif /* local variables moved into u.bs */ |
| 68325 | +#endif /* local variables moved into u.bv */ |
| 68273 | 68326 | |
| 68274 | | - u.bs.nChange = 0; |
| 68327 | + u.bv.nChange = 0; |
| 68275 | 68328 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 68276 | 68329 | rc = sqlite3BtreeClearTable( |
| 68277 | | - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0) |
| 68330 | + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) |
| 68278 | 68331 | ); |
| 68279 | 68332 | if( pOp->p3 ){ |
| 68280 | | - p->nChange += u.bs.nChange; |
| 68333 | + p->nChange += u.bv.nChange; |
| 68281 | 68334 | if( pOp->p3>0 ){ |
| 68282 | 68335 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 68283 | 68336 | memAboutToChange(p, &aMem[pOp->p3]); |
| 68284 | | - aMem[pOp->p3].u.i += u.bs.nChange; |
| 68337 | + aMem[pOp->p3].u.i += u.bv.nChange; |
| 68285 | 68338 | } |
| 68286 | 68339 | } |
| 68287 | 68340 | break; |
| 68288 | 68341 | } |
| 68289 | 68342 | |
| | @@ -68309,29 +68362,29 @@ |
| 68309 | 68362 | ** |
| 68310 | 68363 | ** See documentation on OP_CreateTable for additional information. |
| 68311 | 68364 | */ |
| 68312 | 68365 | case OP_CreateIndex: /* out2-prerelease */ |
| 68313 | 68366 | case OP_CreateTable: { /* out2-prerelease */ |
| 68314 | | -#if 0 /* local variables moved into u.bt */ |
| 68367 | +#if 0 /* local variables moved into u.bw */ |
| 68315 | 68368 | int pgno; |
| 68316 | 68369 | int flags; |
| 68317 | 68370 | Db *pDb; |
| 68318 | | -#endif /* local variables moved into u.bt */ |
| 68371 | +#endif /* local variables moved into u.bw */ |
| 68319 | 68372 | |
| 68320 | | - u.bt.pgno = 0; |
| 68373 | + u.bw.pgno = 0; |
| 68321 | 68374 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 68322 | 68375 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 68323 | | - u.bt.pDb = &db->aDb[pOp->p1]; |
| 68324 | | - assert( u.bt.pDb->pBt!=0 ); |
| 68376 | + u.bw.pDb = &db->aDb[pOp->p1]; |
| 68377 | + assert( u.bw.pDb->pBt!=0 ); |
| 68325 | 68378 | if( pOp->opcode==OP_CreateTable ){ |
| 68326 | | - /* u.bt.flags = BTREE_INTKEY; */ |
| 68327 | | - u.bt.flags = BTREE_INTKEY; |
| 68379 | + /* u.bw.flags = BTREE_INTKEY; */ |
| 68380 | + u.bw.flags = BTREE_INTKEY; |
| 68328 | 68381 | }else{ |
| 68329 | | - u.bt.flags = BTREE_BLOBKEY; |
| 68382 | + u.bw.flags = BTREE_BLOBKEY; |
| 68330 | 68383 | } |
| 68331 | | - rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); |
| 68332 | | - pOut->u.i = u.bt.pgno; |
| 68384 | + rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); |
| 68385 | + pOut->u.i = u.bw.pgno; |
| 68333 | 68386 | break; |
| 68334 | 68387 | } |
| 68335 | 68388 | |
| 68336 | 68389 | /* Opcode: ParseSchema P1 * * P4 * |
| 68337 | 68390 | ** |
| | @@ -68340,48 +68393,48 @@ |
| 68340 | 68393 | ** |
| 68341 | 68394 | ** This opcode invokes the parser to create a new virtual machine, |
| 68342 | 68395 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 68343 | 68396 | */ |
| 68344 | 68397 | case OP_ParseSchema: { |
| 68345 | | -#if 0 /* local variables moved into u.bu */ |
| 68398 | +#if 0 /* local variables moved into u.bx */ |
| 68346 | 68399 | int iDb; |
| 68347 | 68400 | const char *zMaster; |
| 68348 | 68401 | char *zSql; |
| 68349 | 68402 | InitData initData; |
| 68350 | | -#endif /* local variables moved into u.bu */ |
| 68403 | +#endif /* local variables moved into u.bx */ |
| 68351 | 68404 | |
| 68352 | 68405 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 68353 | 68406 | ** on every btree. This is a prerequisite for invoking |
| 68354 | 68407 | ** sqlite3InitCallback(). |
| 68355 | 68408 | */ |
| 68356 | 68409 | #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) ); |
| 68410 | + for(u.bx.iDb=0; u.bx.iDb<db->nDb; u.bx.iDb++){ |
| 68411 | + assert( u.bx.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); |
| 68359 | 68412 | } |
| 68360 | 68413 | #endif |
| 68361 | 68414 | |
| 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) ); |
| 68415 | + u.bx.iDb = pOp->p1; |
| 68416 | + assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); |
| 68417 | + assert( DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ); |
| 68365 | 68418 | /* 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, |
| 68419 | + u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); |
| 68420 | + u.bx.initData.db = db; |
| 68421 | + u.bx.initData.iDb = pOp->p1; |
| 68422 | + u.bx.initData.pzErrMsg = &p->zErrMsg; |
| 68423 | + u.bx.zSql = sqlite3MPrintf(db, |
| 68371 | 68424 | "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 ){ |
| 68425 | + db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); |
| 68426 | + if( u.bx.zSql==0 ){ |
| 68374 | 68427 | rc = SQLITE_NOMEM; |
| 68375 | 68428 | }else{ |
| 68376 | 68429 | assert( db->init.busy==0 ); |
| 68377 | 68430 | db->init.busy = 1; |
| 68378 | | - u.bu.initData.rc = SQLITE_OK; |
| 68431 | + u.bx.initData.rc = SQLITE_OK; |
| 68379 | 68432 | 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); |
| 68433 | + rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); |
| 68434 | + if( rc==SQLITE_OK ) rc = u.bx.initData.rc; |
| 68435 | + sqlite3DbFree(db, u.bx.zSql); |
| 68383 | 68436 | db->init.busy = 0; |
| 68384 | 68437 | } |
| 68385 | 68438 | } |
| 68386 | 68439 | if( rc==SQLITE_NOMEM ){ |
| 68387 | 68440 | goto no_mem; |
| | @@ -68460,45 +68513,45 @@ |
| 68460 | 68513 | ** file, not the main database file. |
| 68461 | 68514 | ** |
| 68462 | 68515 | ** This opcode is used to implement the integrity_check pragma. |
| 68463 | 68516 | */ |
| 68464 | 68517 | case OP_IntegrityCk: { |
| 68465 | | -#if 0 /* local variables moved into u.bv */ |
| 68518 | +#if 0 /* local variables moved into u.by */ |
| 68466 | 68519 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 68467 | 68520 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 68468 | 68521 | int j; /* Loop counter */ |
| 68469 | 68522 | int nErr; /* Number of errors reported */ |
| 68470 | 68523 | char *z; /* Text of the error report */ |
| 68471 | 68524 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 68472 | | -#endif /* local variables moved into u.bv */ |
| 68525 | +#endif /* local variables moved into u.by */ |
| 68473 | 68526 | |
| 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; |
| 68527 | + u.by.nRoot = pOp->p2; |
| 68528 | + assert( u.by.nRoot>0 ); |
| 68529 | + u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); |
| 68530 | + if( u.by.aRoot==0 ) goto no_mem; |
| 68478 | 68531 | 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 ); |
| 68532 | + u.by.pnErr = &aMem[pOp->p3]; |
| 68533 | + assert( (u.by.pnErr->flags & MEM_Int)!=0 ); |
| 68534 | + assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 68482 | 68535 | 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]); |
| 68536 | + for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ |
| 68537 | + u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); |
| 68485 | 68538 | } |
| 68486 | | - u.bv.aRoot[u.bv.j] = 0; |
| 68539 | + u.by.aRoot[u.by.j] = 0; |
| 68487 | 68540 | assert( pOp->p5<db->nDb ); |
| 68488 | 68541 | 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; |
| 68542 | + u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, |
| 68543 | + (int)u.by.pnErr->u.i, &u.by.nErr); |
| 68544 | + sqlite3DbFree(db, u.by.aRoot); |
| 68545 | + u.by.pnErr->u.i -= u.by.nErr; |
| 68493 | 68546 | sqlite3VdbeMemSetNull(pIn1); |
| 68494 | | - if( u.bv.nErr==0 ){ |
| 68495 | | - assert( u.bv.z==0 ); |
| 68496 | | - }else if( u.bv.z==0 ){ |
| 68547 | + if( u.by.nErr==0 ){ |
| 68548 | + assert( u.by.z==0 ); |
| 68549 | + }else if( u.by.z==0 ){ |
| 68497 | 68550 | goto no_mem; |
| 68498 | 68551 | }else{ |
| 68499 | | - sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68552 | + sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); |
| 68500 | 68553 | } |
| 68501 | 68554 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 68502 | 68555 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 68503 | 68556 | break; |
| 68504 | 68557 | } |
| | @@ -68528,24 +68581,24 @@ |
| 68528 | 68581 | ** Extract the smallest value from boolean index P1 and put that value into |
| 68529 | 68582 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 68530 | 68583 | ** unchanged and jump to instruction P2. |
| 68531 | 68584 | */ |
| 68532 | 68585 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 68533 | | -#if 0 /* local variables moved into u.bw */ |
| 68586 | +#if 0 /* local variables moved into u.bz */ |
| 68534 | 68587 | i64 val; |
| 68535 | | -#endif /* local variables moved into u.bw */ |
| 68588 | +#endif /* local variables moved into u.bz */ |
| 68536 | 68589 | CHECK_FOR_INTERRUPT; |
| 68537 | 68590 | pIn1 = &aMem[pOp->p1]; |
| 68538 | 68591 | if( (pIn1->flags & MEM_RowSet)==0 |
| 68539 | | - || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bw.val)==0 |
| 68592 | + || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bz.val)==0 |
| 68540 | 68593 | ){ |
| 68541 | 68594 | /* The boolean index is empty */ |
| 68542 | 68595 | sqlite3VdbeMemSetNull(pIn1); |
| 68543 | 68596 | pc = pOp->p2 - 1; |
| 68544 | 68597 | }else{ |
| 68545 | 68598 | /* A value was pulled from the index */ |
| 68546 | | - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bw.val); |
| 68599 | + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bz.val); |
| 68547 | 68600 | } |
| 68548 | 68601 | break; |
| 68549 | 68602 | } |
| 68550 | 68603 | |
| 68551 | 68604 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| | @@ -68570,18 +68623,18 @@ |
| 68570 | 68623 | ** inserted, there is no need to search to see if the same value was |
| 68571 | 68624 | ** previously inserted as part of set X (only if it was previously |
| 68572 | 68625 | ** inserted as part of some other set). |
| 68573 | 68626 | */ |
| 68574 | 68627 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 68575 | | -#if 0 /* local variables moved into u.bx */ |
| 68628 | +#if 0 /* local variables moved into u.ca */ |
| 68576 | 68629 | int iSet; |
| 68577 | 68630 | int exists; |
| 68578 | | -#endif /* local variables moved into u.bx */ |
| 68631 | +#endif /* local variables moved into u.ca */ |
| 68579 | 68632 | |
| 68580 | 68633 | pIn1 = &aMem[pOp->p1]; |
| 68581 | 68634 | pIn3 = &aMem[pOp->p3]; |
| 68582 | | - u.bx.iSet = pOp->p4.i; |
| 68635 | + u.ca.iSet = pOp->p4.i; |
| 68583 | 68636 | assert( pIn3->flags&MEM_Int ); |
| 68584 | 68637 | |
| 68585 | 68638 | /* If there is anything other than a rowset object in memory cell P1, |
| 68586 | 68639 | ** delete it now and initialize P1 with an empty rowset |
| 68587 | 68640 | */ |
| | @@ -68589,21 +68642,21 @@ |
| 68589 | 68642 | sqlite3VdbeMemSetRowSet(pIn1); |
| 68590 | 68643 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 68591 | 68644 | } |
| 68592 | 68645 | |
| 68593 | 68646 | 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), |
| 68647 | + assert( u.ca.iSet==-1 || u.ca.iSet>=0 ); |
| 68648 | + if( u.ca.iSet ){ |
| 68649 | + u.ca.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 68650 | + (u8)(u.ca.iSet>=0 ? u.ca.iSet & 0xf : 0xff), |
| 68598 | 68651 | pIn3->u.i); |
| 68599 | | - if( u.bx.exists ){ |
| 68652 | + if( u.ca.exists ){ |
| 68600 | 68653 | pc = pOp->p2 - 1; |
| 68601 | 68654 | break; |
| 68602 | 68655 | } |
| 68603 | 68656 | } |
| 68604 | | - if( u.bx.iSet>=0 ){ |
| 68657 | + if( u.ca.iSet>=0 ){ |
| 68605 | 68658 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 68606 | 68659 | } |
| 68607 | 68660 | break; |
| 68608 | 68661 | } |
| 68609 | 68662 | |
| | @@ -68622,25 +68675,25 @@ |
| 68622 | 68675 | ** memory required by the sub-vdbe at runtime. |
| 68623 | 68676 | ** |
| 68624 | 68677 | ** P4 is a pointer to the VM containing the trigger program. |
| 68625 | 68678 | */ |
| 68626 | 68679 | case OP_Program: { /* jump */ |
| 68627 | | -#if 0 /* local variables moved into u.by */ |
| 68680 | +#if 0 /* local variables moved into u.cb */ |
| 68628 | 68681 | int nMem; /* Number of memory registers for sub-program */ |
| 68629 | 68682 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 68630 | 68683 | Mem *pRt; /* Register to allocate runtime space */ |
| 68631 | 68684 | Mem *pMem; /* Used to iterate through memory cells */ |
| 68632 | 68685 | Mem *pEnd; /* Last memory cell in new array */ |
| 68633 | 68686 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 68634 | 68687 | SubProgram *pProgram; /* Sub-program to execute */ |
| 68635 | 68688 | void *t; /* Token identifying trigger */ |
| 68636 | | -#endif /* local variables moved into u.by */ |
| 68689 | +#endif /* local variables moved into u.cb */ |
| 68637 | 68690 | |
| 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 ); |
| 68691 | + u.cb.pProgram = pOp->p4.pProgram; |
| 68692 | + u.cb.pRt = &aMem[pOp->p3]; |
| 68693 | + assert( memIsValid(u.cb.pRt) ); |
| 68694 | + assert( u.cb.pProgram->nOp>0 ); |
| 68642 | 68695 | |
| 68643 | 68696 | /* If the p5 flag is clear, then recursive invocation of triggers is |
| 68644 | 68697 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 68645 | 68698 | ** is really a trigger, not a foreign key action, and the flag set |
| 68646 | 68699 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| | @@ -68650,79 +68703,79 @@ |
| 68650 | 68703 | ** SubProgram (if the trigger may be executed with more than one different |
| 68651 | 68704 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 68652 | 68705 | ** single trigger all have the same value for the SubProgram.token |
| 68653 | 68706 | ** variable. */ |
| 68654 | 68707 | 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; |
| 68708 | + u.cb.t = u.cb.pProgram->token; |
| 68709 | + for(u.cb.pFrame=p->pFrame; u.cb.pFrame && u.cb.pFrame->token!=u.cb.t; u.cb.pFrame=u.cb.pFrame->pParent); |
| 68710 | + if( u.cb.pFrame ) break; |
| 68658 | 68711 | } |
| 68659 | 68712 | |
| 68660 | 68713 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 68661 | 68714 | rc = SQLITE_ERROR; |
| 68662 | 68715 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 68663 | 68716 | break; |
| 68664 | 68717 | } |
| 68665 | 68718 | |
| 68666 | | - /* Register u.by.pRt is used to store the memory required to save the state |
| 68719 | + /* Register u.cb.pRt is used to store the memory required to save the state |
| 68667 | 68720 | ** 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 |
| 68721 | + ** the trigger program. If this trigger has been fired before, then u.cb.pRt |
| 68669 | 68722 | ** is already allocated. Otherwise, it must be initialized. */ |
| 68670 | | - if( (u.by.pRt->flags&MEM_Frame)==0 ){ |
| 68723 | + if( (u.cb.pRt->flags&MEM_Frame)==0 ){ |
| 68671 | 68724 | /* SubProgram.nMem is set to the number of memory cells used by the |
| 68672 | 68725 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 68673 | 68726 | ** cell is required for each cursor used by the program. Set local |
| 68674 | | - ** variable u.by.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68727 | + ** variable u.cb.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 68675 | 68728 | */ |
| 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 ){ |
| 68729 | + u.cb.nMem = u.cb.pProgram->nMem + u.cb.pProgram->nCsr; |
| 68730 | + u.cb.nByte = ROUND8(sizeof(VdbeFrame)) |
| 68731 | + + u.cb.nMem * sizeof(Mem) |
| 68732 | + + u.cb.pProgram->nCsr * sizeof(VdbeCursor *); |
| 68733 | + u.cb.pFrame = sqlite3DbMallocZero(db, u.cb.nByte); |
| 68734 | + if( !u.cb.pFrame ){ |
| 68682 | 68735 | goto no_mem; |
| 68683 | 68736 | } |
| 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; |
| 68737 | + sqlite3VdbeMemRelease(u.cb.pRt); |
| 68738 | + u.cb.pRt->flags = MEM_Frame; |
| 68739 | + u.cb.pRt->u.pFrame = u.cb.pFrame; |
| 68740 | + |
| 68741 | + u.cb.pFrame->v = p; |
| 68742 | + u.cb.pFrame->nChildMem = u.cb.nMem; |
| 68743 | + u.cb.pFrame->nChildCsr = u.cb.pProgram->nCsr; |
| 68744 | + u.cb.pFrame->pc = pc; |
| 68745 | + u.cb.pFrame->aMem = p->aMem; |
| 68746 | + u.cb.pFrame->nMem = p->nMem; |
| 68747 | + u.cb.pFrame->apCsr = p->apCsr; |
| 68748 | + u.cb.pFrame->nCursor = p->nCursor; |
| 68749 | + u.cb.pFrame->aOp = p->aOp; |
| 68750 | + u.cb.pFrame->nOp = p->nOp; |
| 68751 | + u.cb.pFrame->token = u.cb.pProgram->token; |
| 68752 | + |
| 68753 | + u.cb.pEnd = &VdbeFrameMem(u.cb.pFrame)[u.cb.pFrame->nChildMem]; |
| 68754 | + for(u.cb.pMem=VdbeFrameMem(u.cb.pFrame); u.cb.pMem!=u.cb.pEnd; u.cb.pMem++){ |
| 68755 | + u.cb.pMem->flags = MEM_Null; |
| 68756 | + u.cb.pMem->db = db; |
| 68704 | 68757 | } |
| 68705 | 68758 | }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 ); |
| 68759 | + u.cb.pFrame = u.cb.pRt->u.pFrame; |
| 68760 | + assert( u.cb.pProgram->nMem+u.cb.pProgram->nCsr==u.cb.pFrame->nChildMem ); |
| 68761 | + assert( u.cb.pProgram->nCsr==u.cb.pFrame->nChildCsr ); |
| 68762 | + assert( pc==u.cb.pFrame->pc ); |
| 68710 | 68763 | } |
| 68711 | 68764 | |
| 68712 | 68765 | p->nFrame++; |
| 68713 | | - u.by.pFrame->pParent = p->pFrame; |
| 68714 | | - u.by.pFrame->lastRowid = lastRowid; |
| 68715 | | - u.by.pFrame->nChange = p->nChange; |
| 68766 | + u.cb.pFrame->pParent = p->pFrame; |
| 68767 | + u.cb.pFrame->lastRowid = lastRowid; |
| 68768 | + u.cb.pFrame->nChange = p->nChange; |
| 68716 | 68769 | 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; |
| 68770 | + p->pFrame = u.cb.pFrame; |
| 68771 | + p->aMem = aMem = &VdbeFrameMem(u.cb.pFrame)[-1]; |
| 68772 | + p->nMem = u.cb.pFrame->nChildMem; |
| 68773 | + p->nCursor = (u16)u.cb.pFrame->nChildCsr; |
| 68721 | 68774 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 68722 | | - p->aOp = aOp = u.by.pProgram->aOp; |
| 68723 | | - p->nOp = u.by.pProgram->nOp; |
| 68775 | + p->aOp = aOp = u.cb.pProgram->aOp; |
| 68776 | + p->nOp = u.cb.pProgram->nOp; |
| 68724 | 68777 | pc = -1; |
| 68725 | 68778 | |
| 68726 | 68779 | break; |
| 68727 | 68780 | } |
| 68728 | 68781 | |
| | @@ -68737,17 +68790,17 @@ |
| 68737 | 68790 | ** The address of the cell in the parent frame is determined by adding |
| 68738 | 68791 | ** the value of the P1 argument to the value of the P1 argument to the |
| 68739 | 68792 | ** calling OP_Program instruction. |
| 68740 | 68793 | */ |
| 68741 | 68794 | case OP_Param: { /* out2-prerelease */ |
| 68742 | | -#if 0 /* local variables moved into u.bz */ |
| 68795 | +#if 0 /* local variables moved into u.cc */ |
| 68743 | 68796 | VdbeFrame *pFrame; |
| 68744 | 68797 | 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); |
| 68798 | +#endif /* local variables moved into u.cc */ |
| 68799 | + u.cc.pFrame = p->pFrame; |
| 68800 | + u.cc.pIn = &u.cc.pFrame->aMem[pOp->p1 + u.cc.pFrame->aOp[u.cc.pFrame->pc].p1]; |
| 68801 | + sqlite3VdbeMemShallowCopy(pOut, u.cc.pIn, MEM_Ephem); |
| 68749 | 68802 | break; |
| 68750 | 68803 | } |
| 68751 | 68804 | |
| 68752 | 68805 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 68753 | 68806 | |
| | @@ -68799,26 +68852,26 @@ |
| 68799 | 68852 | ** |
| 68800 | 68853 | ** This instruction throws an error if the memory cell is not initially |
| 68801 | 68854 | ** an integer. |
| 68802 | 68855 | */ |
| 68803 | 68856 | case OP_MemMax: { /* in2 */ |
| 68804 | | -#if 0 /* local variables moved into u.ca */ |
| 68857 | +#if 0 /* local variables moved into u.cd */ |
| 68805 | 68858 | Mem *pIn1; |
| 68806 | 68859 | VdbeFrame *pFrame; |
| 68807 | | -#endif /* local variables moved into u.ca */ |
| 68860 | +#endif /* local variables moved into u.cd */ |
| 68808 | 68861 | 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]; |
| 68862 | + for(u.cd.pFrame=p->pFrame; u.cd.pFrame->pParent; u.cd.pFrame=u.cd.pFrame->pParent); |
| 68863 | + u.cd.pIn1 = &u.cd.pFrame->aMem[pOp->p1]; |
| 68811 | 68864 | }else{ |
| 68812 | | - u.ca.pIn1 = &aMem[pOp->p1]; |
| 68865 | + u.cd.pIn1 = &aMem[pOp->p1]; |
| 68813 | 68866 | } |
| 68814 | | - assert( memIsValid(u.ca.pIn1) ); |
| 68815 | | - sqlite3VdbeMemIntegerify(u.ca.pIn1); |
| 68867 | + assert( memIsValid(u.cd.pIn1) ); |
| 68868 | + sqlite3VdbeMemIntegerify(u.cd.pIn1); |
| 68816 | 68869 | pIn2 = &aMem[pOp->p2]; |
| 68817 | 68870 | sqlite3VdbeMemIntegerify(pIn2); |
| 68818 | | - if( u.ca.pIn1->u.i<pIn2->u.i){ |
| 68819 | | - u.ca.pIn1->u.i = pIn2->u.i; |
| 68871 | + if( u.cd.pIn1->u.i<pIn2->u.i){ |
| 68872 | + u.cd.pIn1->u.i = pIn2->u.i; |
| 68820 | 68873 | } |
| 68821 | 68874 | break; |
| 68822 | 68875 | } |
| 68823 | 68876 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 68824 | 68877 | |
| | @@ -68881,54 +68934,54 @@ |
| 68881 | 68934 | ** |
| 68882 | 68935 | ** The P5 arguments are taken from register P2 and its |
| 68883 | 68936 | ** successors. |
| 68884 | 68937 | */ |
| 68885 | 68938 | case OP_AggStep: { |
| 68886 | | -#if 0 /* local variables moved into u.cb */ |
| 68939 | +#if 0 /* local variables moved into u.ce */ |
| 68887 | 68940 | int n; |
| 68888 | 68941 | int i; |
| 68889 | 68942 | Mem *pMem; |
| 68890 | 68943 | Mem *pRec; |
| 68891 | 68944 | sqlite3_context ctx; |
| 68892 | 68945 | 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; |
| 68946 | +#endif /* local variables moved into u.ce */ |
| 68947 | + |
| 68948 | + u.ce.n = pOp->p5; |
| 68949 | + assert( u.ce.n>=0 ); |
| 68950 | + u.ce.pRec = &aMem[pOp->p2]; |
| 68951 | + u.ce.apVal = p->apArg; |
| 68952 | + assert( u.ce.apVal || u.ce.n==0 ); |
| 68953 | + for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ |
| 68954 | + assert( memIsValid(u.ce.pRec) ); |
| 68955 | + u.ce.apVal[u.ce.i] = u.ce.pRec; |
| 68956 | + memAboutToChange(p, u.ce.pRec); |
| 68957 | + sqlite3VdbeMemStoreType(u.ce.pRec); |
| 68958 | + } |
| 68959 | + u.ce.ctx.pFunc = pOp->p4.pFunc; |
| 68907 | 68960 | 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 ){ |
| 68961 | + u.ce.ctx.pMem = u.ce.pMem = &aMem[pOp->p3]; |
| 68962 | + u.ce.pMem->n++; |
| 68963 | + u.ce.ctx.s.flags = MEM_Null; |
| 68964 | + u.ce.ctx.s.z = 0; |
| 68965 | + u.ce.ctx.s.zMalloc = 0; |
| 68966 | + u.ce.ctx.s.xDel = 0; |
| 68967 | + u.ce.ctx.s.db = db; |
| 68968 | + u.ce.ctx.isError = 0; |
| 68969 | + u.ce.ctx.pColl = 0; |
| 68970 | + if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ |
| 68918 | 68971 | assert( pOp>p->aOp ); |
| 68919 | 68972 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 68920 | 68973 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 68921 | | - u.cb.ctx.pColl = pOp[-1].p4.pColl; |
| 68974 | + u.ce.ctx.pColl = pOp[-1].p4.pColl; |
| 68922 | 68975 | } |
| 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; |
| 68976 | + (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); /* IMP: R-24505-23230 */ |
| 68977 | + if( u.ce.ctx.isError ){ |
| 68978 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); |
| 68979 | + rc = u.ce.ctx.isError; |
| 68927 | 68980 | } |
| 68928 | 68981 | |
| 68929 | | - sqlite3VdbeMemRelease(&u.cb.ctx.s); |
| 68982 | + sqlite3VdbeMemRelease(&u.ce.ctx.s); |
| 68930 | 68983 | |
| 68931 | 68984 | break; |
| 68932 | 68985 | } |
| 68933 | 68986 | |
| 68934 | 68987 | /* Opcode: AggFinal P1 P2 * P4 * |
| | @@ -68942,23 +68995,23 @@ |
| 68942 | 68995 | ** functions that can take varying numbers of arguments. The |
| 68943 | 68996 | ** P4 argument is only needed for the degenerate case where |
| 68944 | 68997 | ** the step function was not previously called. |
| 68945 | 68998 | */ |
| 68946 | 68999 | case OP_AggFinal: { |
| 68947 | | -#if 0 /* local variables moved into u.cc */ |
| 69000 | +#if 0 /* local variables moved into u.cf */ |
| 68948 | 69001 | Mem *pMem; |
| 68949 | | -#endif /* local variables moved into u.cc */ |
| 69002 | +#endif /* local variables moved into u.cf */ |
| 68950 | 69003 | 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); |
| 69004 | + u.cf.pMem = &aMem[pOp->p1]; |
| 69005 | + assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 69006 | + rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); |
| 68954 | 69007 | if( rc ){ |
| 68955 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cc.pMem)); |
| 69008 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); |
| 68956 | 69009 | } |
| 68957 | | - sqlite3VdbeChangeEncoding(u.cc.pMem, encoding); |
| 68958 | | - UPDATE_MAX_BLOBSIZE(u.cc.pMem); |
| 68959 | | - if( sqlite3VdbeMemTooBig(u.cc.pMem) ){ |
| 69010 | + sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); |
| 69011 | + UPDATE_MAX_BLOBSIZE(u.cf.pMem); |
| 69012 | + if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ |
| 68960 | 69013 | goto too_big; |
| 68961 | 69014 | } |
| 68962 | 69015 | break; |
| 68963 | 69016 | } |
| 68964 | 69017 | |
| | @@ -68973,29 +69026,29 @@ |
| 68973 | 69026 | ** in the WAL that have been checkpointed after the checkpoint |
| 68974 | 69027 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 68975 | 69028 | ** mem[P3+2] are initialized to -1. |
| 68976 | 69029 | */ |
| 68977 | 69030 | case OP_Checkpoint: { |
| 68978 | | -#if 0 /* local variables moved into u.cd */ |
| 69031 | +#if 0 /* local variables moved into u.cg */ |
| 68979 | 69032 | int i; /* Loop counter */ |
| 68980 | 69033 | int aRes[3]; /* Results */ |
| 68981 | 69034 | Mem *pMem; /* Write results here */ |
| 68982 | | -#endif /* local variables moved into u.cd */ |
| 69035 | +#endif /* local variables moved into u.cg */ |
| 68983 | 69036 | |
| 68984 | | - u.cd.aRes[0] = 0; |
| 68985 | | - u.cd.aRes[1] = u.cd.aRes[2] = -1; |
| 69037 | + u.cg.aRes[0] = 0; |
| 69038 | + u.cg.aRes[1] = u.cg.aRes[2] = -1; |
| 68986 | 69039 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 68987 | 69040 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 68988 | 69041 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 68989 | 69042 | ); |
| 68990 | | - rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cd.aRes[1], &u.cd.aRes[2]); |
| 69043 | + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cg.aRes[1], &u.cg.aRes[2]); |
| 68991 | 69044 | if( rc==SQLITE_BUSY ){ |
| 68992 | 69045 | rc = SQLITE_OK; |
| 68993 | | - u.cd.aRes[0] = 1; |
| 69046 | + u.cg.aRes[0] = 1; |
| 68994 | 69047 | } |
| 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]); |
| 69048 | + for(u.cg.i=0, u.cg.pMem = &aMem[pOp->p3]; u.cg.i<3; u.cg.i++, u.cg.pMem++){ |
| 69049 | + sqlite3VdbeMemSetInt64(u.cg.pMem, (i64)u.cg.aRes[u.cg.i]); |
| 68997 | 69050 | } |
| 68998 | 69051 | break; |
| 68999 | 69052 | }; |
| 69000 | 69053 | #endif |
| 69001 | 69054 | |
| | @@ -69010,95 +69063,95 @@ |
| 69010 | 69063 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 69011 | 69064 | ** |
| 69012 | 69065 | ** Write a string containing the final journal-mode to register P2. |
| 69013 | 69066 | */ |
| 69014 | 69067 | case OP_JournalMode: { /* out2-prerelease */ |
| 69015 | | -#if 0 /* local variables moved into u.ce */ |
| 69068 | +#if 0 /* local variables moved into u.ch */ |
| 69016 | 69069 | Btree *pBt; /* Btree to change journal mode of */ |
| 69017 | 69070 | Pager *pPager; /* Pager associated with pBt */ |
| 69018 | 69071 | int eNew; /* New journal mode */ |
| 69019 | 69072 | int eOld; /* The old journal mode */ |
| 69020 | 69073 | 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 |
| 69074 | +#endif /* local variables moved into u.ch */ |
| 69075 | + |
| 69076 | + u.ch.eNew = pOp->p3; |
| 69077 | + assert( u.ch.eNew==PAGER_JOURNALMODE_DELETE |
| 69078 | + || u.ch.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 69079 | + || u.ch.eNew==PAGER_JOURNALMODE_PERSIST |
| 69080 | + || u.ch.eNew==PAGER_JOURNALMODE_OFF |
| 69081 | + || u.ch.eNew==PAGER_JOURNALMODE_MEMORY |
| 69082 | + || u.ch.eNew==PAGER_JOURNALMODE_WAL |
| 69083 | + || u.ch.eNew==PAGER_JOURNALMODE_QUERY |
| 69031 | 69084 | ); |
| 69032 | 69085 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69033 | 69086 | |
| 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; |
| 69087 | + u.ch.pBt = db->aDb[pOp->p1].pBt; |
| 69088 | + u.ch.pPager = sqlite3BtreePager(u.ch.pBt); |
| 69089 | + u.ch.eOld = sqlite3PagerGetJournalMode(u.ch.pPager); |
| 69090 | + if( u.ch.eNew==PAGER_JOURNALMODE_QUERY ) u.ch.eNew = u.ch.eOld; |
| 69091 | + if( !sqlite3PagerOkToChangeJournalMode(u.ch.pPager) ) u.ch.eNew = u.ch.eOld; |
| 69039 | 69092 | |
| 69040 | 69093 | #ifndef SQLITE_OMIT_WAL |
| 69041 | | - u.ce.zFilename = sqlite3PagerFilename(u.ce.pPager); |
| 69094 | + u.ch.zFilename = sqlite3PagerFilename(u.ch.pPager); |
| 69042 | 69095 | |
| 69043 | 69096 | /* Do not allow a transition to journal_mode=WAL for a database |
| 69044 | 69097 | ** in temporary storage or if the VFS does not support shared memory |
| 69045 | 69098 | */ |
| 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 */ |
| 69099 | + if( u.ch.eNew==PAGER_JOURNALMODE_WAL |
| 69100 | + && (u.ch.zFilename[0]==0 /* Temp file */ |
| 69101 | + || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */ |
| 69049 | 69102 | ){ |
| 69050 | | - u.ce.eNew = u.ce.eOld; |
| 69103 | + u.ch.eNew = u.ch.eOld; |
| 69051 | 69104 | } |
| 69052 | 69105 | |
| 69053 | | - if( (u.ce.eNew!=u.ce.eOld) |
| 69054 | | - && (u.ce.eOld==PAGER_JOURNALMODE_WAL || u.ce.eNew==PAGER_JOURNALMODE_WAL) |
| 69106 | + if( (u.ch.eNew!=u.ch.eOld) |
| 69107 | + && (u.ch.eOld==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_WAL) |
| 69055 | 69108 | ){ |
| 69056 | 69109 | if( !db->autoCommit || db->activeVdbeCnt>1 ){ |
| 69057 | 69110 | rc = SQLITE_ERROR; |
| 69058 | 69111 | sqlite3SetString(&p->zErrMsg, db, |
| 69059 | 69112 | "cannot change %s wal mode from within a transaction", |
| 69060 | | - (u.ce.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69113 | + (u.ch.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 69061 | 69114 | ); |
| 69062 | 69115 | break; |
| 69063 | 69116 | }else{ |
| 69064 | 69117 | |
| 69065 | | - if( u.ce.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69118 | + if( u.ch.eOld==PAGER_JOURNALMODE_WAL ){ |
| 69066 | 69119 | /* If leaving WAL mode, close the log file. If successful, the call |
| 69067 | 69120 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 69068 | 69121 | ** file. An EXCLUSIVE lock may still be held on the database file |
| 69069 | 69122 | ** after a successful return. |
| 69070 | 69123 | */ |
| 69071 | | - rc = sqlite3PagerCloseWal(u.ce.pPager); |
| 69124 | + rc = sqlite3PagerCloseWal(u.ch.pPager); |
| 69072 | 69125 | if( rc==SQLITE_OK ){ |
| 69073 | | - sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); |
| 69126 | + sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); |
| 69074 | 69127 | } |
| 69075 | | - }else if( u.ce.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69128 | + }else if( u.ch.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 69076 | 69129 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 69077 | 69130 | ** as an intermediate */ |
| 69078 | | - sqlite3PagerSetJournalMode(u.ce.pPager, PAGER_JOURNALMODE_OFF); |
| 69131 | + sqlite3PagerSetJournalMode(u.ch.pPager, PAGER_JOURNALMODE_OFF); |
| 69079 | 69132 | } |
| 69080 | 69133 | |
| 69081 | 69134 | /* Open a transaction on the database file. Regardless of the journal |
| 69082 | 69135 | ** mode, this transaction always uses a rollback journal. |
| 69083 | 69136 | */ |
| 69084 | | - assert( sqlite3BtreeIsInTrans(u.ce.pBt)==0 ); |
| 69137 | + assert( sqlite3BtreeIsInTrans(u.ch.pBt)==0 ); |
| 69085 | 69138 | if( rc==SQLITE_OK ){ |
| 69086 | | - rc = sqlite3BtreeSetVersion(u.ce.pBt, (u.ce.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69139 | + rc = sqlite3BtreeSetVersion(u.ch.pBt, (u.ch.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 69087 | 69140 | } |
| 69088 | 69141 | } |
| 69089 | 69142 | } |
| 69090 | 69143 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 69091 | 69144 | |
| 69092 | 69145 | if( rc ){ |
| 69093 | | - u.ce.eNew = u.ce.eOld; |
| 69146 | + u.ch.eNew = u.ch.eOld; |
| 69094 | 69147 | } |
| 69095 | | - u.ce.eNew = sqlite3PagerSetJournalMode(u.ce.pPager, u.ce.eNew); |
| 69148 | + u.ch.eNew = sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); |
| 69096 | 69149 | |
| 69097 | 69150 | pOut = &aMem[pOp->p2]; |
| 69098 | 69151 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 69099 | | - pOut->z = (char *)sqlite3JournalModename(u.ce.eNew); |
| 69152 | + pOut->z = (char *)sqlite3JournalModename(u.ch.eNew); |
| 69100 | 69153 | pOut->n = sqlite3Strlen30(pOut->z); |
| 69101 | 69154 | pOut->enc = SQLITE_UTF8; |
| 69102 | 69155 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 69103 | 69156 | break; |
| 69104 | 69157 | }; |
| | @@ -69123,18 +69176,18 @@ |
| 69123 | 69176 | ** Perform a single step of the incremental vacuum procedure on |
| 69124 | 69177 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 69125 | 69178 | ** P2. Otherwise, fall through to the next instruction. |
| 69126 | 69179 | */ |
| 69127 | 69180 | case OP_IncrVacuum: { /* jump */ |
| 69128 | | -#if 0 /* local variables moved into u.cf */ |
| 69181 | +#if 0 /* local variables moved into u.ci */ |
| 69129 | 69182 | Btree *pBt; |
| 69130 | | -#endif /* local variables moved into u.cf */ |
| 69183 | +#endif /* local variables moved into u.ci */ |
| 69131 | 69184 | |
| 69132 | 69185 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69133 | 69186 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69134 | | - u.cf.pBt = db->aDb[pOp->p1].pBt; |
| 69135 | | - rc = sqlite3BtreeIncrVacuum(u.cf.pBt); |
| 69187 | + u.ci.pBt = db->aDb[pOp->p1].pBt; |
| 69188 | + rc = sqlite3BtreeIncrVacuum(u.ci.pBt); |
| 69136 | 69189 | if( rc==SQLITE_DONE ){ |
| 69137 | 69190 | pc = pOp->p2 - 1; |
| 69138 | 69191 | rc = SQLITE_OK; |
| 69139 | 69192 | } |
| 69140 | 69193 | break; |
| | @@ -69200,16 +69253,16 @@ |
| 69200 | 69253 | ** Also, whether or not P4 is set, check that this is not being called from |
| 69201 | 69254 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 69202 | 69255 | ** code will be set to SQLITE_LOCKED. |
| 69203 | 69256 | */ |
| 69204 | 69257 | case OP_VBegin: { |
| 69205 | | -#if 0 /* local variables moved into u.cg */ |
| 69258 | +#if 0 /* local variables moved into u.cj */ |
| 69206 | 69259 | 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); |
| 69260 | +#endif /* local variables moved into u.cj */ |
| 69261 | + u.cj.pVTab = pOp->p4.pVtab; |
| 69262 | + rc = sqlite3VtabBegin(db, u.cj.pVTab); |
| 69263 | + if( u.cj.pVTab ) importVtabErrMsg(p, u.cj.pVTab->pVtab); |
| 69211 | 69264 | break; |
| 69212 | 69265 | } |
| 69213 | 69266 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69214 | 69267 | |
| 69215 | 69268 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -69244,36 +69297,36 @@ |
| 69244 | 69297 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69245 | 69298 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 69246 | 69299 | ** table and stores that cursor in P1. |
| 69247 | 69300 | */ |
| 69248 | 69301 | case OP_VOpen: { |
| 69249 | | -#if 0 /* local variables moved into u.ch */ |
| 69302 | +#if 0 /* local variables moved into u.ck */ |
| 69250 | 69303 | VdbeCursor *pCur; |
| 69251 | 69304 | sqlite3_vtab_cursor *pVtabCursor; |
| 69252 | 69305 | sqlite3_vtab *pVtab; |
| 69253 | 69306 | 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); |
| 69307 | +#endif /* local variables moved into u.ck */ |
| 69308 | + |
| 69309 | + u.ck.pCur = 0; |
| 69310 | + u.ck.pVtabCursor = 0; |
| 69311 | + u.ck.pVtab = pOp->p4.pVtab->pVtab; |
| 69312 | + u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; |
| 69313 | + assert(u.ck.pVtab && u.ck.pModule); |
| 69314 | + rc = u.ck.pModule->xOpen(u.ck.pVtab, &u.ck.pVtabCursor); |
| 69315 | + importVtabErrMsg(p, u.ck.pVtab); |
| 69263 | 69316 | if( SQLITE_OK==rc ){ |
| 69264 | 69317 | /* Initialize sqlite3_vtab_cursor base class */ |
| 69265 | | - u.ch.pVtabCursor->pVtab = u.ch.pVtab; |
| 69318 | + u.ck.pVtabCursor->pVtab = u.ck.pVtab; |
| 69266 | 69319 | |
| 69267 | 69320 | /* 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; |
| 69321 | + u.ck.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 69322 | + if( u.ck.pCur ){ |
| 69323 | + u.ck.pCur->pVtabCursor = u.ck.pVtabCursor; |
| 69324 | + u.ck.pCur->pModule = u.ck.pVtabCursor->pVtab->pModule; |
| 69272 | 69325 | }else{ |
| 69273 | 69326 | db->mallocFailed = 1; |
| 69274 | | - u.ch.pModule->xClose(u.ch.pVtabCursor); |
| 69327 | + u.ck.pModule->xClose(u.ck.pVtabCursor); |
| 69275 | 69328 | } |
| 69276 | 69329 | } |
| 69277 | 69330 | break; |
| 69278 | 69331 | } |
| 69279 | 69332 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -69296,11 +69349,11 @@ |
| 69296 | 69349 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 69297 | 69350 | ** |
| 69298 | 69351 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 69299 | 69352 | */ |
| 69300 | 69353 | case OP_VFilter: { /* jump */ |
| 69301 | | -#if 0 /* local variables moved into u.ci */ |
| 69354 | +#if 0 /* local variables moved into u.cl */ |
| 69302 | 69355 | int nArg; |
| 69303 | 69356 | int iQuery; |
| 69304 | 69357 | const sqlite3_module *pModule; |
| 69305 | 69358 | Mem *pQuery; |
| 69306 | 69359 | Mem *pArgc; |
| | @@ -69308,49 +69361,49 @@ |
| 69308 | 69361 | sqlite3_vtab *pVtab; |
| 69309 | 69362 | VdbeCursor *pCur; |
| 69310 | 69363 | int res; |
| 69311 | 69364 | int i; |
| 69312 | 69365 | 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; |
| 69366 | +#endif /* local variables moved into u.cl */ |
| 69367 | + |
| 69368 | + u.cl.pQuery = &aMem[pOp->p3]; |
| 69369 | + u.cl.pArgc = &u.cl.pQuery[1]; |
| 69370 | + u.cl.pCur = p->apCsr[pOp->p1]; |
| 69371 | + assert( memIsValid(u.cl.pQuery) ); |
| 69372 | + REGISTER_TRACE(pOp->p3, u.cl.pQuery); |
| 69373 | + assert( u.cl.pCur->pVtabCursor ); |
| 69374 | + u.cl.pVtabCursor = u.cl.pCur->pVtabCursor; |
| 69375 | + u.cl.pVtab = u.cl.pVtabCursor->pVtab; |
| 69376 | + u.cl.pModule = u.cl.pVtab->pModule; |
| 69324 | 69377 | |
| 69325 | 69378 | /* 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; |
| 69379 | + assert( (u.cl.pQuery->flags&MEM_Int)!=0 && u.cl.pArgc->flags==MEM_Int ); |
| 69380 | + u.cl.nArg = (int)u.cl.pArgc->u.i; |
| 69381 | + u.cl.iQuery = (int)u.cl.pQuery->u.i; |
| 69329 | 69382 | |
| 69330 | 69383 | /* Invoke the xFilter method */ |
| 69331 | 69384 | { |
| 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]); |
| 69385 | + u.cl.res = 0; |
| 69386 | + u.cl.apArg = p->apArg; |
| 69387 | + for(u.cl.i = 0; u.cl.i<u.cl.nArg; u.cl.i++){ |
| 69388 | + u.cl.apArg[u.cl.i] = &u.cl.pArgc[u.cl.i+1]; |
| 69389 | + sqlite3VdbeMemStoreType(u.cl.apArg[u.cl.i]); |
| 69337 | 69390 | } |
| 69338 | 69391 | |
| 69339 | 69392 | p->inVtabMethod = 1; |
| 69340 | | - rc = u.ci.pModule->xFilter(u.ci.pVtabCursor, u.ci.iQuery, pOp->p4.z, u.ci.nArg, u.ci.apArg); |
| 69393 | + rc = u.cl.pModule->xFilter(u.cl.pVtabCursor, u.cl.iQuery, pOp->p4.z, u.cl.nArg, u.cl.apArg); |
| 69341 | 69394 | p->inVtabMethod = 0; |
| 69342 | | - importVtabErrMsg(p, u.ci.pVtab); |
| 69395 | + importVtabErrMsg(p, u.cl.pVtab); |
| 69343 | 69396 | if( rc==SQLITE_OK ){ |
| 69344 | | - u.ci.res = u.ci.pModule->xEof(u.ci.pVtabCursor); |
| 69397 | + u.cl.res = u.cl.pModule->xEof(u.cl.pVtabCursor); |
| 69345 | 69398 | } |
| 69346 | 69399 | |
| 69347 | | - if( u.ci.res ){ |
| 69400 | + if( u.cl.res ){ |
| 69348 | 69401 | pc = pOp->p2 - 1; |
| 69349 | 69402 | } |
| 69350 | 69403 | } |
| 69351 | | - u.ci.pCur->nullRow = 0; |
| 69404 | + u.cl.pCur->nullRow = 0; |
| 69352 | 69405 | |
| 69353 | 69406 | break; |
| 69354 | 69407 | } |
| 69355 | 69408 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 69356 | 69409 | |
| | @@ -69360,55 +69413,55 @@ |
| 69360 | 69413 | ** Store the value of the P2-th column of |
| 69361 | 69414 | ** the row of the virtual-table that the |
| 69362 | 69415 | ** P1 cursor is pointing to into register P3. |
| 69363 | 69416 | */ |
| 69364 | 69417 | case OP_VColumn: { |
| 69365 | | -#if 0 /* local variables moved into u.cj */ |
| 69418 | +#if 0 /* local variables moved into u.cm */ |
| 69366 | 69419 | sqlite3_vtab *pVtab; |
| 69367 | 69420 | const sqlite3_module *pModule; |
| 69368 | 69421 | Mem *pDest; |
| 69369 | 69422 | sqlite3_context sContext; |
| 69370 | | -#endif /* local variables moved into u.cj */ |
| 69423 | +#endif /* local variables moved into u.cm */ |
| 69371 | 69424 | |
| 69372 | 69425 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 69373 | 69426 | assert( pCur->pVtabCursor ); |
| 69374 | 69427 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 69375 | | - u.cj.pDest = &aMem[pOp->p3]; |
| 69376 | | - memAboutToChange(p, u.cj.pDest); |
| 69428 | + u.cm.pDest = &aMem[pOp->p3]; |
| 69429 | + memAboutToChange(p, u.cm.pDest); |
| 69377 | 69430 | if( pCur->nullRow ){ |
| 69378 | | - sqlite3VdbeMemSetNull(u.cj.pDest); |
| 69431 | + sqlite3VdbeMemSetNull(u.cm.pDest); |
| 69379 | 69432 | break; |
| 69380 | 69433 | } |
| 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)); |
| 69434 | + u.cm.pVtab = pCur->pVtabCursor->pVtab; |
| 69435 | + u.cm.pModule = u.cm.pVtab->pModule; |
| 69436 | + assert( u.cm.pModule->xColumn ); |
| 69437 | + memset(&u.cm.sContext, 0, sizeof(u.cm.sContext)); |
| 69385 | 69438 | |
| 69386 | 69439 | /* 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 |
| 69440 | + ** the current contents to u.cm.sContext.s so in case the user-function |
| 69388 | 69441 | ** can use the already allocated buffer instead of allocating a |
| 69389 | 69442 | ** new one. |
| 69390 | 69443 | */ |
| 69391 | | - sqlite3VdbeMemMove(&u.cj.sContext.s, u.cj.pDest); |
| 69392 | | - MemSetTypeFlag(&u.cj.sContext.s, MEM_Null); |
| 69444 | + sqlite3VdbeMemMove(&u.cm.sContext.s, u.cm.pDest); |
| 69445 | + MemSetTypeFlag(&u.cm.sContext.s, MEM_Null); |
| 69393 | 69446 | |
| 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; |
| 69447 | + rc = u.cm.pModule->xColumn(pCur->pVtabCursor, &u.cm.sContext, pOp->p2); |
| 69448 | + importVtabErrMsg(p, u.cm.pVtab); |
| 69449 | + if( u.cm.sContext.isError ){ |
| 69450 | + rc = u.cm.sContext.isError; |
| 69398 | 69451 | } |
| 69399 | 69452 | |
| 69400 | 69453 | /* Copy the result of the function to the P3 register. We |
| 69401 | 69454 | ** 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. |
| 69455 | + ** dynamic allocation in u.cm.sContext.s (a Mem struct) is released. |
| 69403 | 69456 | */ |
| 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); |
| 69457 | + sqlite3VdbeChangeEncoding(&u.cm.sContext.s, encoding); |
| 69458 | + sqlite3VdbeMemMove(u.cm.pDest, &u.cm.sContext.s); |
| 69459 | + REGISTER_TRACE(pOp->p3, u.cm.pDest); |
| 69460 | + UPDATE_MAX_BLOBSIZE(u.cm.pDest); |
| 69408 | 69461 | |
| 69409 | | - if( sqlite3VdbeMemTooBig(u.cj.pDest) ){ |
| 69462 | + if( sqlite3VdbeMemTooBig(u.cm.pDest) ){ |
| 69410 | 69463 | goto too_big; |
| 69411 | 69464 | } |
| 69412 | 69465 | break; |
| 69413 | 69466 | } |
| 69414 | 69467 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -69419,42 +69472,42 @@ |
| 69419 | 69472 | ** Advance virtual table P1 to the next row in its result set and |
| 69420 | 69473 | ** jump to instruction P2. Or, if the virtual table has reached |
| 69421 | 69474 | ** the end of its result set, then fall through to the next instruction. |
| 69422 | 69475 | */ |
| 69423 | 69476 | case OP_VNext: { /* jump */ |
| 69424 | | -#if 0 /* local variables moved into u.ck */ |
| 69477 | +#if 0 /* local variables moved into u.cn */ |
| 69425 | 69478 | sqlite3_vtab *pVtab; |
| 69426 | 69479 | const sqlite3_module *pModule; |
| 69427 | 69480 | int res; |
| 69428 | 69481 | VdbeCursor *pCur; |
| 69429 | | -#endif /* local variables moved into u.ck */ |
| 69482 | +#endif /* local variables moved into u.cn */ |
| 69430 | 69483 | |
| 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 ){ |
| 69484 | + u.cn.res = 0; |
| 69485 | + u.cn.pCur = p->apCsr[pOp->p1]; |
| 69486 | + assert( u.cn.pCur->pVtabCursor ); |
| 69487 | + if( u.cn.pCur->nullRow ){ |
| 69435 | 69488 | break; |
| 69436 | 69489 | } |
| 69437 | | - u.ck.pVtab = u.ck.pCur->pVtabCursor->pVtab; |
| 69438 | | - u.ck.pModule = u.ck.pVtab->pModule; |
| 69439 | | - assert( u.ck.pModule->xNext ); |
| 69490 | + u.cn.pVtab = u.cn.pCur->pVtabCursor->pVtab; |
| 69491 | + u.cn.pModule = u.cn.pVtab->pModule; |
| 69492 | + assert( u.cn.pModule->xNext ); |
| 69440 | 69493 | |
| 69441 | 69494 | /* Invoke the xNext() method of the module. There is no way for the |
| 69442 | 69495 | ** underlying implementation to return an error if one occurs during |
| 69443 | 69496 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 69444 | 69497 | ** data is available) and the error code returned when xColumn or |
| 69445 | 69498 | ** some other method is next invoked on the save virtual table cursor. |
| 69446 | 69499 | */ |
| 69447 | 69500 | p->inVtabMethod = 1; |
| 69448 | | - rc = u.ck.pModule->xNext(u.ck.pCur->pVtabCursor); |
| 69501 | + rc = u.cn.pModule->xNext(u.cn.pCur->pVtabCursor); |
| 69449 | 69502 | p->inVtabMethod = 0; |
| 69450 | | - importVtabErrMsg(p, u.ck.pVtab); |
| 69503 | + importVtabErrMsg(p, u.cn.pVtab); |
| 69451 | 69504 | if( rc==SQLITE_OK ){ |
| 69452 | | - u.ck.res = u.ck.pModule->xEof(u.ck.pCur->pVtabCursor); |
| 69505 | + u.cn.res = u.cn.pModule->xEof(u.cn.pCur->pVtabCursor); |
| 69453 | 69506 | } |
| 69454 | 69507 | |
| 69455 | | - if( !u.ck.res ){ |
| 69508 | + if( !u.cn.res ){ |
| 69456 | 69509 | /* If there is data, jump to P2 */ |
| 69457 | 69510 | pc = pOp->p2 - 1; |
| 69458 | 69511 | } |
| 69459 | 69512 | break; |
| 69460 | 69513 | } |
| | @@ -69466,23 +69519,23 @@ |
| 69466 | 69519 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 69467 | 69520 | ** This opcode invokes the corresponding xRename method. The value |
| 69468 | 69521 | ** in register P1 is passed as the zName argument to the xRename method. |
| 69469 | 69522 | */ |
| 69470 | 69523 | case OP_VRename: { |
| 69471 | | -#if 0 /* local variables moved into u.cl */ |
| 69524 | +#if 0 /* local variables moved into u.co */ |
| 69472 | 69525 | sqlite3_vtab *pVtab; |
| 69473 | 69526 | 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); |
| 69527 | +#endif /* local variables moved into u.co */ |
| 69528 | + |
| 69529 | + u.co.pVtab = pOp->p4.pVtab->pVtab; |
| 69530 | + u.co.pName = &aMem[pOp->p1]; |
| 69531 | + assert( u.co.pVtab->pModule->xRename ); |
| 69532 | + assert( memIsValid(u.co.pName) ); |
| 69533 | + REGISTER_TRACE(pOp->p1, u.co.pName); |
| 69534 | + assert( u.co.pName->flags & MEM_Str ); |
| 69535 | + rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z); |
| 69536 | + importVtabErrMsg(p, u.co.pVtab); |
| 69484 | 69537 | p->expired = 0; |
| 69485 | 69538 | |
| 69486 | 69539 | break; |
| 69487 | 69540 | } |
| 69488 | 69541 | #endif |
| | @@ -69510,45 +69563,45 @@ |
| 69510 | 69563 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 69511 | 69564 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 69512 | 69565 | ** is set to the value of the rowid for the row just inserted. |
| 69513 | 69566 | */ |
| 69514 | 69567 | case OP_VUpdate: { |
| 69515 | | -#if 0 /* local variables moved into u.cm */ |
| 69568 | +#if 0 /* local variables moved into u.cp */ |
| 69516 | 69569 | sqlite3_vtab *pVtab; |
| 69517 | 69570 | sqlite3_module *pModule; |
| 69518 | 69571 | int nArg; |
| 69519 | 69572 | int i; |
| 69520 | 69573 | sqlite_int64 rowid; |
| 69521 | 69574 | Mem **apArg; |
| 69522 | 69575 | Mem *pX; |
| 69523 | | -#endif /* local variables moved into u.cm */ |
| 69576 | +#endif /* local variables moved into u.cp */ |
| 69524 | 69577 | |
| 69525 | 69578 | assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 69526 | 69579 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 69527 | 69580 | ); |
| 69528 | | - u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 69529 | | - u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 69530 | | - u.cm.nArg = pOp->p2; |
| 69581 | + u.cp.pVtab = pOp->p4.pVtab->pVtab; |
| 69582 | + u.cp.pModule = (sqlite3_module *)u.cp.pVtab->pModule; |
| 69583 | + u.cp.nArg = pOp->p2; |
| 69531 | 69584 | assert( pOp->p4type==P4_VTAB ); |
| 69532 | | - if( ALWAYS(u.cm.pModule->xUpdate) ){ |
| 69585 | + if( ALWAYS(u.cp.pModule->xUpdate) ){ |
| 69533 | 69586 | 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++; |
| 69587 | + u.cp.apArg = p->apArg; |
| 69588 | + u.cp.pX = &aMem[pOp->p3]; |
| 69589 | + for(u.cp.i=0; u.cp.i<u.cp.nArg; u.cp.i++){ |
| 69590 | + assert( memIsValid(u.cp.pX) ); |
| 69591 | + memAboutToChange(p, u.cp.pX); |
| 69592 | + sqlite3VdbeMemStoreType(u.cp.pX); |
| 69593 | + u.cp.apArg[u.cp.i] = u.cp.pX; |
| 69594 | + u.cp.pX++; |
| 69542 | 69595 | } |
| 69543 | 69596 | db->vtabOnConflict = pOp->p5; |
| 69544 | | - rc = u.cm.pModule->xUpdate(u.cm.pVtab, u.cm.nArg, u.cm.apArg, &u.cm.rowid); |
| 69597 | + rc = u.cp.pModule->xUpdate(u.cp.pVtab, u.cp.nArg, u.cp.apArg, &u.cp.rowid); |
| 69545 | 69598 | db->vtabOnConflict = vtabOnConflict; |
| 69546 | | - importVtabErrMsg(p, u.cm.pVtab); |
| 69599 | + importVtabErrMsg(p, u.cp.pVtab); |
| 69547 | 69600 | 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; |
| 69601 | + assert( u.cp.nArg>1 && u.cp.apArg[0] && (u.cp.apArg[0]->flags&MEM_Null) ); |
| 69602 | + db->lastRowid = lastRowid = u.cp.rowid; |
| 69550 | 69603 | } |
| 69551 | 69604 | if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 69552 | 69605 | if( pOp->p5==OE_Ignore ){ |
| 69553 | 69606 | rc = SQLITE_OK; |
| 69554 | 69607 | }else{ |
| | @@ -69604,25 +69657,25 @@ |
| 69604 | 69657 | ** |
| 69605 | 69658 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 69606 | 69659 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 69607 | 69660 | */ |
| 69608 | 69661 | case OP_Trace: { |
| 69609 | | -#if 0 /* local variables moved into u.cn */ |
| 69662 | +#if 0 /* local variables moved into u.cq */ |
| 69610 | 69663 | char *zTrace; |
| 69611 | 69664 | char *z; |
| 69612 | | -#endif /* local variables moved into u.cn */ |
| 69665 | +#endif /* local variables moved into u.cq */ |
| 69613 | 69666 | |
| 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); |
| 69667 | + if( db->xTrace && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ |
| 69668 | + u.cq.z = sqlite3VdbeExpandSql(p, u.cq.zTrace); |
| 69669 | + db->xTrace(db->pTraceArg, u.cq.z); |
| 69670 | + sqlite3DbFree(db, u.cq.z); |
| 69618 | 69671 | } |
| 69619 | 69672 | #ifdef SQLITE_DEBUG |
| 69620 | 69673 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 69621 | | - && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69674 | + && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 69622 | 69675 | ){ |
| 69623 | | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 69676 | + sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); |
| 69624 | 69677 | } |
| 69625 | 69678 | #endif /* SQLITE_DEBUG */ |
| 69626 | 69679 | break; |
| 69627 | 69680 | } |
| 69628 | 69681 | #endif |
| | @@ -70021,21 +70074,21 @@ |
| 70021 | 70074 | /* Make sure a mutex is held on the table to be accessed */ |
| 70022 | 70075 | sqlite3VdbeUsesBtree(v, iDb); |
| 70023 | 70076 | |
| 70024 | 70077 | /* Configure the OP_TableLock instruction */ |
| 70025 | 70078 | #ifdef SQLITE_OMIT_SHARED_CACHE |
| 70026 | | - sqlite3VdbeChangeToNoop(v, 2, 1); |
| 70079 | + sqlite3VdbeChangeToNoop(v, 2); |
| 70027 | 70080 | #else |
| 70028 | 70081 | sqlite3VdbeChangeP1(v, 2, iDb); |
| 70029 | 70082 | sqlite3VdbeChangeP2(v, 2, pTab->tnum); |
| 70030 | 70083 | sqlite3VdbeChangeP3(v, 2, flags); |
| 70031 | 70084 | sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); |
| 70032 | 70085 | #endif |
| 70033 | 70086 | |
| 70034 | 70087 | /* Remove either the OP_OpenWrite or OpenRead. Set the P2 |
| 70035 | 70088 | ** parameter of the other to pTab->tnum. */ |
| 70036 | | - sqlite3VdbeChangeToNoop(v, 4 - flags, 1); |
| 70089 | + sqlite3VdbeChangeToNoop(v, 4 - flags); |
| 70037 | 70090 | sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); |
| 70038 | 70091 | sqlite3VdbeChangeP3(v, 3 + flags, iDb); |
| 70039 | 70092 | |
| 70040 | 70093 | /* Configure the number of columns. Configure the cursor to |
| 70041 | 70094 | ** think that the table has one more column than it really |
| | @@ -70239,10 +70292,11 @@ |
| 70239 | 70292 | |
| 70240 | 70293 | |
| 70241 | 70294 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70242 | 70295 | |
| 70243 | 70296 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70297 | +typedef struct SorterRecord SorterRecord; |
| 70244 | 70298 | |
| 70245 | 70299 | /* |
| 70246 | 70300 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70247 | 70301 | ** |
| 70248 | 70302 | ** As keys are added to the sorter, they are written to disk in a series |
| | @@ -70310,19 +70364,22 @@ |
| 70310 | 70364 | ** In other words, each time we advance to the next sorter element, log2(N) |
| 70311 | 70365 | ** key comparison operations are required, where N is the number of segments |
| 70312 | 70366 | ** being merged (rounded up to the next power of 2). |
| 70313 | 70367 | */ |
| 70314 | 70368 | 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 */ |
| 70369 | + int nInMemory; /* Current size of pRecord list as PMA */ |
| 70317 | 70370 | int nTree; /* Used size of aTree/aIter (power of 2) */ |
| 70318 | 70371 | VdbeSorterIter *aIter; /* Array of iterators to merge */ |
| 70319 | 70372 | int *aTree; /* Current state of incremental merge */ |
| 70320 | 70373 | i64 iWriteOff; /* Current write offset within file pTemp1 */ |
| 70321 | 70374 | i64 iReadOff; /* Current read offset within file pTemp1 */ |
| 70322 | 70375 | sqlite3_file *pTemp1; /* PMA file 1 */ |
| 70323 | 70376 | int nPMA; /* Number of PMAs stored in pTemp1 */ |
| 70377 | + SorterRecord *pRecord; /* Head of in-memory record list */ |
| 70378 | + int mnPmaSize; /* Minimum PMA size, in bytes */ |
| 70379 | + int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ |
| 70380 | + UnpackedRecord *pUnpacked; /* Used to unpack keys */ |
| 70324 | 70381 | }; |
| 70325 | 70382 | |
| 70326 | 70383 | /* |
| 70327 | 70384 | ** The following type is an iterator for a PMA. It caches the current key in |
| 70328 | 70385 | ** variables nKey/aKey. If the iterator is at EOF, pFile==0. |
| | @@ -70334,10 +70391,21 @@ |
| 70334 | 70391 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70335 | 70392 | u8 *aAlloc; /* Allocated space */ |
| 70336 | 70393 | int nKey; /* Number of bytes in key */ |
| 70337 | 70394 | u8 *aKey; /* Pointer to current key */ |
| 70338 | 70395 | }; |
| 70396 | + |
| 70397 | +/* |
| 70398 | +** A structure to store a single record. All in-memory records are connected |
| 70399 | +** together into a linked list headed at VdbeSorter.pRecord using the |
| 70400 | +** SorterRecord.pNext pointer. |
| 70401 | +*/ |
| 70402 | +struct SorterRecord { |
| 70403 | + void *pVal; |
| 70404 | + int nVal; |
| 70405 | + SorterRecord *pNext; |
| 70406 | +}; |
| 70339 | 70407 | |
| 70340 | 70408 | /* Minimum allowable value for the VdbeSorter.nWorking variable */ |
| 70341 | 70409 | #define SORTER_MIN_WORKING 10 |
| 70342 | 70410 | |
| 70343 | 70411 | /* Maximum number of segments to merge in a single pass. */ |
| | @@ -70360,41 +70428,46 @@ |
| 70360 | 70428 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70361 | 70429 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70362 | 70430 | ){ |
| 70363 | 70431 | int rc; /* Return Code */ |
| 70364 | 70432 | int nRead; /* Number of bytes read */ |
| 70365 | | - int nRec; /* Size of record in bytes */ |
| 70366 | | - int iOff; /* Size of serialized size varint in bytes */ |
| 70433 | + int nRec = 0; /* Size of record in bytes */ |
| 70434 | + int iOff = 0; /* Size of serialized size varint in bytes */ |
| 70367 | 70435 | |
| 70368 | | - nRead = pIter->iEof - pIter->iReadOff; |
| 70369 | | - if( nRead>5 ) nRead = 5; |
| 70436 | + assert( pIter->iEof>=pIter->iReadOff ); |
| 70437 | + if( pIter->iEof-pIter->iReadOff>5 ){ |
| 70438 | + nRead = 5; |
| 70439 | + }else{ |
| 70440 | + nRead = (int)(pIter->iEof - pIter->iReadOff); |
| 70441 | + } |
| 70370 | 70442 | if( nRead<=0 ){ |
| 70371 | 70443 | /* This is an EOF condition */ |
| 70372 | 70444 | vdbeSorterIterZero(db, pIter); |
| 70373 | 70445 | return SQLITE_OK; |
| 70374 | 70446 | } |
| 70375 | 70447 | |
| 70376 | 70448 | 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 ); |
| 70449 | + if( rc==SQLITE_OK ){ |
| 70450 | + iOff = getVarint32(pIter->aAlloc, nRec); |
| 70451 | + if( (iOff+nRec)>nRead ){ |
| 70452 | + int nRead2; /* Number of extra bytes to read */ |
| 70453 | + if( (iOff+nRec)>pIter->nAlloc ){ |
| 70454 | + int nNew = pIter->nAlloc*2; |
| 70455 | + while( (iOff+nRec)>nNew ) nNew = nNew*2; |
| 70456 | + pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); |
| 70457 | + if( !pIter->aAlloc ) return SQLITE_NOMEM; |
| 70458 | + pIter->nAlloc = nNew; |
| 70459 | + } |
| 70460 | + |
| 70461 | + nRead2 = iOff + nRec - nRead; |
| 70462 | + rc = sqlite3OsRead( |
| 70463 | + pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead |
| 70464 | + ); |
| 70465 | + } |
| 70466 | + } |
| 70467 | + |
| 70468 | + assert( rc!=SQLITE_OK || nRec>0 ); |
| 70396 | 70469 | pIter->iReadOff += iOff+nRec; |
| 70397 | 70470 | pIter->nKey = nRec; |
| 70398 | 70471 | pIter->aKey = &pIter->aAlloc[iOff]; |
| 70399 | 70472 | return rc; |
| 70400 | 70473 | } |
| | @@ -70434,25 +70507,18 @@ |
| 70434 | 70507 | ** set to the integer value read. If an error occurs, the final values of |
| 70435 | 70508 | ** both *piOffset and *piVal are undefined. |
| 70436 | 70509 | */ |
| 70437 | 70510 | static int vdbeSorterReadVarint( |
| 70438 | 70511 | sqlite3_file *pFile, /* File to read from */ |
| 70439 | | - i64 iEof, /* Total number of bytes in file */ |
| 70440 | 70512 | i64 *piOffset, /* IN/OUT: Read offset in pFile */ |
| 70441 | 70513 | i64 *piVal /* OUT: Value read from file */ |
| 70442 | 70514 | ){ |
| 70443 | 70515 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70444 | 70516 | i64 iOff = *piOffset; /* Offset in file to read from */ |
| 70445 | | - int nRead = 9; /* Number of bytes to read from file */ |
| 70446 | 70517 | int rc; /* Return code */ |
| 70447 | 70518 | |
| 70448 | | - assert( iEof>iOff ); |
| 70449 | | - if( (iEof-iOff)<nRead ){ |
| 70450 | | - nRead = iEof-iOff; |
| 70451 | | - } |
| 70452 | | - |
| 70453 | | - rc = sqlite3OsRead(pFile, aVarint, nRead, iOff); |
| 70519 | + rc = sqlite3OsRead(pFile, aVarint, 9, iOff); |
| 70454 | 70520 | if( rc==SQLITE_OK ){ |
| 70455 | 70521 | *piOffset += getVarint(aVarint, (u64 *)piVal); |
| 70456 | 70522 | } |
| 70457 | 70523 | |
| 70458 | 70524 | return rc; |
| | @@ -70480,22 +70546,68 @@ |
| 70480 | 70546 | pIter->nAlloc = 128; |
| 70481 | 70547 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70482 | 70548 | if( !pIter->aAlloc ){ |
| 70483 | 70549 | rc = SQLITE_NOMEM; |
| 70484 | 70550 | }else{ |
| 70485 | | - i64 iEof = pSorter->iWriteOff; /* EOF of file pSorter->pTemp1 */ |
| 70486 | 70551 | i64 nByte; /* Total size of PMA in bytes */ |
| 70487 | | - rc = vdbeSorterReadVarint(pSorter->pTemp1, iEof, &pIter->iReadOff, &nByte); |
| 70552 | + rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); |
| 70488 | 70553 | *pnByte += nByte; |
| 70489 | 70554 | pIter->iEof = pIter->iReadOff + nByte; |
| 70490 | 70555 | } |
| 70491 | 70556 | if( rc==SQLITE_OK ){ |
| 70492 | 70557 | rc = vdbeSorterIterNext(db, pIter); |
| 70493 | 70558 | } |
| 70494 | 70559 | return rc; |
| 70495 | 70560 | } |
| 70496 | 70561 | |
| 70562 | + |
| 70563 | +/* |
| 70564 | +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, |
| 70565 | +** size nKey2 bytes). Argument pKeyInfo supplies the collation functions |
| 70566 | +** used by the comparison. If an error occurs, return an SQLite error code. |
| 70567 | +** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive |
| 70568 | +** value, depending on whether key1 is smaller, equal to or larger than key2. |
| 70569 | +** |
| 70570 | +** If the bOmitRowid argument is non-zero, assume both keys end in a rowid |
| 70571 | +** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid |
| 70572 | +** is true and key1 contains even a single NULL value, it is considered to |
| 70573 | +** be less than key2. Even if key2 also contains NULL values. |
| 70574 | +** |
| 70575 | +** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 70576 | +** has been allocated and contains an unpacked record that is used as key2. |
| 70577 | +*/ |
| 70578 | +static void vdbeSorterCompare( |
| 70579 | + VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 70580 | + int bOmitRowid, /* Ignore rowid field at end of keys */ |
| 70581 | + void *pKey1, int nKey1, /* Left side of comparison */ |
| 70582 | + void *pKey2, int nKey2, /* Right side of comparison */ |
| 70583 | + int *pRes /* OUT: Result of comparison */ |
| 70584 | +){ |
| 70585 | + KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 70586 | + VdbeSorter *pSorter = pCsr->pSorter; |
| 70587 | + UnpackedRecord *r2 = pSorter->pUnpacked; |
| 70588 | + int i; |
| 70589 | + |
| 70590 | + if( pKey2 ){ |
| 70591 | + sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); |
| 70592 | + } |
| 70593 | + |
| 70594 | + if( bOmitRowid ){ |
| 70595 | + r2->nField = pKeyInfo->nField; |
| 70596 | + assert( r2->nField>0 ); |
| 70597 | + for(i=0; i<r2->nField; i++){ |
| 70598 | + if( r2->aMem[i].flags & MEM_Null ){ |
| 70599 | + *pRes = -1; |
| 70600 | + return; |
| 70601 | + } |
| 70602 | + } |
| 70603 | + r2->flags |= UNPACKED_PREFIX_MATCH; |
| 70604 | + } |
| 70605 | + |
| 70606 | + *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); |
| 70607 | +} |
| 70608 | + |
| 70497 | 70609 | /* |
| 70498 | 70610 | ** This function is called to compare two iterator keys when merging |
| 70499 | 70611 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70500 | 70612 | ** value to recalculate. |
| 70501 | 70613 | */ |
| | @@ -70523,24 +70635,20 @@ |
| 70523 | 70635 | if( p1->pFile==0 ){ |
| 70524 | 70636 | iRes = i2; |
| 70525 | 70637 | }else if( p2->pFile==0 ){ |
| 70526 | 70638 | iRes = i1; |
| 70527 | 70639 | }else{ |
| 70528 | | - char aSpace[150]; |
| 70529 | | - UnpackedRecord *r1; |
| 70530 | | - |
| 70531 | | - r1 = sqlite3VdbeRecordUnpack( |
| 70532 | | - pCsr->pKeyInfo, p1->nKey, p1->aKey, aSpace, sizeof(aSpace) |
| 70640 | + int res; |
| 70641 | + assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */ |
| 70642 | + vdbeSorterCompare( |
| 70643 | + pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res |
| 70533 | 70644 | ); |
| 70534 | | - if( r1==0 ) return SQLITE_NOMEM; |
| 70535 | | - |
| 70536 | | - if( sqlite3VdbeRecordCompare(p2->nKey, p2->aKey, r1)>=0 ){ |
| 70645 | + if( res<=0 ){ |
| 70537 | 70646 | iRes = i1; |
| 70538 | 70647 | }else{ |
| 70539 | 70648 | iRes = i2; |
| 70540 | 70649 | } |
| 70541 | | - sqlite3VdbeDeleteUnpackedRecord(r1); |
| 70542 | 70650 | } |
| 70543 | 70651 | |
| 70544 | 70652 | pSorter->aTree[iOut] = iRes; |
| 70545 | 70653 | return SQLITE_OK; |
| 70546 | 70654 | } |
| | @@ -70547,13 +70655,46 @@ |
| 70547 | 70655 | |
| 70548 | 70656 | /* |
| 70549 | 70657 | ** Initialize the temporary index cursor just opened as a sorter cursor. |
| 70550 | 70658 | */ |
| 70551 | 70659 | 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); |
| 70660 | + int pgsz; /* Page size of main database */ |
| 70661 | + int mxCache; /* Cache size */ |
| 70662 | + VdbeSorter *pSorter; /* The new sorter */ |
| 70663 | + char *d; /* Dummy */ |
| 70664 | + |
| 70665 | + assert( pCsr->pKeyInfo && pCsr->pBt==0 ); |
| 70666 | + pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); |
| 70667 | + if( pSorter==0 ){ |
| 70668 | + return SQLITE_NOMEM; |
| 70669 | + } |
| 70670 | + |
| 70671 | + pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d); |
| 70672 | + if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM; |
| 70673 | + assert( pSorter->pUnpacked==(UnpackedRecord *)d ); |
| 70674 | + |
| 70675 | + if( !sqlite3TempInMemory(db) ){ |
| 70676 | + pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 70677 | + pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; |
| 70678 | + mxCache = db->aDb[0].pSchema->cache_size; |
| 70679 | + if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; |
| 70680 | + pSorter->mxPmaSize = mxCache * pgsz; |
| 70681 | + } |
| 70682 | + |
| 70683 | + return SQLITE_OK; |
| 70684 | +} |
| 70685 | + |
| 70686 | +/* |
| 70687 | +** Free the list of sorted records starting at pRecord. |
| 70688 | +*/ |
| 70689 | +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ |
| 70690 | + SorterRecord *p; |
| 70691 | + SorterRecord *pNext; |
| 70692 | + for(p=pRecord; p; p=pNext){ |
| 70693 | + pNext = p->pNext; |
| 70694 | + sqlite3DbFree(db, p); |
| 70695 | + } |
| 70555 | 70696 | } |
| 70556 | 70697 | |
| 70557 | 70698 | /* |
| 70558 | 70699 | ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. |
| 70559 | 70700 | */ |
| | @@ -70568,10 +70709,12 @@ |
| 70568 | 70709 | sqlite3DbFree(db, pSorter->aIter); |
| 70569 | 70710 | } |
| 70570 | 70711 | if( pSorter->pTemp1 ){ |
| 70571 | 70712 | sqlite3OsCloseFree(pSorter->pTemp1); |
| 70572 | 70713 | } |
| 70714 | + vdbeSorterRecordFree(db, pSorter->pRecord); |
| 70715 | + sqlite3DbFree(db, pSorter->pUnpacked); |
| 70573 | 70716 | sqlite3DbFree(db, pSorter); |
| 70574 | 70717 | pCsr->pSorter = 0; |
| 70575 | 70718 | } |
| 70576 | 70719 | } |
| 70577 | 70720 | |
| | @@ -70587,14 +70730,86 @@ |
| 70587 | 70730 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| 70588 | 70731 | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy |
| 70589 | 70732 | ); |
| 70590 | 70733 | } |
| 70591 | 70734 | |
| 70735 | +/* |
| 70736 | +** Merge the two sorted lists p1 and p2 into a single list. |
| 70737 | +** Set *ppOut to the head of the new list. |
| 70738 | +*/ |
| 70739 | +static void vdbeSorterMerge( |
| 70740 | + VdbeCursor *pCsr, /* For pKeyInfo */ |
| 70741 | + SorterRecord *p1, /* First list to merge */ |
| 70742 | + SorterRecord *p2, /* Second list to merge */ |
| 70743 | + SorterRecord **ppOut /* OUT: Head of merged list */ |
| 70744 | +){ |
| 70745 | + SorterRecord *pFinal = 0; |
| 70746 | + SorterRecord **pp = &pFinal; |
| 70747 | + void *pVal2 = p2 ? p2->pVal : 0; |
| 70748 | + |
| 70749 | + while( p1 && p2 ){ |
| 70750 | + int res; |
| 70751 | + vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); |
| 70752 | + if( res<=0 ){ |
| 70753 | + *pp = p1; |
| 70754 | + pp = &p1->pNext; |
| 70755 | + p1 = p1->pNext; |
| 70756 | + pVal2 = 0; |
| 70757 | + }else{ |
| 70758 | + *pp = p2; |
| 70759 | + pp = &p2->pNext; |
| 70760 | + p2 = p2->pNext; |
| 70761 | + if( p2==0 ) break; |
| 70762 | + pVal2 = p2->pVal; |
| 70763 | + } |
| 70764 | + } |
| 70765 | + *pp = p1 ? p1 : p2; |
| 70766 | + *ppOut = pFinal; |
| 70767 | +} |
| 70592 | 70768 | |
| 70593 | 70769 | /* |
| 70594 | | -** Write the current contents of the b-tree to a PMA. Return SQLITE_OK |
| 70595 | | -** if successful, or an SQLite error code otherwise. |
| 70770 | +** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 70771 | +** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 70772 | +** occurs. |
| 70773 | +*/ |
| 70774 | +static int vdbeSorterSort(VdbeCursor *pCsr){ |
| 70775 | + int i; |
| 70776 | + SorterRecord **aSlot; |
| 70777 | + SorterRecord *p; |
| 70778 | + VdbeSorter *pSorter = pCsr->pSorter; |
| 70779 | + |
| 70780 | + aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); |
| 70781 | + if( !aSlot ){ |
| 70782 | + return SQLITE_NOMEM; |
| 70783 | + } |
| 70784 | + |
| 70785 | + p = pSorter->pRecord; |
| 70786 | + while( p ){ |
| 70787 | + SorterRecord *pNext = p->pNext; |
| 70788 | + p->pNext = 0; |
| 70789 | + for(i=0; aSlot[i]; i++){ |
| 70790 | + vdbeSorterMerge(pCsr, p, aSlot[i], &p); |
| 70791 | + aSlot[i] = 0; |
| 70792 | + } |
| 70793 | + aSlot[i] = p; |
| 70794 | + p = pNext; |
| 70795 | + } |
| 70796 | + |
| 70797 | + p = 0; |
| 70798 | + for(i=0; i<64; i++){ |
| 70799 | + vdbeSorterMerge(pCsr, p, aSlot[i], &p); |
| 70800 | + } |
| 70801 | + pSorter->pRecord = p; |
| 70802 | + |
| 70803 | + sqlite3_free(aSlot); |
| 70804 | + return SQLITE_OK; |
| 70805 | +} |
| 70806 | + |
| 70807 | + |
| 70808 | +/* |
| 70809 | +** Write the current contents of the in-memory linked-list to a PMA. Return |
| 70810 | +** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 70596 | 70811 | ** |
| 70597 | 70812 | ** The format of a PMA is: |
| 70598 | 70813 | ** |
| 70599 | 70814 | ** * A varint. This varint contains the total number of bytes of content |
| 70600 | 70815 | ** in the PMA (not including the varint itself). |
| | @@ -70601,153 +70816,111 @@ |
| 70601 | 70816 | ** |
| 70602 | 70817 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70603 | 70818 | ** Each record consists of a varint followed by a blob of data (the |
| 70604 | 70819 | ** key). The varint is the number of bytes in the blob of data. |
| 70605 | 70820 | */ |
| 70606 | | -static int vdbeSorterBtreeToPMA(sqlite3 *db, VdbeCursor *pCsr){ |
| 70821 | +static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ |
| 70607 | 70822 | int rc = SQLITE_OK; /* Return code */ |
| 70608 | 70823 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70609 | | - int res = 0; |
| 70610 | 70824 | |
| 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 ); |
| 70825 | + if( pSorter->nInMemory==0 ){ |
| 70826 | + assert( pSorter->pRecord==0 ); |
| 70827 | + return rc; |
| 70828 | + } |
| 70829 | + |
| 70830 | + rc = vdbeSorterSort(pCsr); |
| 70616 | 70831 | |
| 70617 | 70832 | /* If the first temporary PMA file has not been opened, open it now. */ |
| 70618 | | - if( pSorter->pTemp1==0 ){ |
| 70833 | + if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ |
| 70619 | 70834 | rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); |
| 70620 | 70835 | assert( rc!=SQLITE_OK || pSorter->pTemp1 ); |
| 70621 | 70836 | assert( pSorter->iWriteOff==0 ); |
| 70622 | 70837 | assert( pSorter->nPMA==0 ); |
| 70623 | 70838 | } |
| 70624 | 70839 | |
| 70625 | 70840 | 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 */ |
| 70841 | + i64 iOff = pSorter->iWriteOff; |
| 70842 | + SorterRecord *p; |
| 70843 | + SorterRecord *pNext = 0; |
| 70844 | + static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 70629 | 70845 | |
| 70630 | 70846 | 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 */ |
| 70847 | + rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); |
| 70848 | + for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ |
| 70849 | + pNext = p->pNext; |
| 70850 | + rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); |
| 70851 | + |
| 70653 | 70852 | 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 | | - } |
| 70853 | + rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); |
| 70854 | + iOff += p->nVal; |
| 70660 | 70855 | } |
| 70661 | 70856 | |
| 70662 | | - if( rc!=SQLITE_OK ) break; |
| 70857 | + sqlite3DbFree(db, p); |
| 70663 | 70858 | } |
| 70664 | 70859 | |
| 70665 | 70860 | /* This assert verifies that unless an error has occurred, the size of |
| 70666 | 70861 | ** 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) |
| 70862 | + ** pSorter->nInMemory. */ |
| 70863 | + assert( rc!=SQLITE_OK || pSorter->nInMemory==( |
| 70864 | + iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) |
| 70670 | 70865 | )); |
| 70671 | 70866 | |
| 70672 | | - pSorter->iWriteOff = iWriteOff; |
| 70673 | | - sqlite3DbFree(db, aMalloc); |
| 70867 | + pSorter->iWriteOff = iOff; |
| 70868 | + if( rc==SQLITE_OK ){ |
| 70869 | + /* Terminate each file with 8 extra bytes so that from any offset |
| 70870 | + ** in the file we can always read 9 bytes without a SHORT_READ error */ |
| 70871 | + rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); |
| 70872 | + } |
| 70873 | + pSorter->pRecord = p; |
| 70674 | 70874 | } |
| 70675 | 70875 | |
| 70676 | | - pSorter->nBtree = 0; |
| 70677 | 70876 | return rc; |
| 70678 | 70877 | } |
| 70679 | 70878 | |
| 70680 | 70879 | /* |
| 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. |
| 70880 | +** Add a record to the sorter. |
| 70692 | 70881 | */ |
| 70693 | | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *db, VdbeCursor *pCsr, int nKey){ |
| 70694 | | - int rc = SQLITE_OK; /* Return code */ |
| 70882 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 70883 | + sqlite3 *db, /* Database handle */ |
| 70884 | + VdbeCursor *pCsr, /* Sorter cursor */ |
| 70885 | + Mem *pVal /* Memory cell containing record */ |
| 70886 | +){ |
| 70695 | 70887 | 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 | | - } |
| 70888 | + int rc = SQLITE_OK; /* Return Code */ |
| 70889 | + SorterRecord *pNew; /* New list element */ |
| 70890 | + |
| 70891 | + assert( pSorter ); |
| 70892 | + pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; |
| 70893 | + |
| 70894 | + pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); |
| 70895 | + if( pNew==0 ){ |
| 70896 | + rc = SQLITE_NOMEM; |
| 70897 | + }else{ |
| 70898 | + pNew->pVal = (void *)&pNew[1]; |
| 70899 | + memcpy(pNew->pVal, pVal->z, pVal->n); |
| 70900 | + pNew->nVal = pVal->n; |
| 70901 | + pNew->pNext = pSorter->pRecord; |
| 70902 | + pSorter->pRecord = pNew; |
| 70903 | + } |
| 70904 | + |
| 70905 | + /* See if the contents of the sorter should now be written out. They |
| 70906 | + ** are written out when either of the following are true: |
| 70907 | + ** |
| 70908 | + ** * The total memory allocated for the in-memory list is greater |
| 70909 | + ** than (page-size * cache-size), or |
| 70910 | + ** |
| 70911 | + ** * The total memory allocated for the in-memory list is greater |
| 70912 | + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. |
| 70913 | + */ |
| 70914 | + if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 70915 | + (pSorter->nInMemory>pSorter->mxPmaSize) |
| 70916 | + || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 70917 | + )){ |
| 70918 | + rc = vdbeSorterListToPMA(db, pCsr); |
| 70919 | + pSorter->nInMemory = 0; |
| 70920 | + } |
| 70921 | + |
| 70749 | 70922 | return rc; |
| 70750 | 70923 | } |
| 70751 | 70924 | |
| 70752 | 70925 | /* |
| 70753 | 70926 | ** Helper function for sqlite3VdbeSorterRewind(). |
| | @@ -70761,16 +70934,16 @@ |
| 70761 | 70934 | int rc = SQLITE_OK; /* Return code */ |
| 70762 | 70935 | int i; /* Used to iterator through aIter[] */ |
| 70763 | 70936 | i64 nByte = 0; /* Total bytes in all opened PMAs */ |
| 70764 | 70937 | |
| 70765 | 70938 | /* Initialize the iterators. */ |
| 70766 | | - for(i=0; rc==SQLITE_OK && i<SORTER_MAX_MERGE_COUNT; i++){ |
| 70939 | + for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){ |
| 70767 | 70940 | VdbeSorterIter *pIter = &pSorter->aIter[i]; |
| 70768 | 70941 | rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte); |
| 70769 | 70942 | pSorter->iReadOff = pIter->iEof; |
| 70770 | | - assert( pSorter->iReadOff<=pSorter->iWriteOff || rc!=SQLITE_OK ); |
| 70771 | | - if( pSorter->iReadOff>=pSorter->iWriteOff ) break; |
| 70943 | + assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff ); |
| 70944 | + if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break; |
| 70772 | 70945 | } |
| 70773 | 70946 | |
| 70774 | 70947 | /* Initialize the aTree[] array. */ |
| 70775 | 70948 | for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){ |
| 70776 | 70949 | rc = vdbeSorterDoCompare(pCsr, i); |
| | @@ -70793,18 +70966,22 @@ |
| 70793 | 70966 | int nByte; /* Bytes of space required for aIter/aTree */ |
| 70794 | 70967 | int N = 2; /* Power of 2 >= nIter */ |
| 70795 | 70968 | |
| 70796 | 70969 | assert( pSorter ); |
| 70797 | 70970 | |
| 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; |
| 70971 | + /* If no data has been written to disk, then do not do so now. Instead, |
| 70972 | + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly |
| 70973 | + ** from the in-memory list. */ |
| 70802 | 70974 | if( pSorter->nPMA==0 ){ |
| 70803 | | - *pbEof = 1; |
| 70804 | | - return SQLITE_OK; |
| 70975 | + *pbEof = !pSorter->pRecord; |
| 70976 | + assert( pSorter->aTree==0 ); |
| 70977 | + return vdbeSorterSort(pCsr); |
| 70805 | 70978 | } |
| 70979 | + |
| 70980 | + /* Write the current b-tree to a PMA. Close the b-tree cursor. */ |
| 70981 | + rc = vdbeSorterListToPMA(db, pCsr); |
| 70982 | + if( rc!=SQLITE_OK ) return rc; |
| 70806 | 70983 | |
| 70807 | 70984 | /* Allocate space for aIter[] and aTree[]. */ |
| 70808 | 70985 | nIter = pSorter->nPMA; |
| 70809 | 70986 | if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; |
| 70810 | 70987 | assert( nIter>0 ); |
| | @@ -70888,47 +71065,94 @@ |
| 70888 | 71065 | /* |
| 70889 | 71066 | ** Advance to the next element in the sorter. |
| 70890 | 71067 | */ |
| 70891 | 71068 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 70892 | 71069 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70893 | | - int iPrev = pSorter->aTree[1]; /* Index of iterator to advance */ |
| 70894 | | - int i; /* Index of aTree[] to recalculate */ |
| 70895 | 71070 | int rc; /* Return code */ |
| 70896 | 71071 | |
| 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); |
| 71072 | + if( pSorter->aTree ){ |
| 71073 | + int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| 71074 | + int i; /* Index of aTree[] to recalculate */ |
| 71075 | + |
| 71076 | + rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); |
| 71077 | + for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ |
| 71078 | + rc = vdbeSorterDoCompare(pCsr, i); |
| 71079 | + } |
| 71080 | + |
| 71081 | + *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 71082 | + }else{ |
| 71083 | + SorterRecord *pFree = pSorter->pRecord; |
| 71084 | + pSorter->pRecord = pFree->pNext; |
| 71085 | + pFree->pNext = 0; |
| 71086 | + vdbeSorterRecordFree(db, pFree); |
| 71087 | + *pbEof = !pSorter->pRecord; |
| 71088 | + rc = SQLITE_OK; |
| 70900 | 71089 | } |
| 71090 | + return rc; |
| 71091 | +} |
| 70901 | 71092 | |
| 70902 | | - *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); |
| 70903 | | - return rc; |
| 71093 | +/* |
| 71094 | +** Return a pointer to a buffer owned by the sorter that contains the |
| 71095 | +** current key. |
| 71096 | +*/ |
| 71097 | +static void *vdbeSorterRowkey( |
| 71098 | + VdbeSorter *pSorter, /* Sorter object */ |
| 71099 | + int *pnKey /* OUT: Size of current key in bytes */ |
| 71100 | +){ |
| 71101 | + void *pKey; |
| 71102 | + if( pSorter->aTree ){ |
| 71103 | + VdbeSorterIter *pIter; |
| 71104 | + pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 71105 | + *pnKey = pIter->nKey; |
| 71106 | + pKey = pIter->aKey; |
| 71107 | + }else{ |
| 71108 | + *pnKey = pSorter->pRecord->nVal; |
| 71109 | + pKey = pSorter->pRecord->pVal; |
| 71110 | + } |
| 71111 | + return pKey; |
| 70904 | 71112 | } |
| 70905 | 71113 | |
| 70906 | 71114 | /* |
| 70907 | 71115 | ** Copy the current sorter key into the memory cell pOut. |
| 70908 | 71116 | */ |
| 70909 | 71117 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ |
| 70910 | 71118 | 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)) ){ |
| 71119 | + void *pKey; int nKey; /* Sorter key to copy into pOut */ |
| 71120 | + |
| 71121 | + pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 71122 | + if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ |
| 70922 | 71123 | return SQLITE_NOMEM; |
| 70923 | 71124 | } |
| 70924 | | - pOut->n = pIter->nKey; |
| 71125 | + pOut->n = nKey; |
| 70925 | 71126 | MemSetTypeFlag(pOut, MEM_Blob); |
| 70926 | | - memcpy(pOut->z, pIter->aKey, pIter->nKey); |
| 71127 | + memcpy(pOut->z, pKey, nKey); |
| 70927 | 71128 | |
| 70928 | 71129 | return SQLITE_OK; |
| 70929 | 71130 | } |
| 71131 | + |
| 71132 | +/* |
| 71133 | +** Compare the key in memory cell pVal with the key that the sorter cursor |
| 71134 | +** passed as the first argument currently points to. For the purposes of |
| 71135 | +** the comparison, ignore the rowid field at the end of each record. |
| 71136 | +** |
| 71137 | +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). |
| 71138 | +** Otherwise, set *pRes to a negative, zero or positive value if the |
| 71139 | +** key in pVal is smaller than, equal to or larger than the current sorter |
| 71140 | +** key. |
| 71141 | +*/ |
| 71142 | +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 71143 | + VdbeCursor *pCsr, /* Sorter cursor */ |
| 71144 | + Mem *pVal, /* Value to compare to current sorter key */ |
| 71145 | + int *pRes /* OUT: Result of comparison */ |
| 71146 | +){ |
| 71147 | + VdbeSorter *pSorter = pCsr->pSorter; |
| 71148 | + void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| 71149 | + |
| 71150 | + pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 71151 | + vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); |
| 71152 | + return SQLITE_OK; |
| 71153 | +} |
| 70930 | 71154 | |
| 70931 | 71155 | #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ |
| 70932 | 71156 | |
| 70933 | 71157 | /************** End of vdbesort.c ********************************************/ |
| 70934 | 71158 | /************** Begin file journal.c *****************************************/ |
| | @@ -73691,11 +73915,12 @@ |
| 73691 | 73915 | pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); |
| 73692 | 73916 | pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 73693 | 73917 | pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); |
| 73694 | 73918 | pNewItem->jointype = pOldItem->jointype; |
| 73695 | 73919 | pNewItem->iCursor = pOldItem->iCursor; |
| 73696 | | - pNewItem->isPopulated = pOldItem->isPopulated; |
| 73920 | + pNewItem->addrFillSub = pOldItem->addrFillSub; |
| 73921 | + pNewItem->regReturn = pOldItem->regReturn; |
| 73697 | 73922 | pNewItem->isCorrelated = pOldItem->isCorrelated; |
| 73698 | 73923 | pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); |
| 73699 | 73924 | pNewItem->notIndexed = pOldItem->notIndexed; |
| 73700 | 73925 | pNewItem->pIndex = pOldItem->pIndex; |
| 73701 | 73926 | pTab = pNewItem->pTab = pOldItem->pTab; |
| | @@ -74251,12 +74476,11 @@ |
| 74251 | 74476 | assert(v); |
| 74252 | 74477 | if( iCol<0 ){ |
| 74253 | 74478 | int iMem = ++pParse->nMem; |
| 74254 | 74479 | int iAddr; |
| 74255 | 74480 | |
| 74256 | | - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); |
| 74257 | | - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); |
| 74481 | + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); |
| 74258 | 74482 | |
| 74259 | 74483 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| 74260 | 74484 | eType = IN_INDEX_ROWID; |
| 74261 | 74485 | |
| 74262 | 74486 | sqlite3VdbeJumpHere(v, iAddr); |
| | @@ -74283,12 +74507,11 @@ |
| 74283 | 74507 | int iMem = ++pParse->nMem; |
| 74284 | 74508 | int iAddr; |
| 74285 | 74509 | char *pKey; |
| 74286 | 74510 | |
| 74287 | 74511 | pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); |
| 74288 | | - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); |
| 74289 | | - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); |
| 74512 | + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); |
| 74290 | 74513 | |
| 74291 | 74514 | sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, |
| 74292 | 74515 | pKey,P4_KEYINFO_HANDOFF); |
| 74293 | 74516 | VdbeComment((v, "%s", pIdx->zName)); |
| 74294 | 74517 | eType = IN_INDEX_INDEX; |
| | @@ -74365,11 +74588,11 @@ |
| 74365 | 74588 | Parse *pParse, /* Parsing context */ |
| 74366 | 74589 | Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ |
| 74367 | 74590 | int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ |
| 74368 | 74591 | int isRowid /* If true, LHS of IN operator is a rowid */ |
| 74369 | 74592 | ){ |
| 74370 | | - int testAddr = 0; /* One-time test address */ |
| 74593 | + int testAddr = -1; /* One-time test address */ |
| 74371 | 74594 | int rReg = 0; /* Register storing resulting */ |
| 74372 | 74595 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 74373 | 74596 | if( NEVER(v==0) ) return 0; |
| 74374 | 74597 | sqlite3ExprCachePush(pParse); |
| 74375 | 74598 | |
| | @@ -74383,19 +74606,17 @@ |
| 74383 | 74606 | ** If all of the above are false, then we can run this code just once |
| 74384 | 74607 | ** save the results, and reuse the same result on subsequent invocations. |
| 74385 | 74608 | */ |
| 74386 | 74609 | if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ |
| 74387 | 74610 | int mem = ++pParse->nMem; |
| 74388 | | - sqlite3VdbeAddOp1(v, OP_If, mem); |
| 74389 | | - testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); |
| 74390 | | - assert( testAddr>0 || pParse->db->mallocFailed ); |
| 74611 | + testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); |
| 74391 | 74612 | } |
| 74392 | 74613 | |
| 74393 | 74614 | #ifndef SQLITE_OMIT_EXPLAIN |
| 74394 | 74615 | if( pParse->explain==2 ){ |
| 74395 | 74616 | char *zMsg = sqlite3MPrintf( |
| 74396 | | - pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr?"":"CORRELATED ", |
| 74617 | + pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", |
| 74397 | 74618 | pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId |
| 74398 | 74619 | ); |
| 74399 | 74620 | sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); |
| 74400 | 74621 | } |
| 74401 | 74622 | #endif |
| | @@ -74483,13 +74704,13 @@ |
| 74483 | 74704 | /* If the expression is not constant then we will need to |
| 74484 | 74705 | ** disable the test that was generated above that makes sure |
| 74485 | 74706 | ** this code only executes once. Because for a non-constant |
| 74486 | 74707 | ** expression we need to rerun this code each time. |
| 74487 | 74708 | */ |
| 74488 | | - if( testAddr && !sqlite3ExprIsConstant(pE2) ){ |
| 74489 | | - sqlite3VdbeChangeToNoop(v, testAddr-1, 2); |
| 74490 | | - testAddr = 0; |
| 74709 | + if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ |
| 74710 | + sqlite3VdbeChangeToNoop(v, testAddr); |
| 74711 | + testAddr = -1; |
| 74491 | 74712 | } |
| 74492 | 74713 | |
| 74493 | 74714 | /* Evaluate the expression and insert it into the temp table */ |
| 74494 | 74715 | if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ |
| 74495 | 74716 | sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); |
| | @@ -74554,12 +74775,12 @@ |
| 74554 | 74775 | ExprSetIrreducible(pExpr); |
| 74555 | 74776 | break; |
| 74556 | 74777 | } |
| 74557 | 74778 | } |
| 74558 | 74779 | |
| 74559 | | - if( testAddr ){ |
| 74560 | | - sqlite3VdbeJumpHere(v, testAddr-1); |
| 74780 | + if( testAddr>=0 ){ |
| 74781 | + sqlite3VdbeJumpHere(v, testAddr); |
| 74561 | 74782 | } |
| 74562 | 74783 | sqlite3ExprCachePop(pParse, 1); |
| 74563 | 74784 | |
| 74564 | 74785 | return rReg; |
| 74565 | 74786 | } |
| | @@ -75077,11 +75298,11 @@ |
| 75077 | 75298 | if( !pAggInfo->directMode ){ |
| 75078 | 75299 | assert( pCol->iMem>0 ); |
| 75079 | 75300 | inReg = pCol->iMem; |
| 75080 | 75301 | break; |
| 75081 | 75302 | }else if( pAggInfo->useSortingIdx ){ |
| 75082 | | - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, |
| 75303 | + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, |
| 75083 | 75304 | pCol->iSorterColumn, target); |
| 75084 | 75305 | break; |
| 75085 | 75306 | } |
| 75086 | 75307 | /* Otherwise, fall thru into the TK_COLUMN case */ |
| 75087 | 75308 | } |
| | @@ -81235,27 +81456,19 @@ |
| 81235 | 81456 | Table *pTab = pIndex->pTable; /* The table that is indexed */ |
| 81236 | 81457 | int iTab = pParse->nTab++; /* Btree cursor used for pTab */ |
| 81237 | 81458 | int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ |
| 81238 | 81459 | int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ |
| 81239 | 81460 | int addr1; /* Address of top of loop */ |
| 81461 | + int addr2; /* Address to jump to for next iteration */ |
| 81240 | 81462 | int tnum; /* Root page of index */ |
| 81241 | 81463 | Vdbe *v; /* Generate code into this virtual machine */ |
| 81242 | 81464 | KeyInfo *pKey; /* KeyInfo for index */ |
| 81243 | 81465 | int regIdxKey; /* Registers containing the index key */ |
| 81244 | 81466 | int regRecord; /* Register holding assemblied index record */ |
| 81245 | 81467 | sqlite3 *db = pParse->db; /* The database connection */ |
| 81246 | 81468 | int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); |
| 81247 | 81469 | |
| 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 | 81470 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 81258 | 81471 | if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, |
| 81259 | 81472 | db->aDb[iDb].zName ) ){ |
| 81260 | 81473 | return; |
| 81261 | 81474 | } |
| | @@ -81277,32 +81490,44 @@ |
| 81277 | 81490 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81278 | 81491 | if( memRootPage>=0 ){ |
| 81279 | 81492 | sqlite3VdbeChangeP5(v, 1); |
| 81280 | 81493 | } |
| 81281 | 81494 | |
| 81495 | +#ifndef SQLITE_OMIT_MERGE_SORT |
| 81282 | 81496 | /* 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 | | - } |
| 81497 | + iSorter = pParse->nTab++; |
| 81498 | + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| 81499 | +#endif |
| 81288 | 81500 | |
| 81289 | 81501 | /* Open the table. Loop through all rows of the table, inserting index |
| 81290 | 81502 | ** records into the sorter. */ |
| 81291 | 81503 | sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); |
| 81292 | 81504 | addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); |
| 81505 | + addr2 = addr1 + 1; |
| 81293 | 81506 | regRecord = sqlite3GetTempReg(pParse); |
| 81294 | 81507 | regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); |
| 81295 | 81508 | |
| 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 | | - |
| 81509 | +#ifndef SQLITE_OMIT_MERGE_SORT |
| 81510 | + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); |
| 81511 | + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); |
| 81512 | + sqlite3VdbeJumpHere(v, addr1); |
| 81513 | + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); |
| 81514 | + if( pIndex->onError!=OE_None ){ |
| 81515 | + int j2 = sqlite3VdbeCurrentAddr(v) + 3; |
| 81516 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); |
| 81517 | + addr2 = sqlite3VdbeCurrentAddr(v); |
| 81518 | + sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); |
| 81519 | + sqlite3HaltConstraint( |
| 81520 | + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC |
| 81521 | + ); |
| 81522 | + }else{ |
| 81523 | + addr2 = sqlite3VdbeCurrentAddr(v); |
| 81524 | + } |
| 81525 | + sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); |
| 81526 | + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); |
| 81527 | + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81528 | +#else |
| 81304 | 81529 | if( pIndex->onError!=OE_None ){ |
| 81305 | 81530 | const int regRowid = regIdxKey + pIndex->nColumn; |
| 81306 | 81531 | const int j2 = sqlite3VdbeCurrentAddr(v) + 2; |
| 81307 | 81532 | void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); |
| 81308 | 81533 | |
| | @@ -81317,14 +81542,15 @@ |
| 81317 | 81542 | */ |
| 81318 | 81543 | sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); |
| 81319 | 81544 | sqlite3HaltConstraint( |
| 81320 | 81545 | pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); |
| 81321 | 81546 | } |
| 81322 | | - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, bUseSorter); |
| 81547 | + sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); |
| 81323 | 81548 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 81549 | +#endif |
| 81324 | 81550 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 81325 | | - sqlite3VdbeAddOp2(v, OP_Next, iSorter, addr1+1); |
| 81551 | + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); |
| 81326 | 81552 | sqlite3VdbeJumpHere(v, addr1); |
| 81327 | 81553 | |
| 81328 | 81554 | sqlite3VdbeAddOp1(v, OP_Close, iTab); |
| 81329 | 81555 | sqlite3VdbeAddOp1(v, OP_Close, iIdx); |
| 81330 | 81556 | sqlite3VdbeAddOp1(v, OP_Close, iSorter); |
| | @@ -92204,10 +92430,12 @@ |
| 92204 | 92430 | pNew->addrOpenEphm[2] = -1; |
| 92205 | 92431 | if( db->mallocFailed ) { |
| 92206 | 92432 | clearSelect(db, pNew); |
| 92207 | 92433 | if( pNew!=&standin ) sqlite3DbFree(db, pNew); |
| 92208 | 92434 | pNew = 0; |
| 92435 | + }else{ |
| 92436 | + assert( pNew->pSrc!=0 || pParse->nErr>0 ); |
| 92209 | 92437 | } |
| 92210 | 92438 | return pNew; |
| 92211 | 92439 | } |
| 92212 | 92440 | |
| 92213 | 92441 | /* |
| | @@ -92534,16 +92762,22 @@ |
| 92534 | 92762 | ){ |
| 92535 | 92763 | Vdbe *v = pParse->pVdbe; |
| 92536 | 92764 | int nExpr = pOrderBy->nExpr; |
| 92537 | 92765 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); |
| 92538 | 92766 | int regRecord = sqlite3GetTempReg(pParse); |
| 92767 | + int op; |
| 92539 | 92768 | sqlite3ExprCacheClear(pParse); |
| 92540 | 92769 | sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); |
| 92541 | 92770 | sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); |
| 92542 | 92771 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); |
| 92543 | 92772 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); |
| 92544 | | - sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); |
| 92773 | + if( pSelect->selFlags & SF_UseSorter ){ |
| 92774 | + op = OP_SorterInsert; |
| 92775 | + }else{ |
| 92776 | + op = OP_IdxInsert; |
| 92777 | + } |
| 92778 | + sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); |
| 92545 | 92779 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 92546 | 92780 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); |
| 92547 | 92781 | if( pSelect->iLimit ){ |
| 92548 | 92782 | int addr1, addr2; |
| 92549 | 92783 | int iLimit; |
| | @@ -93008,13 +93242,24 @@ |
| 93008 | 93242 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); |
| 93009 | 93243 | regRowid = 0; |
| 93010 | 93244 | }else{ |
| 93011 | 93245 | regRowid = sqlite3GetTempReg(pParse); |
| 93012 | 93246 | } |
| 93013 | | - addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); |
| 93014 | | - codeOffset(v, p, addrContinue); |
| 93015 | | - sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); |
| 93247 | + if( p->selFlags & SF_UseSorter ){ |
| 93248 | + int regSortOut = ++pParse->nMem; |
| 93249 | + int ptab2 = pParse->nTab++; |
| 93250 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); |
| 93251 | + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); |
| 93252 | + codeOffset(v, p, addrContinue); |
| 93253 | + sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); |
| 93254 | + sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); |
| 93255 | + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 93256 | + }else{ |
| 93257 | + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); |
| 93258 | + codeOffset(v, p, addrContinue); |
| 93259 | + sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); |
| 93260 | + } |
| 93016 | 93261 | switch( eDest ){ |
| 93017 | 93262 | case SRT_Table: |
| 93018 | 93263 | case SRT_EphemTab: { |
| 93019 | 93264 | testcase( eDest==SRT_Table ); |
| 93020 | 93265 | testcase( eDest==SRT_EphemTab ); |
| | @@ -93063,11 +93308,15 @@ |
| 93063 | 93308 | sqlite3ReleaseTempReg(pParse, regRowid); |
| 93064 | 93309 | |
| 93065 | 93310 | /* The bottom of the loop |
| 93066 | 93311 | */ |
| 93067 | 93312 | sqlite3VdbeResolveLabel(v, addrContinue); |
| 93068 | | - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); |
| 93313 | + if( p->selFlags & SF_UseSorter ){ |
| 93314 | + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); |
| 93315 | + }else{ |
| 93316 | + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); |
| 93317 | + } |
| 93069 | 93318 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 93070 | 93319 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ |
| 93071 | 93320 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); |
| 93072 | 93321 | } |
| 93073 | 93322 | } |
| | @@ -95895,11 +96144,15 @@ |
| 95895 | 96144 | struct SrcList_item *pItem = &pTabList->a[i]; |
| 95896 | 96145 | SelectDest dest; |
| 95897 | 96146 | Select *pSub = pItem->pSelect; |
| 95898 | 96147 | int isAggSub; |
| 95899 | 96148 | |
| 95900 | | - if( pSub==0 || pItem->isPopulated ) continue; |
| 96149 | + if( pSub==0 ) continue; |
| 96150 | + if( pItem->addrFillSub ){ |
| 96151 | + sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); |
| 96152 | + continue; |
| 96153 | + } |
| 95901 | 96154 | |
| 95902 | 96155 | /* Increment Parse.nHeight by the height of the largest expression |
| 95903 | 96156 | ** tree refered to by this, the parent select. The child select |
| 95904 | 96157 | ** may contain expression trees of at most |
| 95905 | 96158 | ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit |
| | @@ -95906,25 +96159,48 @@ |
| 95906 | 96159 | ** more conservative than necessary, but much easier than enforcing |
| 95907 | 96160 | ** an exact limit. |
| 95908 | 96161 | */ |
| 95909 | 96162 | pParse->nHeight += sqlite3SelectExprHeight(p); |
| 95910 | 96163 | |
| 95911 | | - /* Check to see if the subquery can be absorbed into the parent. */ |
| 95912 | 96164 | isAggSub = (pSub->selFlags & SF_Aggregate)!=0; |
| 95913 | 96165 | if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ |
| 96166 | + /* This subquery can be absorbed into its parent. */ |
| 95914 | 96167 | if( isAggSub ){ |
| 95915 | 96168 | isAgg = 1; |
| 95916 | 96169 | p->selFlags |= SF_Aggregate; |
| 95917 | 96170 | } |
| 95918 | 96171 | i = -1; |
| 95919 | 96172 | }else{ |
| 96173 | + /* Generate a subroutine that will fill an ephemeral table with |
| 96174 | + ** the content of this subquery. pItem->addrFillSub will point |
| 96175 | + ** to the address of the generated subroutine. pItem->regReturn |
| 96176 | + ** is a register allocated to hold the subroutine return address |
| 96177 | + */ |
| 96178 | + int topAddr; |
| 96179 | + int onceAddr = 0; |
| 96180 | + int retAddr; |
| 96181 | + assert( pItem->addrFillSub==0 ); |
| 96182 | + pItem->regReturn = ++pParse->nMem; |
| 96183 | + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); |
| 96184 | + pItem->addrFillSub = topAddr+1; |
| 96185 | + VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); |
| 96186 | + if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){ |
| 96187 | + /* If the subquery is no correlated and if we are not inside of |
| 96188 | + ** a trigger, then we only need to compute the value of the subquery |
| 96189 | + ** once. */ |
| 96190 | + int regOnce = ++pParse->nMem; |
| 96191 | + onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); |
| 96192 | + } |
| 95920 | 96193 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| 95921 | | - assert( pItem->isPopulated==0 ); |
| 95922 | 96194 | explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); |
| 95923 | 96195 | sqlite3Select(pParse, pSub, &dest); |
| 95924 | | - pItem->isPopulated = 1; |
| 95925 | 96196 | pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; |
| 96197 | + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 96198 | + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); |
| 96199 | + VdbeComment((v, "end %s", pItem->pTab->zName)); |
| 96200 | + sqlite3VdbeChangeP1(v, topAddr, retAddr); |
| 96201 | + |
| 95926 | 96202 | } |
| 95927 | 96203 | if( /*pParse->nErr ||*/ db->mallocFailed ){ |
| 95928 | 96204 | goto select_end; |
| 95929 | 96205 | } |
| 95930 | 96206 | pParse->nHeight -= sqlite3SelectExprHeight(p); |
| | @@ -96029,10 +96305,14 @@ |
| 96029 | 96305 | /* Set the limiter. |
| 96030 | 96306 | */ |
| 96031 | 96307 | iEnd = sqlite3VdbeMakeLabel(v); |
| 96032 | 96308 | p->nSelectRow = (double)LARGEST_INT64; |
| 96033 | 96309 | computeLimitRegisters(pParse, p, iEnd); |
| 96310 | + if( p->iLimit==0 && addrSortIndex>=0 ){ |
| 96311 | + sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; |
| 96312 | + p->selFlags |= SF_UseSorter; |
| 96313 | + } |
| 96034 | 96314 | |
| 96035 | 96315 | /* Open a virtual index to use for the distinct set. |
| 96036 | 96316 | */ |
| 96037 | 96317 | if( p->selFlags & SF_Distinct ){ |
| 96038 | 96318 | KeyInfo *pKeyInfo; |
| | @@ -96057,18 +96337,18 @@ |
| 96057 | 96337 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| 96058 | 96338 | ** instruction ended up not being needed, then change the OP_OpenEphemeral |
| 96059 | 96339 | ** into an OP_Noop. |
| 96060 | 96340 | */ |
| 96061 | 96341 | if( addrSortIndex>=0 && pOrderBy==0 ){ |
| 96062 | | - sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); |
| 96342 | + sqlite3VdbeChangeToNoop(v, addrSortIndex); |
| 96063 | 96343 | p->addrOpenEphm[2] = -1; |
| 96064 | 96344 | } |
| 96065 | 96345 | |
| 96066 | 96346 | if( pWInfo->eDistinct ){ |
| 96067 | 96347 | VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ |
| 96068 | 96348 | |
| 96069 | | - assert( addrDistinctIndex>0 ); |
| 96349 | + assert( addrDistinctIndex>=0 ); |
| 96070 | 96350 | pOp = sqlite3VdbeGetOp(v, addrDistinctIndex); |
| 96071 | 96351 | |
| 96072 | 96352 | assert( isDistinct ); |
| 96073 | 96353 | assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED |
| 96074 | 96354 | || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE |
| | @@ -96123,10 +96403,12 @@ |
| 96123 | 96403 | ** one row of the input to the aggregator has been |
| 96124 | 96404 | ** processed */ |
| 96125 | 96405 | int iAbortFlag; /* Mem address which causes query abort if positive */ |
| 96126 | 96406 | int groupBySort; /* Rows come from source in GROUP BY order */ |
| 96127 | 96407 | int addrEnd; /* End of processing for this SELECT */ |
| 96408 | + int sortPTab = 0; /* Pseudotable used to decode sorting results */ |
| 96409 | + int sortOut = 0; /* Output register from the sorter */ |
| 96128 | 96410 | |
| 96129 | 96411 | /* Remove any and all aliases between the result set and the |
| 96130 | 96412 | ** GROUP BY clause. |
| 96131 | 96413 | */ |
| 96132 | 96414 | if( pGroupBy ){ |
| | @@ -96184,16 +96466,16 @@ |
| 96184 | 96466 | int addrReset; /* Subroutine for resetting the accumulator */ |
| 96185 | 96467 | int regReset; /* Return address register for reset subroutine */ |
| 96186 | 96468 | |
| 96187 | 96469 | /* If there is a GROUP BY clause we might need a sorting index to |
| 96188 | 96470 | ** implement it. Allocate that sorting index now. If it turns out |
| 96189 | | - ** that we do not need it after all, the OpenEphemeral instruction |
| 96471 | + ** that we do not need it after all, the OP_SorterOpen instruction |
| 96190 | 96472 | ** will be converted into a Noop. |
| 96191 | 96473 | */ |
| 96192 | 96474 | sAggInfo.sortingIdx = pParse->nTab++; |
| 96193 | 96475 | pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); |
| 96194 | | - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, |
| 96476 | + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, |
| 96195 | 96477 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, |
| 96196 | 96478 | 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); |
| 96197 | 96479 | |
| 96198 | 96480 | /* Initialize memory locations used by GROUP BY aggregate processing |
| 96199 | 96481 | */ |
| | @@ -96270,15 +96552,18 @@ |
| 96270 | 96552 | j++; |
| 96271 | 96553 | } |
| 96272 | 96554 | } |
| 96273 | 96555 | regRecord = sqlite3GetTempReg(pParse); |
| 96274 | 96556 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); |
| 96275 | | - sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); |
| 96557 | + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); |
| 96276 | 96558 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 96277 | 96559 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 96278 | 96560 | sqlite3WhereEnd(pWInfo); |
| 96279 | | - sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); |
| 96561 | + sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; |
| 96562 | + sortOut = sqlite3GetTempReg(pParse); |
| 96563 | + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 96564 | + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); |
| 96280 | 96565 | VdbeComment((v, "GROUP BY sort")); |
| 96281 | 96566 | sAggInfo.useSortingIdx = 1; |
| 96282 | 96567 | sqlite3ExprCacheClear(pParse); |
| 96283 | 96568 | } |
| 96284 | 96569 | |
| | @@ -96287,13 +96572,17 @@ |
| 96287 | 96572 | ** Then compare the current GROUP BY terms against the GROUP BY terms |
| 96288 | 96573 | ** from the previous row currently stored in a0, a1, a2... |
| 96289 | 96574 | */ |
| 96290 | 96575 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); |
| 96291 | 96576 | sqlite3ExprCacheClear(pParse); |
| 96577 | + if( groupBySort ){ |
| 96578 | + sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); |
| 96579 | + } |
| 96292 | 96580 | for(j=0; j<pGroupBy->nExpr; j++){ |
| 96293 | 96581 | if( groupBySort ){ |
| 96294 | | - sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j); |
| 96582 | + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); |
| 96583 | + if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 96295 | 96584 | }else{ |
| 96296 | 96585 | sAggInfo.directMode = 1; |
| 96297 | 96586 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); |
| 96298 | 96587 | } |
| 96299 | 96588 | } |
| | @@ -96328,14 +96617,14 @@ |
| 96328 | 96617 | VdbeComment((v, "indicate data in accumulator")); |
| 96329 | 96618 | |
| 96330 | 96619 | /* End of the loop |
| 96331 | 96620 | */ |
| 96332 | 96621 | if( groupBySort ){ |
| 96333 | | - sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); |
| 96622 | + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); |
| 96334 | 96623 | }else{ |
| 96335 | 96624 | sqlite3WhereEnd(pWInfo); |
| 96336 | | - sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); |
| 96625 | + sqlite3VdbeChangeToNoop(v, addrSortingIdx); |
| 96337 | 96626 | } |
| 96338 | 96627 | |
| 96339 | 96628 | /* Output the final row of result |
| 96340 | 96629 | */ |
| 96341 | 96630 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); |
| | @@ -100517,15 +100806,23 @@ |
| 100517 | 100806 | return mask; |
| 100518 | 100807 | } |
| 100519 | 100808 | static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ |
| 100520 | 100809 | Bitmask mask = 0; |
| 100521 | 100810 | while( pS ){ |
| 100811 | + SrcList *pSrc = pS->pSrc; |
| 100522 | 100812 | mask |= exprListTableUsage(pMaskSet, pS->pEList); |
| 100523 | 100813 | mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); |
| 100524 | 100814 | mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); |
| 100525 | 100815 | mask |= exprTableUsage(pMaskSet, pS->pWhere); |
| 100526 | 100816 | mask |= exprTableUsage(pMaskSet, pS->pHaving); |
| 100817 | + if( ALWAYS(pSrc!=0) ){ |
| 100818 | + int i; |
| 100819 | + for(i=0; i<pSrc->nSrc; i++){ |
| 100820 | + mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect); |
| 100821 | + mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn); |
| 100822 | + } |
| 100823 | + } |
| 100527 | 100824 | pS = pS->pPrior; |
| 100528 | 100825 | } |
| 100529 | 100826 | return mask; |
| 100530 | 100827 | } |
| 100531 | 100828 | |
| | @@ -102044,12 +102341,11 @@ |
| 102044 | 102341 | /* Generate code to skip over the creation and initialization of the |
| 102045 | 102342 | ** transient index on 2nd and subsequent iterations of the loop. */ |
| 102046 | 102343 | v = pParse->pVdbe; |
| 102047 | 102344 | assert( v!=0 ); |
| 102048 | 102345 | regIsInit = ++pParse->nMem; |
| 102049 | | - addrInit = sqlite3VdbeAddOp1(v, OP_If, regIsInit); |
| 102050 | | - sqlite3VdbeAddOp2(v, OP_Integer, 1, regIsInit); |
| 102346 | + addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); |
| 102051 | 102347 | |
| 102052 | 102348 | /* Count the number of columns that will be added to the index |
| 102053 | 102349 | ** and used to match WHERE clause constraints */ |
| 102054 | 102350 | nColumn = 0; |
| 102055 | 102351 | pTable = pSrc->pTab; |
| | @@ -115981,11 +116277,41 @@ |
| 115981 | 116277 | char *aOut; |
| 115982 | 116278 | int bFirstOut = 0; |
| 115983 | 116279 | |
| 115984 | 116280 | *paOut = 0; |
| 115985 | 116281 | *pnOut = 0; |
| 115986 | | - aOut = sqlite3_malloc(n1+n2); |
| 116282 | + |
| 116283 | + /* Allocate space for the output. Both the input and output doclists |
| 116284 | + ** are delta encoded. If they are in ascending order (bDescDoclist==0), |
| 116285 | + ** then the first docid in each list is simply encoded as a varint. For |
| 116286 | + ** each subsequent docid, the varint stored is the difference between the |
| 116287 | + ** current and previous docid (a positive number - since the list is in |
| 116288 | + ** ascending order). |
| 116289 | + ** |
| 116290 | + ** The first docid written to the output is therefore encoded using the |
| 116291 | + ** same number of bytes as it is in whichever of the input lists it is |
| 116292 | + ** read from. And each subsequent docid read from the same input list |
| 116293 | + ** consumes either the same or less bytes as it did in the input (since |
| 116294 | + ** the difference between it and the previous value in the output must |
| 116295 | + ** be a positive value less than or equal to the delta value read from |
| 116296 | + ** the input list). The same argument applies to all but the first docid |
| 116297 | + ** read from the 'other' list. And to the contents of all position lists |
| 116298 | + ** that will be copied and merged from the input to the output. |
| 116299 | + ** |
| 116300 | + ** However, if the first docid copied to the output is a negative number, |
| 116301 | + ** then the encoding of the first docid from the 'other' input list may |
| 116302 | + ** be larger in the output than it was in the input (since the delta value |
| 116303 | + ** may be a larger positive integer than the actual docid). |
| 116304 | + ** |
| 116305 | + ** The space required to store the output is therefore the sum of the |
| 116306 | + ** sizes of the two inputs, plus enough space for exactly one of the input |
| 116307 | + ** docids to grow. |
| 116308 | + ** |
| 116309 | + ** A symetric argument may be made if the doclists are in descending |
| 116310 | + ** order. |
| 116311 | + */ |
| 116312 | + aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); |
| 115987 | 116313 | if( !aOut ) return SQLITE_NOMEM; |
| 115988 | 116314 | |
| 115989 | 116315 | p = aOut; |
| 115990 | 116316 | fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); |
| 115991 | 116317 | fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); |
| | @@ -116008,10 +116334,11 @@ |
| 116008 | 116334 | } |
| 116009 | 116335 | } |
| 116010 | 116336 | |
| 116011 | 116337 | *paOut = aOut; |
| 116012 | 116338 | *pnOut = (p-aOut); |
| 116339 | + assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); |
| 116013 | 116340 | return SQLITE_OK; |
| 116014 | 116341 | } |
| 116015 | 116342 | |
| 116016 | 116343 | /* |
| 116017 | 116344 | ** This function does a "phrase" merge of two doclists. In a phrase merge, |
| 116018 | 116345 | |