Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add 'Changes' property to the connection class. Also, update the core SQLite library to the latest trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3a02749d711e236180c184187c9528fe |
User & Date: | mistachkin 2011-09-18 22:39:35.950 |
Context
2011-09-20
| ||
17:34 | Update core SQLite to 3.7.8 release. check-in: 2fa7c53d4e user: mistachkin tags: trunk | |
2011-09-18
| ||
22:39 | Add 'Changes' property to the connection class. Also, update the core SQLite library to the latest trunk. check-in: 3a02749d71 user: mistachkin tags: trunk | |
2011-09-16
| ||
03:37 | In the test for ticket [b4a7ddc83f], brace all substituted values in the setup script just in case they may ever contain spaces. check-in: b1727a9afb user: mistachkin tags: trunk | |
Changes
Changes to SQLite.Interop/src/core/sqlite3.c.
︙ | ︙ | |||
654 655 656 657 658 659 660 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.8" #define SQLITE_VERSION_NUMBER 3007008 | | | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.8" #define SQLITE_VERSION_NUMBER 3007008 #define SQLITE_SOURCE_ID "2011-09-17 15:34:50 29c4d0dd43d41650e54824afd70dd40f1b91cc86" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
7630 7631 7632 7633 7634 7635 7636 | ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified ** on the command-line */ #ifndef SQLITE_TEMP_STORE # define SQLITE_TEMP_STORE 1 #endif | < < < < < < < < | 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 | ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified ** on the command-line */ #ifndef SQLITE_TEMP_STORE # define SQLITE_TEMP_STORE 1 #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif |
︙ | ︙ | |||
7980 7981 7982 7983 7984 7985 7986 | ** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ | < | 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 | ** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ #define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ #define BTREE_MEMORY 4 /* This is an in-memory DB */ #define BTREE_SINGLE 8 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 16 /* Use of a hash implementation is OK */ SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int); SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*); SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); |
︙ | ︙ | |||
8381 8382 8383 8384 8385 8386 8387 | #define OP_Permutation 23 #define OP_Compare 24 #define OP_Jump 25 #define OP_And 69 /* same as TK_AND */ #define OP_Or 68 /* same as TK_OR */ #define OP_Not 19 /* same as TK_NOT */ #define OP_BitNot 93 /* same as TK_BITNOT */ | > | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | > > | | | | | > | | > | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < | | | | | | | | > | | | | | < | | 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 | #define OP_Permutation 23 #define OP_Compare 24 #define OP_Jump 25 #define OP_And 69 /* same as TK_AND */ #define OP_Or 68 /* same as TK_OR */ #define OP_Not 19 /* same as TK_NOT */ #define OP_BitNot 93 /* same as TK_BITNOT */ #define OP_Once 26 #define OP_If 27 #define OP_IfNot 28 #define OP_IsNull 73 /* same as TK_ISNULL */ #define OP_NotNull 74 /* same as TK_NOTNULL */ #define OP_Column 29 #define OP_Affinity 30 #define OP_MakeRecord 31 #define OP_Count 32 #define OP_Savepoint 33 #define OP_AutoCommit 34 #define OP_Transaction 35 #define OP_ReadCookie 36 #define OP_SetCookie 37 #define OP_VerifyCookie 38 #define OP_OpenRead 39 #define OP_OpenWrite 40 #define OP_OpenAutoindex 41 #define OP_OpenEphemeral 42 #define OP_SorterOpen 43 #define OP_OpenPseudo 44 #define OP_Close 45 #define OP_SeekLt 46 #define OP_SeekLe 47 #define OP_SeekGe 48 #define OP_SeekGt 49 #define OP_Seek 50 #define OP_NotFound 51 #define OP_Found 52 #define OP_IsUnique 53 #define OP_NotExists 54 #define OP_Sequence 55 #define OP_NewRowid 56 #define OP_Insert 57 #define OP_InsertInt 58 #define OP_Delete 59 #define OP_ResetCount 60 #define OP_SorterCompare 61 #define OP_SorterData 62 #define OP_RowKey 63 #define OP_RowData 64 #define OP_Rowid 65 #define OP_NullRow 66 #define OP_Last 67 #define OP_SorterSort 70 #define OP_Sort 71 #define OP_Rewind 72 #define OP_SorterNext 81 #define OP_Prev 92 #define OP_Next 95 #define OP_SorterInsert 96 #define OP_IdxInsert 97 #define OP_IdxDelete 98 #define OP_IdxRowid 99 #define OP_IdxLT 100 #define OP_IdxGE 101 #define OP_Destroy 102 #define OP_Clear 103 #define OP_CreateIndex 104 #define OP_CreateTable 105 #define OP_ParseSchema 106 #define OP_LoadAnalysis 107 #define OP_DropTable 108 #define OP_DropIndex 109 #define OP_DropTrigger 110 #define OP_IntegrityCk 111 #define OP_RowSetAdd 112 #define OP_RowSetRead 113 #define OP_RowSetTest 114 #define OP_Program 115 #define OP_Param 116 #define OP_FkCounter 117 #define OP_FkIfZero 118 #define OP_MemMax 119 #define OP_IfPos 120 #define OP_IfNeg 121 #define OP_IfZero 122 #define OP_AggStep 123 #define OP_AggFinal 124 #define OP_Checkpoint 125 #define OP_JournalMode 126 #define OP_Vacuum 127 #define OP_IncrVacuum 128 #define OP_Expire 129 #define OP_TableLock 131 #define OP_VBegin 132 #define OP_VCreate 133 #define OP_VDestroy 134 #define OP_VOpen 135 #define OP_VFilter 136 #define OP_VColumn 137 #define OP_VNext 138 #define OP_VRename 139 #define OP_VUpdate 140 #define OP_Pagecount 146 #define OP_MaxPgcnt 147 #define OP_Trace 148 #define OP_Noop 149 #define OP_Explain 150 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ #define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */ #define OPFLG_IN1 0x0004 /* in1: P1 is an input */ #define OPFLG_IN2 0x0008 /* in2: P2 is an input */ #define OPFLG_IN3 0x0010 /* in3: P3 is an input */ #define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x01, 0x05, 0x04, 0x04, 0x10, 0x00, 0x02,\ /* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\ /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\ /* 24 */ 0x00, 0x01, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00,\ /* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\ /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\ /* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\ /* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\ /* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ /* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\ /* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ /* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ /* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\ /* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\ /* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,} /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. |
︙ | ︙ | |||
8532 8533 8534 8535 8536 8537 8538 | SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); | | | 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 | SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr); SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
︙ | ︙ | |||
8564 8565 8566 8567 8568 8569 8570 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif | | < > | 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); #endif #ifndef NDEBUG |
︙ | ︙ | |||
8747 8748 8749 8750 8751 8752 8753 | SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*); SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); | < < < | 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 | SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*); SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); /* Functions used to truncate the database file. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); #endif |
︙ | ︙ | |||
10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 | */ struct AggInfo { u8 directMode; /* Direct rendering mode means take data directly ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ int sortingIdx; /* Cursor number of the sorting index */ ExprList *pGroupBy; /* The group by clause */ int nSortingColumn; /* Number of columns in the sorting index */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ int iTable; /* Cursor number of the source table */ int iColumn; /* Column number within the source table */ int iSorterColumn; /* Column number in the sorting index */ | > | 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 | */ struct AggInfo { u8 directMode; /* Direct rendering mode means take data directly ** from source tables rather than from accumulators */ u8 useSortingIdx; /* In direct mode, reference the sorting index rather ** than the source table */ int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ ExprList *pGroupBy; /* The group by clause */ int nSortingColumn; /* Number of columns in the sorting index */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ int iTable; /* Cursor number of the source table */ int iColumn; /* Column number within the source table */ int iSorterColumn; /* Column number in the sorting index */ |
︙ | ︙ | |||
10493 10494 10495 10496 10497 10498 10499 | i16 nAlloc; /* Number of entries allocated in a[] below */ struct SrcList_item { char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ | | > | 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 | i16 nAlloc; /* Number of entries allocated in a[] below */ struct SrcList_item { char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ int addrFillSub; /* Address of subroutine to manifest a subquery */ int regReturn; /* Register holding return address of addrFillSub */ u8 jointype; /* Type of join between this able and the previous */ u8 notIndexed; /* True if there is a NOT INDEXED clause */ u8 isCorrelated; /* True if sub-query is correlated */ #ifndef SQLITE_OMIT_EXPLAIN u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ #endif int iCursor; /* The VDBE cursor number used to access this table */ |
︙ | ︙ | |||
10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 | */ #define SF_Distinct 0x0001 /* Output should be DISTINCT */ #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ /* ** The results of a select can be distributed in several ways. The ** "SRT" prefix means "SELECT Result Type". */ #define SRT_Union 1 /* Store result as keys in an index */ | > | 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 | */ #define SF_Distinct 0x0001 /* Output should be DISTINCT */ #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_UseSorter 0x0040 /* Sort using a sorter */ /* ** The results of a select can be distributed in several ways. The ** "SRT" prefix means "SELECT Result Type". */ #define SRT_Union 1 /* Store result as keys in an index */ |
︙ | ︙ | |||
12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 | Bool atFirst; /* True if pointing to first entry */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow; /* True if pointing to a row with no data */ Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool isTable; /* True if a table requiring integer keys */ Bool isIndex; /* True if an index containing keys only - no data */ Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ | > | | 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 | Bool atFirst; /* True if pointing to first entry */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow; /* True if pointing to a row with no data */ Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool isTable; /* True if a table requiring integer keys */ Bool isIndex; /* True if an index containing keys only - no data */ Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ Bool isSorter; /* True if a new-style sorter */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or ** OP_IsUnique opcode on this cursor. */ int seekResult; /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheStatus matches |
︙ | ︙ | |||
12945 12946 12947 12948 12949 12950 12951 12952 12953 | #ifdef SQLITE_OMIT_MERGE_SORT # define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterClose(Y,Z) # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK #else SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); | > < > > | | 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 | #ifdef SQLITE_OMIT_MERGE_SORT # define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterClose(Y,Z) # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK #else SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); #else # define sqlite3VdbeEnter(X) |
︙ | ︙ | |||
14538 14539 14540 14541 14542 14543 14544 | const char *zFile, sqlite3_file **ppFile, int flags, int *pOutFlags ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; | | | 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 | const char *zFile, sqlite3_file **ppFile, int flags, int *pOutFlags ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); if( pFile ){ rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ sqlite3_free(pFile); }else{ *ppFile = pFile; } |
︙ | ︙ | |||
22101 22102 22103 22104 22105 22106 22107 | /* 19 */ "Not", /* 20 */ "AddImm", /* 21 */ "MustBeInt", /* 22 */ "RealAffinity", /* 23 */ "Permutation", /* 24 */ "Compare", /* 25 */ "Jump", | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > | 22098 22099 22100 22101 22102 22103 22104 22105 22106 22107 22108 22109 22110 22111 22112 22113 22114 22115 22116 22117 22118 22119 22120 22121 22122 22123 22124 22125 22126 22127 22128 22129 22130 22131 22132 22133 22134 22135 22136 22137 22138 22139 22140 22141 22142 22143 22144 22145 22146 22147 22148 22149 22150 22151 22152 22153 22154 22155 22156 22157 22158 22159 22160 22161 22162 22163 22164 22165 22166 22167 22168 22169 22170 22171 22172 22173 22174 22175 22176 22177 22178 22179 22180 22181 22182 22183 22184 22185 22186 22187 22188 22189 22190 22191 22192 22193 22194 22195 22196 22197 22198 22199 22200 22201 22202 22203 22204 22205 22206 22207 22208 22209 22210 22211 22212 22213 22214 22215 22216 22217 22218 22219 22220 22221 22222 22223 22224 22225 22226 22227 22228 22229 22230 22231 22232 22233 22234 22235 22236 | /* 19 */ "Not", /* 20 */ "AddImm", /* 21 */ "MustBeInt", /* 22 */ "RealAffinity", /* 23 */ "Permutation", /* 24 */ "Compare", /* 25 */ "Jump", /* 26 */ "Once", /* 27 */ "If", /* 28 */ "IfNot", /* 29 */ "Column", /* 30 */ "Affinity", /* 31 */ "MakeRecord", /* 32 */ "Count", /* 33 */ "Savepoint", /* 34 */ "AutoCommit", /* 35 */ "Transaction", /* 36 */ "ReadCookie", /* 37 */ "SetCookie", /* 38 */ "VerifyCookie", /* 39 */ "OpenRead", /* 40 */ "OpenWrite", /* 41 */ "OpenAutoindex", /* 42 */ "OpenEphemeral", /* 43 */ "SorterOpen", /* 44 */ "OpenPseudo", /* 45 */ "Close", /* 46 */ "SeekLt", /* 47 */ "SeekLe", /* 48 */ "SeekGe", /* 49 */ "SeekGt", /* 50 */ "Seek", /* 51 */ "NotFound", /* 52 */ "Found", /* 53 */ "IsUnique", /* 54 */ "NotExists", /* 55 */ "Sequence", /* 56 */ "NewRowid", /* 57 */ "Insert", /* 58 */ "InsertInt", /* 59 */ "Delete", /* 60 */ "ResetCount", /* 61 */ "SorterCompare", /* 62 */ "SorterData", /* 63 */ "RowKey", /* 64 */ "RowData", /* 65 */ "Rowid", /* 66 */ "NullRow", /* 67 */ "Last", /* 68 */ "Or", /* 69 */ "And", /* 70 */ "SorterSort", /* 71 */ "Sort", /* 72 */ "Rewind", /* 73 */ "IsNull", /* 74 */ "NotNull", /* 75 */ "Ne", /* 76 */ "Eq", /* 77 */ "Gt", /* 78 */ "Le", /* 79 */ "Lt", /* 80 */ "Ge", /* 81 */ "SorterNext", /* 82 */ "BitAnd", /* 83 */ "BitOr", /* 84 */ "ShiftLeft", /* 85 */ "ShiftRight", /* 86 */ "Add", /* 87 */ "Subtract", /* 88 */ "Multiply", /* 89 */ "Divide", /* 90 */ "Remainder", /* 91 */ "Concat", /* 92 */ "Prev", /* 93 */ "BitNot", /* 94 */ "String8", /* 95 */ "Next", /* 96 */ "SorterInsert", /* 97 */ "IdxInsert", /* 98 */ "IdxDelete", /* 99 */ "IdxRowid", /* 100 */ "IdxLT", /* 101 */ "IdxGE", /* 102 */ "Destroy", /* 103 */ "Clear", /* 104 */ "CreateIndex", /* 105 */ "CreateTable", /* 106 */ "ParseSchema", /* 107 */ "LoadAnalysis", /* 108 */ "DropTable", /* 109 */ "DropIndex", /* 110 */ "DropTrigger", /* 111 */ "IntegrityCk", /* 112 */ "RowSetAdd", /* 113 */ "RowSetRead", /* 114 */ "RowSetTest", /* 115 */ "Program", /* 116 */ "Param", /* 117 */ "FkCounter", /* 118 */ "FkIfZero", /* 119 */ "MemMax", /* 120 */ "IfPos", /* 121 */ "IfNeg", /* 122 */ "IfZero", /* 123 */ "AggStep", /* 124 */ "AggFinal", /* 125 */ "Checkpoint", /* 126 */ "JournalMode", /* 127 */ "Vacuum", /* 128 */ "IncrVacuum", /* 129 */ "Expire", /* 130 */ "Real", /* 131 */ "TableLock", /* 132 */ "VBegin", /* 133 */ "VCreate", /* 134 */ "VDestroy", /* 135 */ "VOpen", /* 136 */ "VFilter", /* 137 */ "VColumn", /* 138 */ "VNext", /* 139 */ "VRename", /* 140 */ "VUpdate", /* 141 */ "ToText", /* 142 */ "ToBlob", /* 143 */ "ToNumeric", /* 144 */ "ToInt", /* 145 */ "ToReal", /* 146 */ "Pagecount", /* 147 */ "MaxPgcnt", /* 148 */ "Trace", /* 149 */ "Noop", /* 150 */ "Explain", }; return azName[i]; } #endif /************** End of opcodes.c *********************************************/ /************** Begin file os_os2.c ******************************************/ |
︙ | ︙ | |||
32796 32797 32798 32799 32800 32801 32802 | SQLITE_API int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. */ static int winSync(sqlite3_file *id, int flags){ | > > > > > > | > > > > > < | 32798 32799 32800 32801 32802 32803 32804 32805 32806 32807 32808 32809 32810 32811 32812 32813 32814 32815 32816 32817 32818 32819 32820 32821 32822 32823 32824 | SQLITE_API int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. */ static int winSync(sqlite3_file *id, int flags){ #ifndef SQLITE_NO_SYNC /* ** Used only when SQLITE_NO_SYNC is not defined. */ BOOL rc; #endif #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ (defined(SQLITE_TEST) && defined(SQLITE_DEBUG)) /* ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or ** OSTRACE() macros. */ winFile *pFile = (winFile*)id; #else UNUSED_PARAMETER(id); #endif assert( pFile ); /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ assert((flags&0x0F)==SQLITE_SYNC_NORMAL |
︙ | ︙ | |||
38138 38139 38140 38141 38142 38143 38144 | u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ u8 hasSeenStress; /* pagerStress() called one or more times */ | < | 38150 38151 38152 38153 38154 38155 38156 38157 38158 38159 38160 38161 38162 38163 | u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ u8 hasSeenStress; /* pagerStress() called one or more times */ /************************************************************************** ** The following block contains those class members that change during ** routine opertion. Class members not in this block are either fixed ** when the pager is first created or else only change when there is a ** significant mode change (such as changing the page_size, locking_mode, ** or the journal_mode). From another view, these class members describe |
︙ | ︙ | |||
38362 38363 38364 38365 38366 38367 38368 | assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_MEMORY ); assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); assert( pagerUseWal(p)==0 ); } | < < < < < < < < < | 38373 38374 38375 38376 38377 38378 38379 38380 38381 38382 38383 38384 38385 38386 | assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_MEMORY ); assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); assert( pagerUseWal(p)==0 ); } /* If changeCountDone is set, a RESERVED lock or greater must be held ** on the file. */ assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); assert( p->eLock!=PENDING_LOCK ); switch( p->eState ){ |
︙ | ︙ | |||
42074 42075 42076 42077 42078 42079 42080 | }else if( memDb ){ pPager->journalMode = PAGER_JOURNALMODE_MEMORY; } /* pPager->xBusyHandler = 0; */ /* pPager->pBusyHandlerArg = 0; */ pPager->xReiniter = xReinit; /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ | < < < < < < | 42076 42077 42078 42079 42080 42081 42082 42083 42084 42085 42086 42087 42088 42089 | }else if( memDb ){ pPager->journalMode = PAGER_JOURNALMODE_MEMORY; } /* pPager->xBusyHandler = 0; */ /* pPager->pBusyHandlerArg = 0; */ pPager->xReiniter = xReinit; /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; return SQLITE_OK; } |
︙ | ︙ | |||
43624 43625 43626 43627 43628 43629 43630 | /* ** Return true if this is an in-memory pager. */ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ return MEMDB; } | < < < < < < < < < < < | 43620 43621 43622 43623 43624 43625 43626 43627 43628 43629 43630 43631 43632 43633 | /* ** Return true if this is an in-memory pager. */ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ return MEMDB; } /* ** Check that there are at least nSavepoint savepoints open. If there are ** currently less than nSavepoints open, then open one or more savepoints ** to make up the difference. If the number of savepoints is already ** equal to nSavepoint, then this function is a no-op. ** ** If a memory allocation fails, SQLITE_NOMEM is returned. If an error |
︙ | ︙ | |||
48925 48926 48927 48928 48929 48930 48931 48932 48933 48934 | i64 nKey, /* Integer key for tables. Size of pKey for indices */ int bias, /* Bias search to the high end */ int *pRes /* Write search results here */ ){ int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ if( pKey ){ assert( nKey==(i64)(int)nKey ); | > | | > > | | | 48910 48911 48912 48913 48914 48915 48916 48917 48918 48919 48920 48921 48922 48923 48924 48925 48926 48927 48928 48929 48930 48931 48932 48933 48934 48935 48936 48937 48938 | i64 nKey, /* Integer key for tables. Size of pKey for indices */ int bias, /* Bias search to the high end */ int *pRes /* Write search results here */ ){ int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ char *pFree = 0; if( pKey ){ assert( nKey==(i64)(int)nKey ); pIdxKey = sqlite3VdbeAllocUnpackedRecord( pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree ); if( pIdxKey==0 ) return SQLITE_NOMEM; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); }else{ pIdxKey = 0; } rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); if( pFree ){ sqlite3DbFree(pCur->pKeyInfo->db, pFree); } return rc; } /* ** Restore the cursor to the position it was in (or as close to as possible) ** when saveCursorPosition() was called. Note that this call deletes the |
︙ | ︙ | |||
50003 50004 50005 50006 50007 50008 50009 | /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ assert( (flags & BTREE_SINGLE)==0 || isTempDb ); | < < < < < < < < < < < | 49991 49992 49993 49994 49995 49996 49997 49998 49999 50000 50001 50002 50003 50004 50005 50006 50007 50008 50009 | /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ assert( (flags & BTREE_SINGLE)==0 || isTempDb ); if( db->flags & SQLITE_NoReadlock ){ flags |= BTREE_NO_READLOCK; } if( isMemdb ){ flags |= BTREE_MEMORY; } if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; } p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM; |
︙ | ︙ | |||
55565 55566 55567 55568 55569 55570 55571 | */ zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); releasePage(pPage); } return rc; } SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ | < < < < < < | < | 55542 55543 55544 55545 55546 55547 55548 55549 55550 55551 55552 55553 55554 55555 55556 55557 55558 | */ zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); releasePage(pPage); } return rc; } SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ int rc; sqlite3BtreeEnter(p); rc = btreeDropTable(p, iTable, piMoved); sqlite3BtreeLeave(p); return rc; } /* ** This function may only be called if the b-tree connection already |
︙ | ︙ | |||
58763 58764 58765 58766 58767 58768 58769 | }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); assert( pOp[-1].opcode==OP_Integer ); n = pOp[-1].p1; if( n>nMaxArgs ) nMaxArgs = n; #endif | | | 58733 58734 58735 58736 58737 58738 58739 58740 58741 58742 58743 58744 58745 58746 58747 | }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); assert( pOp[-1].opcode==OP_Integer ); n = pOp[-1].p1; if( n>nMaxArgs ) nMaxArgs = n; #endif }else if( opcode==OP_Next || opcode==OP_SorterNext ){ pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; }else if( opcode==OP_Prev ){ pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; } |
︙ | ︙ | |||
59000 59001 59002 59003 59004 59005 59006 | */ SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ p->pNext = pVdbe->pProgram; pVdbe->pProgram = p; } /* | | | < | | | < < | 58970 58971 58972 58973 58974 58975 58976 58977 58978 58979 58980 58981 58982 58983 58984 58985 58986 58987 58988 58989 58990 58991 58992 | */ SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ p->pNext = pVdbe->pProgram; pVdbe->pProgram = p; } /* ** Change the opcode at addr into OP_Noop */ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ if( p->aOp ){ VdbeOp *pOp = &p->aOp[addr]; sqlite3 *db = p->db; freeP4(db, pOp->p4type, pOp->p4.p); memset(pOp, 0, sizeof(pOp[0])); pOp->opcode = OP_Noop; } } /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a ** static array using sqlite3VdbeAddOpList but we want to make a |
︙ | ︙ | |||
59167 59168 59169 59170 59171 59172 59173 | ** having to double-check to make sure that the result is non-negative. But ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to ** check the value of p->nOp-1 before continuing. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ | | | 59134 59135 59136 59137 59138 59139 59140 59141 59142 59143 59144 59145 59146 59147 59148 | ** having to double-check to make sure that the result is non-negative. But ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to ** check the value of p->nOp-1 before continuing. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ assert( p->magic==VDBE_MAGIC_INIT ); if( addr<0 ){ #ifdef SQLITE_OMIT_TRACE if( p->nOp==0 ) return (VdbeOp*)&dummy; #endif addr = p->nOp - 1; } |
︙ | ︙ | |||
61160 61161 61162 61163 61164 61165 61166 | } return len; } } return 0; } | < < | | > | > | | | > | < | | | < < | | > < | | < < | < < < | < | < < | | > | < | | > > > > | > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < | 61127 61128 61129 61130 61131 61132 61133 61134 61135 61136 61137 61138 61139 61140 61141 61142 61143 61144 61145 61146 61147 61148 61149 61150 61151 61152 61153 61154 61155 61156 61157 61158 61159 61160 61161 61162 61163 61164 61165 61166 61167 61168 61169 61170 61171 61172 61173 61174 61175 61176 61177 61178 61179 61180 61181 61182 61183 61184 61185 61186 61187 61188 61189 61190 61191 61192 61193 61194 61195 61196 61197 61198 61199 61200 61201 61202 61203 61204 61205 61206 61207 61208 61209 61210 61211 61212 61213 61214 61215 61216 61217 61218 61219 61220 61221 61222 | } return len; } } return 0; } /* ** This routine is used to allocate sufficient space for an UnpackedRecord ** structure large enough to be used with sqlite3VdbeRecordUnpack() if ** the first argument is a pointer to KeyInfo structure pKeyInfo. ** ** The space is either allocated using sqlite3DbMallocRaw() or from within ** the unaligned buffer passed via the second and third arguments (presumably ** stack space). If the former, then *ppFree is set to a pointer that should ** be eventually freed by the caller using sqlite3DbFree(). Or, if the ** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL ** before returning. ** ** If an OOM error occurs, NULL is returned. */ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( KeyInfo *pKeyInfo, /* Description of the record */ char *pSpace, /* Unaligned space available */ int szSpace, /* Size of pSpace[] in bytes */ char **ppFree /* OUT: Caller should free this pointer */ ){ UnpackedRecord *p; /* Unpacked record to return */ int nOff; /* Increment pSpace by nOff to align it */ int nByte; /* Number of bytes required for *p */ /* We want to shift the pointer pSpace up such that it is 8-byte aligned. ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift ** it by. If pSpace is already 8-byte aligned, nOff should be zero. */ nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); if( nByte>szSpace+nOff ){ p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); *ppFree = (char *)p; if( !p ) return 0; }else{ p = (UnpackedRecord*)&pSpace[nOff]; *ppFree = 0; } p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nField + 1; return p; } /* ** Given the nKey-byte encoding of a record in pKey[], populate the ** UnpackedRecord structure indicated by the fourth argument with the ** contents of the decoded record. */ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( KeyInfo *pKeyInfo, /* Information about the record format */ int nKey, /* Size of the binary record */ const void *pKey, /* The binary record */ UnpackedRecord *p /* Populate this structure before returning. */ ){ const unsigned char *aKey = (const unsigned char *)pKey; int d; u32 idx; /* Offset in aKey[] to read from */ u16 u; /* Unsigned loop counter */ u32 szHdr; Mem *pMem = p->aMem; p->flags = 0; assert( EIGHT_BYTE_ALIGNMENT(pMem) ); idx = getVarint32(aKey, szHdr); d = szHdr; u = 0; while( idx<szHdr && u<p->nField && d<=nKey ){ u32 serial_type; idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->zMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; u++; } assert( u<=pKeyInfo->nField + 1 ); p->nField = u; } /* ** This function compares the two table rows or index records ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero ** or positive integer if key1 is less than, equal to or ** greater than key2. The {nKey1, pKey1} key must be a blob |
︙ | ︙ | |||
63876 63877 63878 63879 63880 63881 63882 63883 63884 | Btree *pX; VdbeCursor *pCur; Db *pDb; } aw; struct OP_OpenEphemeral_stack_vars { VdbeCursor *pCx; } ax; struct OP_OpenPseudo_stack_vars { VdbeCursor *pCx; | > > > | | | > | | | | | | > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 63831 63832 63833 63834 63835 63836 63837 63838 63839 63840 63841 63842 63843 63844 63845 63846 63847 63848 63849 63850 63851 63852 63853 63854 63855 63856 63857 63858 63859 63860 63861 63862 63863 63864 63865 63866 63867 63868 63869 63870 63871 63872 63873 63874 63875 63876 63877 63878 63879 63880 63881 63882 63883 63884 63885 63886 63887 63888 63889 63890 63891 63892 63893 63894 63895 63896 63897 63898 63899 63900 63901 63902 63903 63904 63905 63906 63907 63908 63909 63910 63911 63912 63913 63914 63915 63916 63917 63918 63919 63920 63921 63922 63923 63924 63925 63926 63927 63928 63929 63930 63931 63932 63933 63934 63935 63936 63937 63938 63939 63940 63941 63942 63943 63944 63945 63946 63947 63948 63949 63950 63951 63952 63953 63954 63955 63956 63957 63958 63959 63960 63961 63962 63963 63964 63965 63966 63967 63968 63969 63970 63971 63972 63973 63974 63975 63976 63977 63978 63979 63980 63981 63982 63983 63984 63985 63986 63987 63988 63989 63990 63991 63992 63993 63994 63995 63996 63997 63998 63999 64000 64001 64002 64003 64004 64005 64006 64007 64008 64009 64010 64011 64012 64013 64014 64015 64016 64017 64018 64019 64020 64021 64022 64023 64024 64025 64026 64027 64028 64029 64030 64031 64032 64033 64034 64035 64036 64037 64038 64039 64040 64041 64042 64043 64044 64045 64046 64047 64048 64049 64050 64051 64052 64053 64054 64055 64056 64057 64058 64059 64060 64061 64062 64063 64064 64065 64066 64067 64068 64069 64070 64071 64072 64073 64074 64075 64076 64077 64078 64079 64080 64081 64082 64083 64084 64085 64086 64087 64088 64089 64090 64091 64092 64093 64094 64095 64096 | Btree *pX; VdbeCursor *pCur; Db *pDb; } aw; struct OP_OpenEphemeral_stack_vars { VdbeCursor *pCx; } ax; struct OP_SorterOpen_stack_vars { VdbeCursor *pCx; } ay; struct OP_OpenPseudo_stack_vars { VdbeCursor *pCx; } az; struct OP_SeekGt_stack_vars { int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ } ba; struct OP_Seek_stack_vars { VdbeCursor *pC; } bb; struct OP_Found_stack_vars { int alreadyExists; VdbeCursor *pC; int res; char *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; } bc; struct OP_IsUnique_stack_vars { u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; u16 nField; Mem *aMx; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ } bd; struct OP_NotExists_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; } be; struct OP_NewRowid_stack_vars { i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ } bf; struct OP_InsertInt_stack_vars { Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; /* Cursor to table into which insert is written */ int nZero; /* Number of zero-bytes to append */ int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ } bg; struct OP_Delete_stack_vars { i64 iKey; VdbeCursor *pC; } bh; struct OP_SorterCompare_stack_vars { VdbeCursor *pC; int res; } bi; struct OP_SorterData_stack_vars { VdbeCursor *pC; } bj; struct OP_RowData_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; } bk; struct OP_Rowid_stack_vars { VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; } bl; struct OP_NullRow_stack_vars { VdbeCursor *pC; } bm; struct OP_Last_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; } bn; struct OP_Rewind_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; } bo; struct OP_Next_stack_vars { VdbeCursor *pC; int res; } bp; struct OP_IdxInsert_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; } bq; struct OP_IdxDelete_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; UnpackedRecord r; } br; struct OP_IdxRowid_stack_vars { BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; } bs; struct OP_IdxGE_stack_vars { VdbeCursor *pC; int res; UnpackedRecord r; } bt; struct OP_Destroy_stack_vars { int iMoved; int iCnt; Vdbe *pVdbe; int iDb; } bu; struct OP_Clear_stack_vars { int nChange; } bv; struct OP_CreateTable_stack_vars { int pgno; int flags; Db *pDb; } bw; struct OP_ParseSchema_stack_vars { int iDb; const char *zMaster; char *zSql; InitData initData; } bx; struct OP_IntegrityCk_stack_vars { int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ } by; struct OP_RowSetRead_stack_vars { i64 val; } bz; struct OP_RowSetTest_stack_vars { int iSet; int exists; } ca; struct OP_Program_stack_vars { int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ Mem *pMem; /* Used to iterate through memory cells */ Mem *pEnd; /* Last memory cell in new array */ VdbeFrame *pFrame; /* New vdbe frame to execute in */ SubProgram *pProgram; /* Sub-program to execute */ void *t; /* Token identifying trigger */ } cb; struct OP_Param_stack_vars { VdbeFrame *pFrame; Mem *pIn; } cc; struct OP_MemMax_stack_vars { Mem *pIn1; VdbeFrame *pFrame; } cd; struct OP_AggStep_stack_vars { int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; } ce; struct OP_AggFinal_stack_vars { Mem *pMem; } cf; struct OP_Checkpoint_stack_vars { int i; /* Loop counter */ int aRes[3]; /* Results */ Mem *pMem; /* Write results here */ } cg; struct OP_JournalMode_stack_vars { Btree *pBt; /* Btree to change journal mode of */ Pager *pPager; /* Pager associated with pBt */ int eNew; /* New journal mode */ int eOld; /* The old journal mode */ const char *zFilename; /* Name of database file for pPager */ } ch; struct OP_IncrVacuum_stack_vars { Btree *pBt; } ci; struct OP_VBegin_stack_vars { VTable *pVTab; } cj; struct OP_VOpen_stack_vars { VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; } ck; struct OP_VFilter_stack_vars { int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; int i; Mem **apArg; } cl; struct OP_VColumn_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; } cm; struct OP_VNext_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; } cn; struct OP_VRename_stack_vars { sqlite3_vtab *pVtab; Mem *pName; } co; struct OP_VUpdate_stack_vars { sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; } cp; struct OP_Trace_stack_vars { char *zTrace; char *z; } cq; } u; /* End automatically generated code ********************************************************************/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); if( p->rc==SQLITE_NOMEM ){ |
︙ | ︙ | |||
65586 65587 65588 65589 65590 65591 65592 65593 65594 65595 65596 65597 65598 65599 65600 65601 65602 65603 65604 65605 65606 65607 65608 65609 65610 65611 65612 65613 65614 65615 65616 65617 65618 65619 65620 65621 65622 65623 65624 65625 65626 65627 65628 65629 | sqlite3VdbeMemSetNull(pOut); }else{ sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); } break; } /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value ** is considered true if it is numeric and non-zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ #if 0 /* local variables moved into u.al */ int c; #endif /* local variables moved into u.al */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & MEM_Null ){ u.al.c = pOp->p3; }else{ #ifdef SQLITE_OMIT_FLOATING_POINT u.al.c = sqlite3VdbeIntValue(pIn1)!=0; #else u.al.c = sqlite3VdbeRealValue(pIn1)!=0.0; #endif if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c; } if( u.al.c ){ pc = pOp->p2-1; } break; } /* Opcode: IsNull P1 P2 * * * ** ** Jump to P2 if the value in register P1 is NULL. | > > > > > > > > > > > > > > > > > | 65552 65553 65554 65555 65556 65557 65558 65559 65560 65561 65562 65563 65564 65565 65566 65567 65568 65569 65570 65571 65572 65573 65574 65575 65576 65577 65578 65579 65580 65581 65582 65583 65584 65585 65586 65587 65588 65589 65590 65591 65592 65593 65594 65595 65596 65597 65598 65599 65600 65601 65602 65603 65604 65605 65606 65607 65608 65609 65610 65611 65612 | sqlite3VdbeMemSetNull(pOut); }else{ sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); } break; } /* Opcode: Once P1 P2 * * * ** ** Jump to P2 if the value in register P1 is a not null or zero. If ** the value is NULL or zero, fall through and change the P1 register ** to an integer 1. ** ** When P1 is not used otherwise in a program, this opcode falls through ** once and jumps on all subsequent invocations. It is the equivalent ** of "OP_If P1 P2", followed by "OP_Integer 1 P1". */ /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value ** is considered true if it is numeric and non-zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ /* Opcode: IfNot P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is False. The value ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ case OP_Once: /* jump, in1 */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ #if 0 /* local variables moved into u.al */ int c; #endif /* local variables moved into u.al */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & MEM_Null ){ u.al.c = pOp->p3; }else{ #ifdef SQLITE_OMIT_FLOATING_POINT u.al.c = sqlite3VdbeIntValue(pIn1)!=0; #else u.al.c = sqlite3VdbeRealValue(pIn1)!=0.0; #endif if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c; } if( u.al.c ){ pc = pOp->p2-1; }else if( pOp->opcode==OP_Once ){ assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; pIn1->u.i = 1; REGISTER_TRACE(pOp->p1, pIn1); } break; } /* Opcode: IsNull P1 P2 * * * ** ** Jump to P2 if the value in register P1 is NULL. |
︙ | ︙ | |||
66751 66752 66753 66754 66755 66756 66757 | /* Opcode: OpenAutoindex P1 P2 * P4 * ** ** This opcode works the same as OP_OpenEphemeral. It has a ** different name to distinguish its use. Tables created using ** by this opcode will be used for automatically created transient ** indices in joins. */ | < < < < < < < < | 66734 66735 66736 66737 66738 66739 66740 66741 66742 66743 66744 66745 66746 66747 66748 66749 66750 66751 66752 66753 66754 66755 66756 66757 66758 66759 66760 | /* Opcode: OpenAutoindex P1 P2 * P4 * ** ** This opcode works the same as OP_OpenEphemeral. It has a ** different name to distinguish its use. Tables created using ** by this opcode will be used for automatically created transient ** indices in joins. */ case OP_OpenAutoindex: case OP_OpenEphemeral: { #if 0 /* local variables moved into u.ax */ VdbeCursor *pCx; #endif /* local variables moved into u.ax */ static const int vfsFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( u.ax.pCx==0 ) goto no_mem; u.ax.pCx->nullRow = 1; rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ax.pCx->pBt, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(u.ax.pCx->pBt, 1); |
︙ | ︙ | |||
66805 66806 66807 66808 66809 66810 66811 66812 | }else{ rc = sqlite3BtreeCursor(u.ax.pCx->pBt, MASTER_ROOT, 1, 0, u.ax.pCx->pCursor); u.ax.pCx->isTable = 1; } } u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); u.ax.pCx->isIndex = !u.ax.pCx->isTable; #ifndef SQLITE_OMIT_MERGE_SORT | > > > > > > > > > > > > > > > > > | | < > > > | | | | | | | | | 66780 66781 66782 66783 66784 66785 66786 66787 66788 66789 66790 66791 66792 66793 66794 66795 66796 66797 66798 66799 66800 66801 66802 66803 66804 66805 66806 66807 66808 66809 66810 66811 66812 66813 66814 66815 66816 66817 66818 66819 66820 66821 66822 66823 66824 66825 66826 66827 66828 66829 66830 66831 66832 66833 66834 66835 66836 66837 66838 66839 66840 66841 66842 66843 66844 66845 66846 66847 | }else{ rc = sqlite3BtreeCursor(u.ax.pCx->pBt, MASTER_ROOT, 1, 0, u.ax.pCx->pCursor); u.ax.pCx->isTable = 1; } } u.ax.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); u.ax.pCx->isIndex = !u.ax.pCx->isTable; break; } /* Opcode: OpenSorter P1 P2 * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens ** a transient index that is specifically designed to sort large ** tables using an external merge-sort algorithm. */ case OP_SorterOpen: { #if 0 /* local variables moved into u.ay */ VdbeCursor *pCx; #endif /* local variables moved into u.ay */ #ifndef SQLITE_OMIT_MERGE_SORT u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( u.ay.pCx==0 ) goto no_mem; u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo; u.ay.pCx->pKeyInfo->enc = ENC(p->db); u.ay.pCx->isSorter = 1; rc = sqlite3VdbeSorterInit(db, u.ay.pCx); #else pOp->opcode = OP_OpenEphemeral; pc--; #endif break; } /* Opcode: OpenPseudo P1 P2 P3 * * ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row in the content of memory ** register P2. In other words, cursor P1 becomes an alias for the ** MEM_Blob content contained in register P2. ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into ** individual columns using the OP_Column opcode. The OP_Column opcode ** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. */ case OP_OpenPseudo: { #if 0 /* local variables moved into u.az */ VdbeCursor *pCx; #endif /* local variables moved into u.az */ assert( pOp->p1>=0 ); u.az.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); if( u.az.pCx==0 ) goto no_mem; u.az.pCx->nullRow = 1; u.az.pCx->pseudoTableReg = pOp->p2; u.az.pCx->isTable = 1; u.az.pCx->isIndex = 0; break; } /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. |
︙ | ︙ | |||
66911 66912 66913 66914 66915 66916 66917 | ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 66905 66906 66907 66908 66909 66910 66911 66912 66913 66914 66915 66916 66917 66918 66919 66920 66921 66922 66923 66924 66925 66926 66927 66928 66929 66930 66931 66932 66933 66934 66935 66936 66937 66938 66939 66940 66941 66942 66943 66944 66945 66946 66947 66948 66949 66950 66951 66952 66953 66954 66955 66956 66957 66958 66959 66960 66961 66962 66963 66964 66965 66966 66967 66968 66969 66970 66971 66972 66973 66974 66975 66976 66977 66978 66979 66980 66981 66982 66983 66984 66985 66986 66987 66988 66989 66990 66991 66992 66993 66994 66995 66996 66997 66998 66999 67000 67001 67002 67003 67004 67005 67006 67007 67008 67009 67010 67011 67012 67013 67014 67015 67016 67017 67018 67019 67020 67021 67022 67023 67024 67025 67026 67027 67028 67029 67030 67031 67032 67033 67034 67035 67036 67037 67038 67039 67040 67041 67042 67043 67044 67045 67046 67047 67048 67049 67050 67051 67052 67053 67054 67055 67056 | ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ #if 0 /* local variables moved into u.ba */ int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ #endif /* local variables moved into u.ba */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); u.ba.pC = p->apCsr[pOp->p1]; assert( u.ba.pC!=0 ); assert( u.ba.pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); assert( u.ba.pC->isOrdered ); if( ALWAYS(u.ba.pC->pCursor!=0) ){ u.ba.oc = pOp->opcode; u.ba.pC->nullRow = 0; if( u.ba.pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ pIn3 = &aMem[pOp->p3]; applyNumericAffinity(pIn3); u.ba.iKey = sqlite3VdbeIntValue(pIn3); u.ba.pC->rowidIsValid = 0; /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (pIn3->flags & MEM_Int)==0 ){ if( (pIn3->flags & MEM_Real)==0 ){ /* If the P3 value cannot be converted into any kind of a number, ** then the seek is not possible, so jump to P2 */ pc = pOp->p2 - 1; break; } /* If we reach this point, then the P3 value must be a floating ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); if( u.ba.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.ba.iKey || pIn3->r>0) ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ u.ba.res = 1; if( pIn3->r<0 ){ if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); rc = sqlite3BtreeFirst(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ if( u.ba.oc<=OP_SeekLe ){ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); rc = sqlite3BtreeLast(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } if( u.ba.res ){ pc = pOp->p2 - 1; } break; }else if( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekGe ){ /* Use the ceiling() function to convert real->int */ if( pIn3->r > (double)u.ba.iKey ) u.ba.iKey++; }else{ /* Use the floor() function to convert real->int */ assert( u.ba.oc==OP_SeekLe || u.ba.oc==OP_SeekGt ); if( pIn3->r < (double)u.ba.iKey ) u.ba.iKey--; } } rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, 0, (u64)u.ba.iKey, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( u.ba.res==0 ){ u.ba.pC->rowidIsValid = 1; u.ba.pC->lastRowid = u.ba.iKey; } }else{ u.ba.nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( u.ba.nField>0 ); u.ba.r.pKeyInfo = u.ba.pC->pKeyInfo; u.ba.r.nField = (u16)u.ba.nField; /* The next line of code computes as follows, only faster: ** if( u.ba.oc==OP_SeekGt || u.ba.oc==OP_SeekLe ){ ** u.ba.r.flags = UNPACKED_INCRKEY; ** }else{ ** u.ba.r.flags = 0; ** } */ u.ba.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.ba.oc - OP_SeekLt))); assert( u.ba.oc!=OP_SeekGt || u.ba.r.flags==UNPACKED_INCRKEY ); assert( u.ba.oc!=OP_SeekLe || u.ba.r.flags==UNPACKED_INCRKEY ); assert( u.ba.oc!=OP_SeekGe || u.ba.r.flags==0 ); assert( u.ba.oc!=OP_SeekLt || u.ba.r.flags==0 ); u.ba.r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.ba.r.nField; i++) assert( memIsValid(&u.ba.r.aMem[i]) ); } #endif ExpandBlob(u.ba.r.aMem); rc = sqlite3BtreeMovetoUnpacked(u.ba.pC->pCursor, &u.ba.r, 0, 0, &u.ba.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } u.ba.pC->rowidIsValid = 0; } u.ba.pC->deferredMoveto = 0; u.ba.pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif if( u.ba.oc>=OP_SeekGe ){ assert( u.ba.oc==OP_SeekGe || u.ba.oc==OP_SeekGt ); if( u.ba.res<0 || (u.ba.res==0 && u.ba.oc==OP_SeekGt) ){ rc = sqlite3BtreeNext(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; u.ba.pC->rowidIsValid = 0; }else{ u.ba.res = 0; } }else{ assert( u.ba.oc==OP_SeekLt || u.ba.oc==OP_SeekLe ); if( u.ba.res>0 || (u.ba.res==0 && u.ba.oc==OP_SeekLt) ){ rc = sqlite3BtreePrevious(u.ba.pC->pCursor, &u.ba.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; u.ba.pC->rowidIsValid = 0; }else{ /* u.ba.res might be negative because the table is empty. Check to ** see if this is the case. */ u.ba.res = sqlite3BtreeEof(u.ba.pC->pCursor); } } assert( pOp->p2>0 ); if( u.ba.res ){ pc = pOp->p2 - 1; } }else{ /* This happens when attempting to open the sqlite3_master table ** for read access returns SQLITE_EMPTY. In this case always ** take the jump (since there are no records in the table). */ |
︙ | ︙ | |||
67071 67072 67073 67074 67075 67076 67077 | ** for P1 to move so that it points to the rowid given by P2. ** ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ | | | | | | | | | | | | 67065 67066 67067 67068 67069 67070 67071 67072 67073 67074 67075 67076 67077 67078 67079 67080 67081 67082 67083 67084 67085 67086 67087 67088 67089 67090 67091 67092 | ** for P1 to move so that it points to the rowid given by P2. ** ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ #if 0 /* local variables moved into u.bb */ VdbeCursor *pC; #endif /* local variables moved into u.bb */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bb.pC = p->apCsr[pOp->p1]; assert( u.bb.pC!=0 ); if( ALWAYS(u.bb.pC->pCursor!=0) ){ assert( u.bb.pC->isTable ); u.bb.pC->nullRow = 0; pIn2 = &aMem[pOp->p2]; u.bb.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); u.bb.pC->rowidIsValid = 0; u.bb.pC->deferredMoveto = 1; } break; } /* Opcode: Found P1 P2 P3 P4 * ** |
︙ | ︙ | |||
67116 67117 67118 67119 67120 67121 67122 | ** falls through to the next instruction and P1 is left pointing at the ** matching entry. ** ** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ | | > | | | | | | | | | | | | > > > > | < < < < | | | | | | | | | 67110 67111 67112 67113 67114 67115 67116 67117 67118 67119 67120 67121 67122 67123 67124 67125 67126 67127 67128 67129 67130 67131 67132 67133 67134 67135 67136 67137 67138 67139 67140 67141 67142 67143 67144 67145 67146 67147 67148 67149 67150 67151 67152 67153 67154 67155 67156 67157 67158 67159 67160 67161 67162 67163 67164 67165 67166 67167 67168 67169 67170 67171 67172 67173 67174 67175 67176 67177 67178 67179 67180 | ** falls through to the next instruction and P1 is left pointing at the ** matching entry. ** ** See also: Found, NotExists, IsUnique */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ #if 0 /* local variables moved into u.bc */ int alreadyExists; VdbeCursor *pC; int res; char *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; #endif /* local variables moved into u.bc */ #ifdef SQLITE_TEST sqlite3_found_count++; #endif u.bc.alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); u.bc.pC = p->apCsr[pOp->p1]; assert( u.bc.pC!=0 ); pIn3 = &aMem[pOp->p3]; if( ALWAYS(u.bc.pC->pCursor!=0) ){ assert( u.bc.pC->isTable==0 ); if( pOp->p4.i>0 ){ u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; u.bc.r.nField = (u16)pOp->p4.i; u.bc.r.aMem = pIn3; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); } #endif u.bc.r.flags = UNPACKED_PREFIX_MATCH; u.bc.pIdxKey = &u.bc.r; }else{ u.bc.pIdxKey = sqlite3VdbeAllocUnpackedRecord( u.bc.pC->pKeyInfo, u.bc.aTempRec, sizeof(u.bc.aTempRec), &u.bc.pFree ); if( u.bc.pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ sqlite3VdbeRecordUnpack(u.bc.pC->pKeyInfo, pIn3->n, pIn3->z, u.bc.pIdxKey); u.bc.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, u.bc.pIdxKey, 0, 0, &u.bc.res); if( pOp->p4.i==0 ){ sqlite3DbFree(db, u.bc.pFree); } if( rc!=SQLITE_OK ){ break; } u.bc.alreadyExists = (u.bc.res==0); u.bc.pC->deferredMoveto = 0; u.bc.pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ if( u.bc.alreadyExists ) pc = pOp->p2 - 1; }else{ if( !u.bc.alreadyExists ) pc = pOp->p2 - 1; } break; } /* Opcode: IsUnique P1 P2 P3 P4 * ** ** Cursor P1 is open on an index b-tree - that is to say, a btree which |
︙ | ︙ | |||
67203 67204 67205 67206 67207 67208 67209 | ** to instruction P2. Otherwise, the rowid of the conflicting index ** entry is copied to register P3 and control falls through to the next ** instruction. ** ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 67198 67199 67200 67201 67202 67203 67204 67205 67206 67207 67208 67209 67210 67211 67212 67213 67214 67215 67216 67217 67218 67219 67220 67221 67222 67223 67224 67225 67226 67227 67228 67229 67230 67231 67232 67233 67234 67235 67236 67237 67238 67239 67240 67241 67242 67243 67244 67245 67246 67247 67248 67249 67250 67251 67252 67253 67254 67255 67256 67257 67258 67259 67260 67261 67262 67263 67264 67265 67266 67267 67268 67269 67270 67271 67272 67273 67274 67275 67276 67277 67278 67279 67280 67281 67282 67283 67284 67285 67286 67287 67288 67289 67290 67291 67292 67293 67294 67295 67296 67297 67298 67299 67300 67301 67302 67303 67304 67305 67306 67307 67308 67309 67310 67311 67312 67313 67314 67315 67316 67317 67318 67319 67320 67321 67322 67323 67324 | ** to instruction P2. Otherwise, the rowid of the conflicting index ** entry is copied to register P3 and control falls through to the next ** instruction. ** ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ #if 0 /* local variables moved into u.bd */ u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; u16 nField; Mem *aMx; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ #endif /* local variables moved into u.bd */ pIn3 = &aMem[pOp->p3]; u.bd.aMx = &aMem[pOp->p4.i]; /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); /* Find the index cursor. */ u.bd.pCx = p->apCsr[pOp->p1]; assert( u.bd.pCx->deferredMoveto==0 ); u.bd.pCx->seekResult = 0; u.bd.pCx->cacheStatus = CACHE_STALE; u.bd.pCrsr = u.bd.pCx->pCursor; /* If any of the values are NULL, take the jump. */ u.bd.nField = u.bd.pCx->pKeyInfo->nField; for(u.bd.ii=0; u.bd.ii<u.bd.nField; u.bd.ii++){ if( u.bd.aMx[u.bd.ii].flags & MEM_Null ){ pc = pOp->p2 - 1; u.bd.pCrsr = 0; break; } } assert( (u.bd.aMx[u.bd.nField].flags & MEM_Null)==0 ); if( u.bd.pCrsr!=0 ){ /* Populate the index search key. */ u.bd.r.pKeyInfo = u.bd.pCx->pKeyInfo; u.bd.r.nField = u.bd.nField + 1; u.bd.r.flags = UNPACKED_PREFIX_SEARCH; u.bd.r.aMem = u.bd.aMx; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } #endif /* Extract the value of u.bd.R from register P3. */ sqlite3VdbeMemIntegerify(pIn3); u.bd.R = pIn3->u.i; /* Search the B-Tree index. If no conflicting record is found, jump ** to P2. Otherwise, copy the rowid of the conflicting record to ** register P3 and fall through to the next instruction. */ rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, &u.bd.r, 0, 0, &u.bd.pCx->seekResult); if( (u.bd.r.flags & UNPACKED_PREFIX_SEARCH) || u.bd.r.rowid==u.bd.R ){ pc = pOp->p2 - 1; }else{ pIn3->u.i = u.bd.r.rowid; } } break; } /* Opcode: NotExists P1 P2 P3 * * ** ** Use the content of register P3 as an integer key. If a record ** with that key does not exist in table of P1, then jump to P2. ** If the record does exist, then fall through. The cursor is left ** pointing to the record if it exists. ** ** The difference between this operation and NotFound is that this ** operation assumes the key is an integer and that P1 is a table whereas ** NotFound assumes key is a blob constructed from MakeRecord and ** P1 is an index. ** ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ #if 0 /* local variables moved into u.be */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; #endif /* local variables moved into u.be */ pIn3 = &aMem[pOp->p3]; assert( pIn3->flags & MEM_Int ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.be.pC = p->apCsr[pOp->p1]; assert( u.be.pC!=0 ); assert( u.be.pC->isTable ); assert( u.be.pC->pseudoTableReg==0 ); u.be.pCrsr = u.be.pC->pCursor; if( ALWAYS(u.be.pCrsr!=0) ){ u.be.res = 0; u.be.iKey = pIn3->u.i; rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, 0, u.be.iKey, 0, &u.be.res); u.be.pC->lastRowid = pIn3->u.i; u.be.pC->rowidIsValid = u.be.res==0 ?1:0; u.be.pC->nullRow = 0; u.be.pC->cacheStatus = CACHE_STALE; u.be.pC->deferredMoveto = 0; if( u.be.res!=0 ){ pc = pOp->p2 - 1; assert( u.be.pC->rowidIsValid==0 ); } u.be.pC->seekResult = u.be.res; }else{ /* This happens when an attempt to open a read cursor on the ** sqlite_master table returns SQLITE_EMPTY. */ pc = pOp->p2 - 1; assert( u.be.pC->rowidIsValid==0 ); u.be.pC->seekResult = 0; } break; } /* Opcode: Sequence P1 P2 * * * ** ** Find the next available sequence number for cursor P1. |
︙ | ︙ | |||
67350 67351 67352 67353 67354 67355 67356 | ** the largest previously generated record number. No new record numbers are ** allowed to be less than this value. When this value reaches its maximum, ** an SQLITE_FULL error is generated. The P3 register is updated with the ' ** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 67345 67346 67347 67348 67349 67350 67351 67352 67353 67354 67355 67356 67357 67358 67359 67360 67361 67362 67363 67364 67365 67366 67367 67368 67369 67370 67371 67372 67373 67374 67375 67376 67377 67378 67379 67380 67381 67382 67383 67384 67385 67386 67387 67388 67389 67390 67391 67392 67393 67394 67395 67396 67397 67398 67399 67400 67401 67402 67403 67404 67405 67406 67407 67408 67409 67410 67411 67412 67413 67414 67415 67416 67417 67418 67419 67420 67421 67422 67423 67424 67425 67426 67427 67428 67429 67430 67431 67432 67433 67434 67435 67436 67437 67438 67439 67440 67441 67442 67443 67444 67445 67446 67447 67448 67449 67450 67451 67452 67453 67454 67455 67456 67457 67458 67459 67460 67461 67462 67463 67464 67465 67466 67467 67468 67469 67470 67471 67472 67473 67474 67475 67476 67477 67478 67479 67480 67481 67482 67483 67484 67485 67486 67487 67488 67489 67490 67491 | ** the largest previously generated record number. No new record numbers are ** allowed to be less than this value. When this value reaches its maximum, ** an SQLITE_FULL error is generated. The P3 register is updated with the ' ** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ #if 0 /* local variables moved into u.bf */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ #endif /* local variables moved into u.bf */ u.bf.v = 0; u.bf.res = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bf.pC = p->apCsr[pOp->p1]; assert( u.bf.pC!=0 ); if( NEVER(u.bf.pC->pCursor==0) ){ /* The zero initialization above is all that is needed */ }else{ /* The next rowid or record number (different terms for the same ** thing) is obtained in a two-step algorithm. ** ** First we attempt to find the largest existing rowid and add one ** to that. But if the largest existing rowid is already the maximum ** positive integer, we have to fall through to the second ** probabilistic algorithm ** ** The second algorithm is to select a rowid at random and see if ** it already exists in the table. If it does not exist, we have ** succeeded. If the random rowid does exist, we select a new one ** and try again, up to 100 times. */ assert( u.bf.pC->isTable ); #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff #else /* Some compilers complain about constants of the form 0x7fffffffffffffff. ** Others complain about 0x7ffffffffffffffffLL. The following macro seems ** to provide the constant while making all compilers happy. */ # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) #endif if( !u.bf.pC->useRandomRowid ){ u.bf.v = sqlite3BtreeGetCachedRowid(u.bf.pC->pCursor); if( u.bf.v==0 ){ rc = sqlite3BtreeLast(u.bf.pC->pCursor, &u.bf.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( u.bf.res ){ u.bf.v = 1; /* IMP: R-61914-48074 */ }else{ assert( sqlite3BtreeCursorIsValid(u.bf.pC->pCursor) ); rc = sqlite3BtreeKeySize(u.bf.pC->pCursor, &u.bf.v); assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ if( u.bf.v==MAX_ROWID ){ u.bf.pC->useRandomRowid = 1; }else{ u.bf.v++; /* IMP: R-29538-34987 */ } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ /* Assert that P3 is a valid memory cell. */ assert( pOp->p3>0 ); if( p->pFrame ){ for(u.bf.pFrame=p->pFrame; u.bf.pFrame->pParent; u.bf.pFrame=u.bf.pFrame->pParent); /* Assert that P3 is a valid memory cell. */ assert( pOp->p3<=u.bf.pFrame->nMem ); u.bf.pMem = &u.bf.pFrame->aMem[pOp->p3]; }else{ /* Assert that P3 is a valid memory cell. */ assert( pOp->p3<=p->nMem ); u.bf.pMem = &aMem[pOp->p3]; memAboutToChange(p, u.bf.pMem); } assert( memIsValid(u.bf.pMem) ); REGISTER_TRACE(pOp->p3, u.bf.pMem); sqlite3VdbeMemIntegerify(u.bf.pMem); assert( (u.bf.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( u.bf.pMem->u.i==MAX_ROWID || u.bf.pC->useRandomRowid ){ rc = SQLITE_FULL; /* IMP: R-12275-61338 */ goto abort_due_to_error; } if( u.bf.v<u.bf.pMem->u.i+1 ){ u.bf.v = u.bf.pMem->u.i + 1; } u.bf.pMem->u.i = u.bf.v; } #endif sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, u.bf.v<MAX_ROWID ? u.bf.v+1 : 0); } if( u.bf.pC->useRandomRowid ){ /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the ** largest possible integer (9223372036854775807) then the database ** engine starts picking positive candidate ROWIDs at random until ** it finds one that is not previously used. */ assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is ** an AUTOINCREMENT table. */ /* on the first attempt, simply do one more than previous */ u.bf.v = lastRowid; u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ u.bf.v++; /* ensure non-zero */ u.bf.cnt = 0; while( ((rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, 0, (u64)u.bf.v, 0, &u.bf.res))==SQLITE_OK) && (u.bf.res==0) && (++u.bf.cnt<100)){ /* collision - try another random rowid */ sqlite3_randomness(sizeof(u.bf.v), &u.bf.v); if( u.bf.cnt<5 ){ /* try "small" random rowids for the initial attempts */ u.bf.v &= 0xffffff; }else{ u.bf.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ } u.bf.v++; /* ensure non-zero */ } if( rc==SQLITE_OK && u.bf.res==0 ){ rc = SQLITE_FULL; /* IMP: R-38219-53002 */ goto abort_due_to_error; } assert( u.bf.v>0 ); /* EV: R-40812-03570 */ } u.bf.pC->rowidIsValid = 0; u.bf.pC->deferredMoveto = 0; u.bf.pC->cacheStatus = CACHE_STALE; } pOut->u.i = u.bf.v; break; } /* Opcode: Insert P1 P2 P3 P4 P5 ** ** Write an entry into the table of cursor P1. A new entry is ** created if it doesn't already exist or the data for an existing |
︙ | ︙ | |||
67532 67533 67534 67535 67536 67537 67538 | /* Opcode: InsertInt P1 P2 P3 P4 P5 ** ** This works exactly like OP_Insert except that the key is the ** integer value P3, not the value of the integer stored in register P3. */ case OP_Insert: case OP_InsertInt: { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 67527 67528 67529 67530 67531 67532 67533 67534 67535 67536 67537 67538 67539 67540 67541 67542 67543 67544 67545 67546 67547 67548 67549 67550 67551 67552 67553 67554 67555 67556 67557 67558 67559 67560 67561 67562 67563 67564 67565 67566 67567 67568 67569 67570 67571 67572 67573 67574 67575 67576 67577 67578 67579 67580 67581 67582 67583 67584 67585 67586 67587 67588 67589 67590 67591 67592 67593 67594 67595 67596 67597 67598 67599 67600 67601 67602 67603 67604 | /* Opcode: InsertInt P1 P2 P3 P4 P5 ** ** This works exactly like OP_Insert except that the key is the ** integer value P3, not the value of the integer stored in register P3. */ case OP_Insert: case OP_InsertInt: { #if 0 /* local variables moved into u.bg */ Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; /* Cursor to table into which insert is written */ int nZero; /* Number of zero-bytes to append */ int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ #endif /* local variables moved into u.bg */ u.bg.pData = &aMem[pOp->p2]; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( memIsValid(u.bg.pData) ); u.bg.pC = p->apCsr[pOp->p1]; assert( u.bg.pC!=0 ); assert( u.bg.pC->pCursor!=0 ); assert( u.bg.pC->pseudoTableReg==0 ); assert( u.bg.pC->isTable ); REGISTER_TRACE(pOp->p2, u.bg.pData); if( pOp->opcode==OP_Insert ){ u.bg.pKey = &aMem[pOp->p3]; assert( u.bg.pKey->flags & MEM_Int ); assert( memIsValid(u.bg.pKey) ); REGISTER_TRACE(pOp->p3, u.bg.pKey); u.bg.iKey = u.bg.pKey->u.i; }else{ assert( pOp->opcode==OP_InsertInt ); u.bg.iKey = pOp->p3; } if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bg.iKey; if( u.bg.pData->flags & MEM_Null ){ u.bg.pData->z = 0; u.bg.pData->n = 0; }else{ assert( u.bg.pData->flags & (MEM_Blob|MEM_Str) ); } u.bg.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bg.pC->seekResult : 0); if( u.bg.pData->flags & MEM_Zero ){ u.bg.nZero = u.bg.pData->u.nZero; }else{ u.bg.nZero = 0; } sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); rc = sqlite3BtreeInsert(u.bg.pC->pCursor, 0, u.bg.iKey, u.bg.pData->z, u.bg.pData->n, u.bg.nZero, pOp->p5 & OPFLAG_APPEND, u.bg.seekResult ); u.bg.pC->rowidIsValid = 0; u.bg.pC->deferredMoveto = 0; u.bg.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ u.bg.zDb = db->aDb[u.bg.pC->iDb].zName; u.bg.zTbl = pOp->p4.z; u.bg.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); assert( u.bg.pC->isTable ); db->xUpdateCallback(db->pUpdateArg, u.bg.op, u.bg.zDb, u.bg.zTbl, u.bg.iKey); assert( u.bg.pC->iDb>=0 ); } break; } /* Opcode: Delete P1 P2 * P4 * ** ** Delete the record at which the P1 cursor is currently pointing. |
︙ | ︙ | |||
67621 67622 67623 67624 67625 67626 67627 | ** ** If P4 is not NULL, then it is the name of the table that P1 is ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { | | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 67616 67617 67618 67619 67620 67621 67622 67623 67624 67625 67626 67627 67628 67629 67630 67631 67632 67633 67634 67635 67636 67637 67638 67639 67640 67641 67642 67643 67644 67645 67646 67647 67648 67649 67650 67651 67652 67653 67654 67655 67656 67657 67658 67659 67660 67661 67662 67663 67664 67665 67666 67667 67668 67669 67670 67671 67672 67673 67674 67675 67676 67677 67678 67679 67680 67681 67682 67683 67684 67685 67686 67687 67688 67689 67690 67691 67692 67693 67694 67695 67696 67697 67698 67699 67700 67701 67702 67703 67704 67705 67706 67707 67708 67709 67710 67711 67712 67713 67714 67715 67716 67717 67718 67719 67720 67721 67722 67723 67724 67725 67726 67727 67728 67729 | ** ** If P4 is not NULL, then it is the name of the table that P1 is ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { #if 0 /* local variables moved into u.bh */ i64 iKey; VdbeCursor *pC; #endif /* local variables moved into u.bh */ u.bh.iKey = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bh.pC = p->apCsr[pOp->p1]; assert( u.bh.pC!=0 ); assert( u.bh.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ /* If the update-hook will be invoked, set u.bh.iKey to the rowid of the ** row being deleted. */ if( db->xUpdateCallback && pOp->p4.z ){ assert( u.bh.pC->isTable ); assert( u.bh.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ u.bh.iKey = u.bh.pC->lastRowid; } /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or ** OP_Column on the same table without any intervening operations that ** might move or invalidate the cursor. Hence cursor u.bh.pC is always pointing ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation ** below is always a no-op and cannot fail. We will run it anyhow, though, ** to guard against future changes to the code generator. **/ assert( u.bh.pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(u.bh.pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0); rc = sqlite3BtreeDelete(u.bh.pC->pCursor); u.bh.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ const char *zDb = db->aDb[u.bh.pC->iDb].zName; const char *zTbl = pOp->p4.z; db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bh.iKey); assert( u.bh.pC->iDb>=0 ); } if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } /* Opcode: ResetCount * * * * * ** ** The value of the change counter is copied to the database handle ** change counter (returned by subsequent calls to sqlite3_changes()). ** Then the VMs internal change counter resets to 0. ** This is used by trigger programs. */ case OP_ResetCount: { sqlite3VdbeSetChanges(db, p->nChange); p->nChange = 0; break; } /* Opcode: SorterCompare P1 P2 P3 ** ** P1 is a sorter cursor. This instruction compares the record blob in ** register P3 with the entry that the sorter cursor currently points to. ** If, excluding the rowid fields at the end, the two records are a match, ** fall through to the next instruction. Otherwise, jump to instruction P2. */ case OP_SorterCompare: { #if 0 /* local variables moved into u.bi */ VdbeCursor *pC; int res; #endif /* local variables moved into u.bi */ u.bi.pC = p->apCsr[pOp->p1]; assert( isSorter(u.bi.pC) ); pIn3 = &aMem[pOp->p3]; rc = sqlite3VdbeSorterCompare(u.bi.pC, pIn3, &u.bi.res); if( u.bi.res ){ pc = pOp->p2-1; } break; }; /* Opcode: SorterData P1 P2 * * * ** ** Write into register P2 the current sorter data for sorter cursor P1. */ case OP_SorterData: { #if 0 /* local variables moved into u.bj */ VdbeCursor *pC; #endif /* local variables moved into u.bj */ #ifndef SQLITE_OMIT_MERGE_SORT pOut = &aMem[pOp->p2]; u.bj.pC = p->apCsr[pOp->p1]; assert( u.bj.pC->isSorter ); rc = sqlite3VdbeSorterRowkey(u.bj.pC, pOut); #else pOp->opcode = OP_RowKey; pc--; #endif break; } /* Opcode: RowData P1 P2 * * * ** ** Write into register P2 the complete row data for cursor P1. ** There is no interpretation of the data. ** It is just copied onto the P2 register exactly as ** it is found in the database file. |
︙ | ︙ | |||
67701 67702 67703 67704 67705 67706 67707 | ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { | | | | > | | | | | | < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > | | | | > | | | | | | | | | | | | | 67739 67740 67741 67742 67743 67744 67745 67746 67747 67748 67749 67750 67751 67752 67753 67754 67755 67756 67757 67758 67759 67760 67761 67762 67763 67764 67765 67766 67767 67768 67769 67770 67771 67772 67773 67774 67775 67776 67777 67778 67779 67780 67781 67782 67783 67784 67785 67786 67787 67788 67789 67790 67791 67792 67793 67794 67795 67796 67797 67798 67799 67800 67801 67802 67803 67804 67805 67806 67807 67808 67809 67810 67811 67812 67813 67814 67815 67816 67817 67818 67819 67820 67821 67822 67823 67824 67825 67826 67827 67828 67829 67830 67831 67832 67833 67834 67835 67836 67837 67838 67839 67840 67841 67842 67843 67844 67845 67846 67847 67848 67849 67850 67851 67852 67853 67854 67855 67856 67857 67858 67859 67860 67861 67862 67863 67864 67865 67866 67867 67868 67869 67870 67871 67872 67873 67874 67875 67876 67877 67878 67879 67880 67881 67882 67883 67884 67885 67886 67887 67888 67889 67890 67891 67892 67893 67894 67895 67896 67897 67898 67899 67900 67901 67902 67903 67904 67905 67906 67907 67908 67909 67910 67911 67912 67913 67914 67915 67916 67917 67918 67919 67920 67921 67922 67923 67924 67925 67926 67927 67928 67929 67930 67931 67932 67933 67934 67935 67936 67937 67938 67939 67940 67941 67942 67943 67944 67945 67946 67947 67948 67949 67950 67951 67952 67953 67954 67955 67956 67957 67958 67959 67960 67961 67962 67963 67964 67965 67966 67967 67968 67969 67970 67971 67972 67973 67974 67975 67976 67977 67978 67979 67980 | ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { #if 0 /* local variables moved into u.bk */ VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; #endif /* local variables moved into u.bk */ pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bk.pC = p->apCsr[pOp->p1]; assert( u.bk.pC->isSorter==0 ); assert( u.bk.pC->isTable || pOp->opcode!=OP_RowData ); assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); assert( u.bk.pC!=0 ); assert( u.bk.pC->nullRow==0 ); assert( u.bk.pC->pseudoTableReg==0 ); assert( !u.bk.pC->isSorter ); assert( u.bk.pC->pCursor!=0 ); u.bk.pCrsr = u.bk.pC->pCursor; assert( sqlite3BtreeCursorIsValid(u.bk.pCrsr) ); /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or ** OP_Rewind/Op_Next with no intervening instructions that might invalidate ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always ** a no-op and can never fail. But we leave it in place as a safety. */ assert( u.bk.pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(u.bk.pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( u.bk.pC->isIndex ){ assert( !u.bk.pC->isTable ); rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } u.bk.n = (u32)u.bk.n64; }else{ rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ goto no_mem; } pOut->n = u.bk.n; MemSetTypeFlag(pOut, MEM_Blob); if( u.bk.pC->isIndex ){ rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); }else{ rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ UPDATE_MAX_BLOBSIZE(pOut); break; } /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. ** ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ #if 0 /* local variables moved into u.bl */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; #endif /* local variables moved into u.bl */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bl.pC = p->apCsr[pOp->p1]; assert( u.bl.pC!=0 ); assert( u.bl.pC->pseudoTableReg==0 ); if( u.bl.pC->nullRow ){ pOut->flags = MEM_Null; break; }else if( u.bl.pC->deferredMoveto ){ u.bl.v = u.bl.pC->movetoTarget; #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( u.bl.pC->pVtabCursor ){ u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; u.bl.pModule = u.bl.pVtab->pModule; assert( u.bl.pModule->xRowid ); rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); importVtabErrMsg(p, u.bl.pVtab); #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ assert( u.bl.pC->pCursor!=0 ); rc = sqlite3VdbeCursorMoveto(u.bl.pC); if( rc ) goto abort_due_to_error; if( u.bl.pC->rowidIsValid ){ u.bl.v = u.bl.pC->lastRowid; }else{ rc = sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ } } pOut->u.i = u.bl.v; break; } /* Opcode: NullRow P1 * * * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. */ case OP_NullRow: { #if 0 /* local variables moved into u.bm */ VdbeCursor *pC; #endif /* local variables moved into u.bm */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bm.pC = p->apCsr[pOp->p1]; assert( u.bm.pC!=0 ); u.bm.pC->nullRow = 1; u.bm.pC->rowidIsValid = 0; assert( u.bm.pC->pCursor || u.bm.pC->pVtabCursor ); if( u.bm.pC->pCursor ){ sqlite3BtreeClearCursor(u.bm.pC->pCursor); } break; } /* Opcode: Last P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Last: { /* jump */ #if 0 /* local variables moved into u.bn */ VdbeCursor *pC; BtCursor *pCrsr; int res; #endif /* local variables moved into u.bn */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bn.pC = p->apCsr[pOp->p1]; assert( u.bn.pC!=0 ); u.bn.pCrsr = u.bn.pC->pCursor; if( NEVER(u.bn.pCrsr==0) ){ u.bn.res = 1; }else{ rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); } u.bn.pC->nullRow = (u8)u.bn.res; u.bn.pC->deferredMoveto = 0; u.bn.pC->rowidIsValid = 0; u.bn.pC->cacheStatus = CACHE_STALE; if( pOp->p2>0 && u.bn.res ){ pc = pOp->p2 - 1; } break; } /* Opcode: Sort P1 P2 * * * ** ** This opcode does exactly the same thing as OP_Rewind except that ** it increments an undocumented global variable used for testing. ** ** Sorting is accomplished by writing records into a sorting index, ** then rewinding that index and playing it back from beginning to ** end. We use the OP_Sort opcode instead of OP_Rewind to do the ** rewinding so that the global variable will be incremented and ** regression tests can determine whether or not the optimizer is ** correctly optimizing out sorts. */ case OP_SorterSort: /* jump */ #ifdef SQLITE_OMIT_MERGE_SORT pOp->opcode = OP_Sort; #endif case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; #endif p->aCounter[SQLITE_STMTSTATUS_SORT-1]++; /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* jump */ #if 0 /* local variables moved into u.bo */ VdbeCursor *pC; BtCursor *pCrsr; int res; #endif /* local variables moved into u.bo */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bo.pC = p->apCsr[pOp->p1]; assert( u.bo.pC!=0 ); assert( u.bo.pC->isSorter==(pOp->opcode==OP_SorterSort) ); u.bo.res = 1; if( isSorter(u.bo.pC) ){ rc = sqlite3VdbeSorterRewind(db, u.bo.pC, &u.bo.res); }else{ u.bo.pCrsr = u.bo.pC->pCursor; assert( u.bo.pCrsr ); rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); u.bo.pC->atFirst = u.bo.res==0 ?1:0; u.bo.pC->deferredMoveto = 0; u.bo.pC->cacheStatus = CACHE_STALE; u.bo.pC->rowidIsValid = 0; } u.bo.pC->nullRow = (u8)u.bo.res; assert( pOp->p2>0 && pOp->p2<p->nOp ); if( u.bo.res ){ pc = pOp->p2 - 1; } break; } /* Opcode: Next P1 P2 * P4 P5 ** |
︙ | ︙ | |||
67966 67967 67968 67969 67970 67971 67972 67973 67974 | ** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ | > > > > | | | | > | | | | | | | | | | | > > > > | | | | > | | | > > > | | < < | | | | > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 68004 68005 68006 68007 68008 68009 68010 68011 68012 68013 68014 68015 68016 68017 68018 68019 68020 68021 68022 68023 68024 68025 68026 68027 68028 68029 68030 68031 68032 68033 68034 68035 68036 68037 68038 68039 68040 68041 68042 68043 68044 68045 68046 68047 68048 68049 68050 68051 68052 68053 68054 68055 68056 68057 68058 68059 68060 68061 68062 68063 68064 68065 68066 68067 68068 68069 68070 68071 68072 68073 68074 68075 68076 68077 68078 68079 68080 68081 68082 68083 68084 68085 68086 68087 68088 68089 68090 68091 68092 68093 68094 68095 68096 68097 68098 68099 68100 68101 68102 68103 68104 68105 68106 68107 68108 68109 68110 68111 68112 68113 68114 68115 68116 68117 68118 68119 68120 68121 68122 68123 68124 68125 68126 68127 68128 68129 68130 68131 68132 68133 68134 68135 68136 68137 68138 68139 68140 68141 68142 68143 68144 68145 68146 68147 68148 68149 68150 68151 68152 68153 68154 68155 68156 68157 68158 68159 68160 68161 68162 68163 68164 68165 68166 68167 68168 68169 68170 68171 68172 68173 68174 68175 68176 68177 68178 68179 68180 | ** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ case OP_SorterNext: /* jump */ #ifdef SQLITE_OMIT_MERGE_SORT pOp->opcode = OP_Next; #endif case OP_Prev: /* jump */ case OP_Next: { /* jump */ #if 0 /* local variables moved into u.bp */ VdbeCursor *pC; int res; #endif /* local variables moved into u.bp */ CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p5<=ArraySize(p->aCounter) ); u.bp.pC = p->apCsr[pOp->p1]; if( u.bp.pC==0 ){ break; /* See ticket #2273 */ } assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterNext) ); if( isSorter(u.bp.pC) ){ assert( pOp->opcode==OP_SorterNext ); rc = sqlite3VdbeSorterNext(db, u.bp.pC, &u.bp.res); }else{ u.bp.res = 1; assert( u.bp.pC->deferredMoveto==0 ); assert( u.bp.pC->pCursor ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); rc = pOp->p4.xAdvance(u.bp.pC->pCursor, &u.bp.res); } u.bp.pC->nullRow = (u8)u.bp.res; u.bp.pC->cacheStatus = CACHE_STALE; if( u.bp.res==0 ){ pc = pOp->p2 - 1; if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } u.bp.pC->rowidIsValid = 0; break; } /* Opcode: IdxInsert P1 P2 P3 * P5 ** ** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_SorterInsert: /* in2 */ #ifdef SQLITE_OMIT_MERGE_SORT pOp->opcode = OP_IdxInsert; #endif case OP_IdxInsert: { /* in2 */ #if 0 /* local variables moved into u.bq */ VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; #endif /* local variables moved into u.bq */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bq.pC = p->apCsr[pOp->p1]; assert( u.bq.pC!=0 ); assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); u.bq.pCrsr = u.bq.pC->pCursor; if( ALWAYS(u.bq.pCrsr!=0) ){ assert( u.bq.pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ if( isSorter(u.bq.pC) ){ rc = sqlite3VdbeSorterWrite(db, u.bq.pC, pIn2); }else{ u.bq.nKey = pIn2->n; u.bq.zKey = pIn2->z; rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) ); assert( u.bq.pC->deferredMoveto==0 ); u.bq.pC->cacheStatus = CACHE_STALE; } } } break; } /* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { #if 0 /* local variables moved into u.br */ VdbeCursor *pC; BtCursor *pCrsr; int res; UnpackedRecord r; #endif /* local variables moved into u.br */ assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.br.pC = p->apCsr[pOp->p1]; assert( u.br.pC!=0 ); u.br.pCrsr = u.br.pC->pCursor; if( ALWAYS(u.br.pCrsr!=0) ){ u.br.r.pKeyInfo = u.br.pC->pKeyInfo; u.br.r.nField = (u16)pOp->p3; u.br.r.flags = 0; u.br.r.aMem = &aMem[pOp->p2]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.br.r.nField; i++) assert( memIsValid(&u.br.r.aMem[i]) ); } #endif rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &u.br.r, 0, 0, &u.br.res); if( rc==SQLITE_OK && u.br.res==0 ){ rc = sqlite3BtreeDelete(u.br.pCrsr); } assert( u.br.pC->deferredMoveto==0 ); u.br.pC->cacheStatus = CACHE_STALE; } break; } /* Opcode: IdxRowid P1 P2 * * * ** ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ #if 0 /* local variables moved into u.bs */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; #endif /* local variables moved into u.bs */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bs.pC = p->apCsr[pOp->p1]; assert( u.bs.pC!=0 ); u.bs.pCrsr = u.bs.pC->pCursor; pOut->flags = MEM_Null; if( ALWAYS(u.bs.pCrsr!=0) ){ rc = sqlite3VdbeCursorMoveto(u.bs.pC); if( NEVER(rc) ) goto abort_due_to_error; assert( u.bs.pC->deferredMoveto==0 ); assert( u.bs.pC->isTable==0 ); if( !u.bs.pC->nullRow ){ rc = sqlite3VdbeIdxRowid(db, u.bs.pCrsr, &u.bs.rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pOut->u.i = u.bs.rowid; pOut->flags = MEM_Int; } } break; } /* Opcode: IdxGE P1 P2 P3 P4 P5 |
︙ | ︙ | |||
68152 68153 68154 68155 68156 68157 68158 | ** Otherwise fall through to the next instruction. ** ** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump */ case OP_IdxGE: { /* jump */ | | | | | | | | | | | | | | | | | | | 68201 68202 68203 68204 68205 68206 68207 68208 68209 68210 68211 68212 68213 68214 68215 68216 68217 68218 68219 68220 68221 68222 68223 68224 68225 68226 68227 68228 68229 68230 68231 68232 68233 68234 68235 68236 68237 68238 68239 68240 68241 68242 68243 68244 68245 68246 68247 | ** Otherwise fall through to the next instruction. ** ** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump */ case OP_IdxGE: { /* jump */ #if 0 /* local variables moved into u.bt */ VdbeCursor *pC; int res; UnpackedRecord r; #endif /* local variables moved into u.bt */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bt.pC = p->apCsr[pOp->p1]; assert( u.bt.pC!=0 ); assert( u.bt.pC->isOrdered ); if( ALWAYS(u.bt.pC->pCursor!=0) ){ assert( u.bt.pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; u.bt.r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; }else{ u.bt.r.flags = UNPACKED_IGNORE_ROWID; } u.bt.r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } #endif rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); if( pOp->opcode==OP_IdxLT ){ u.bt.res = -u.bt.res; }else{ assert( pOp->opcode==OP_IdxGE ); u.bt.res++; } if( u.bt.res>0 ){ pc = pOp->p2 - 1 ; } } break; } /* Opcode: Destroy P1 P2 P3 * * |
︙ | ︙ | |||
68212 68213 68214 68215 68216 68217 68218 | ** movement was required (because the table being dropped was already ** the last one in the database) then a zero is stored in register P2. ** If AUTOVACUUM is disabled then a zero is stored in register P2. ** ** See also: Clear */ case OP_Destroy: { /* out2-prerelease */ | | | | | | | | | | | | | | | | | | | 68261 68262 68263 68264 68265 68266 68267 68268 68269 68270 68271 68272 68273 68274 68275 68276 68277 68278 68279 68280 68281 68282 68283 68284 68285 68286 68287 68288 68289 68290 68291 68292 68293 68294 68295 68296 68297 68298 68299 68300 68301 68302 68303 68304 68305 68306 68307 | ** movement was required (because the table being dropped was already ** the last one in the database) then a zero is stored in register P2. ** If AUTOVACUUM is disabled then a zero is stored in register P2. ** ** See also: Clear */ case OP_Destroy: { /* out2-prerelease */ #if 0 /* local variables moved into u.bu */ int iMoved; int iCnt; Vdbe *pVdbe; int iDb; #endif /* local variables moved into u.bu */ #ifndef SQLITE_OMIT_VIRTUALTABLE u.bu.iCnt = 0; for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ u.bu.iCnt++; } } #else u.bu.iCnt = db->activeVdbeCnt; #endif pOut->flags = MEM_Null; if( u.bu.iCnt>1 ){ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ u.bu.iDb = pOp->p3; assert( u.bu.iCnt==1 ); assert( (p->btreeMask & (((yDbMask)1)<<u.bu.iDb))!=0 ); rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); pOut->flags = MEM_Int; pOut->u.i = u.bu.iMoved; #ifndef SQLITE_OMIT_AUTOVACUUM if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ sqlite3RootPageMoved(db, u.bu.iDb, u.bu.iMoved, pOp->p1); /* All OP_Destroy operations occur on the same btree */ assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bu.iDb+1 ); resetSchemaOnFault = u.bu.iDb+1; } #endif } break; } /* Opcode: Clear P1 P2 P3 |
︙ | ︙ | |||
68270 68271 68272 68273 68274 68275 68276 | ** count is incremented by the number of rows in the table being cleared. ** If P3 is greater than zero, then the value stored in register P3 is ** also incremented by the number of rows in the table being cleared. ** ** See also: Destroy */ case OP_Clear: { | | | | | | | | 68319 68320 68321 68322 68323 68324 68325 68326 68327 68328 68329 68330 68331 68332 68333 68334 68335 68336 68337 68338 68339 68340 68341 68342 68343 68344 68345 68346 68347 | ** count is incremented by the number of rows in the table being cleared. ** If P3 is greater than zero, then the value stored in register P3 is ** also incremented by the number of rows in the table being cleared. ** ** See also: Destroy */ case OP_Clear: { #if 0 /* local variables moved into u.bv */ int nChange; #endif /* local variables moved into u.bv */ u.bv.nChange = 0; assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); rc = sqlite3BtreeClearTable( db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) ); if( pOp->p3 ){ p->nChange += u.bv.nChange; if( pOp->p3>0 ){ assert( memIsValid(&aMem[pOp->p3]) ); memAboutToChange(p, &aMem[pOp->p3]); aMem[pOp->p3].u.i += u.bv.nChange; } } break; } /* Opcode: CreateTable P1 P2 * * * ** |
︙ | ︙ | |||
68314 68315 68316 68317 68318 68319 68320 | ** P1>1. Write the root page number of the new table into ** register P2. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 68363 68364 68365 68366 68367 68368 68369 68370 68371 68372 68373 68374 68375 68376 68377 68378 68379 68380 68381 68382 68383 68384 68385 68386 68387 68388 68389 68390 68391 68392 68393 68394 68395 68396 68397 68398 68399 68400 68401 68402 68403 68404 68405 68406 68407 68408 68409 68410 68411 68412 68413 68414 68415 68416 68417 68418 68419 68420 68421 68422 68423 68424 68425 68426 68427 68428 68429 68430 68431 68432 68433 68434 68435 68436 68437 68438 68439 68440 68441 68442 68443 68444 68445 | ** P1>1. Write the root page number of the new table into ** register P2. ** ** See documentation on OP_CreateTable for additional information. */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ #if 0 /* local variables moved into u.bw */ int pgno; int flags; Db *pDb; #endif /* local variables moved into u.bw */ u.bw.pgno = 0; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); u.bw.pDb = &db->aDb[pOp->p1]; assert( u.bw.pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ /* u.bw.flags = BTREE_INTKEY; */ u.bw.flags = BTREE_INTKEY; }else{ u.bw.flags = BTREE_BLOBKEY; } rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); pOut->u.i = u.bw.pgno; break; } /* Opcode: ParseSchema P1 * * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 ** that match the WHERE clause P4. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { #if 0 /* local variables moved into u.bx */ int iDb; const char *zMaster; char *zSql; InitData initData; #endif /* local variables moved into u.bx */ /* Any prepared statement that invokes this opcode will hold mutexes ** on every btree. This is a prerequisite for invoking ** sqlite3InitCallback(). */ #ifdef SQLITE_DEBUG for(u.bx.iDb=0; u.bx.iDb<db->nDb; u.bx.iDb++){ assert( u.bx.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); } #endif u.bx.iDb = pOp->p1; assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb ); assert( DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ); /* Used to be a conditional */ { u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); u.bx.initData.db = db; u.bx.initData.iDb = pOp->p1; u.bx.initData.pzErrMsg = &p->zErrMsg; u.bx.zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); if( u.bx.zSql==0 ){ rc = SQLITE_NOMEM; }else{ assert( db->init.busy==0 ); db->init.busy = 1; u.bx.initData.rc = SQLITE_OK; assert( !db->mallocFailed ); rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); if( rc==SQLITE_OK ) rc = u.bx.initData.rc; sqlite3DbFree(db, u.bx.zSql); db->init.busy = 0; } } if( rc==SQLITE_NOMEM ){ goto no_mem; } break; |
︙ | ︙ | |||
68465 68466 68467 68468 68469 68470 68471 | ** ** If P5 is not zero, the check is done on the auxiliary database ** file, not the main database file. ** ** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { | | | | | | | | | | | | | | | | | | | | | | 68514 68515 68516 68517 68518 68519 68520 68521 68522 68523 68524 68525 68526 68527 68528 68529 68530 68531 68532 68533 68534 68535 68536 68537 68538 68539 68540 68541 68542 68543 68544 68545 68546 68547 68548 68549 68550 68551 68552 68553 68554 68555 68556 68557 68558 68559 68560 68561 68562 | ** ** If P5 is not zero, the check is done on the auxiliary database ** file, not the main database file. ** ** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { #if 0 /* local variables moved into u.by */ int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ #endif /* local variables moved into u.by */ u.by.nRoot = pOp->p2; assert( u.by.nRoot>0 ); u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); if( u.by.aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); u.by.pnErr = &aMem[pOp->p3]; assert( (u.by.pnErr->flags & MEM_Int)!=0 ); assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &aMem[pOp->p1]; for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){ u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]); } u.by.aRoot[u.by.j] = 0; assert( pOp->p5<db->nDb ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, (int)u.by.pnErr->u.i, &u.by.nErr); sqlite3DbFree(db, u.by.aRoot); u.by.pnErr->u.i -= u.by.nErr; sqlite3VdbeMemSetNull(pIn1); if( u.by.nErr==0 ){ assert( u.by.z==0 ); }else if( u.by.z==0 ){ goto no_mem; }else{ sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
︙ | ︙ | |||
68533 68534 68535 68536 68537 68538 68539 | /* Opcode: RowSetRead P1 P2 P3 * * ** ** Extract the smallest value from boolean index P1 and put that value into ** register P3. Or, if boolean index P1 is initially empty, leave P3 ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, in1, out3 */ | | | | | | 68582 68583 68584 68585 68586 68587 68588 68589 68590 68591 68592 68593 68594 68595 68596 68597 68598 68599 68600 68601 68602 68603 68604 68605 68606 68607 68608 68609 | /* Opcode: RowSetRead P1 P2 P3 * * ** ** Extract the smallest value from boolean index P1 and put that value into ** register P3. Or, if boolean index P1 is initially empty, leave P3 ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, in1, out3 */ #if 0 /* local variables moved into u.bz */ i64 val; #endif /* local variables moved into u.bz */ CHECK_FOR_INTERRUPT; pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_RowSet)==0 || sqlite3RowSetNext(pIn1->u.pRowSet, &u.bz.val)==0 ){ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); pc = pOp->p2 - 1; }else{ /* A value was pulled from the index */ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.bz.val); } break; } /* Opcode: RowSetTest P1 P2 P3 P4 ** ** Register P3 is assumed to hold a 64-bit integer value. If register P1 |
︙ | ︙ | |||
68575 68576 68577 68578 68579 68580 68581 | ** (b) when P4==-1 there is no need to insert the value, as it will ** never be tested for, and (c) when a value that is part of set X is ** inserted, there is no need to search to see if the same value was ** previously inserted as part of set X (only if it was previously ** inserted as part of some other set). */ case OP_RowSetTest: { /* jump, in1, in3 */ | | | | | | | | | | | 68624 68625 68626 68627 68628 68629 68630 68631 68632 68633 68634 68635 68636 68637 68638 68639 68640 68641 68642 68643 68644 68645 68646 68647 68648 68649 68650 68651 68652 68653 68654 68655 68656 68657 68658 68659 68660 68661 68662 68663 68664 68665 68666 68667 | ** (b) when P4==-1 there is no need to insert the value, as it will ** never be tested for, and (c) when a value that is part of set X is ** inserted, there is no need to search to see if the same value was ** previously inserted as part of set X (only if it was previously ** inserted as part of some other set). */ case OP_RowSetTest: { /* jump, in1, in3 */ #if 0 /* local variables moved into u.ca */ int iSet; int exists; #endif /* local variables moved into u.ca */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; u.ca.iSet = pOp->p4.i; assert( pIn3->flags&MEM_Int ); /* If there is anything other than a rowset object in memory cell P1, ** delete it now and initialize P1 with an empty rowset */ if( (pIn1->flags & MEM_RowSet)==0 ){ sqlite3VdbeMemSetRowSet(pIn1); if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; } assert( pOp->p4type==P4_INT32 ); assert( u.ca.iSet==-1 || u.ca.iSet>=0 ); if( u.ca.iSet ){ u.ca.exists = sqlite3RowSetTest(pIn1->u.pRowSet, (u8)(u.ca.iSet>=0 ? u.ca.iSet & 0xf : 0xff), pIn3->u.i); if( u.ca.exists ){ pc = pOp->p2 - 1; break; } } if( u.ca.iSet>=0 ){ sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; } #ifndef SQLITE_OMIT_TRIGGER |
︙ | ︙ | |||
68627 68628 68629 68630 68631 68632 68633 | ** exception using the RAISE() function. Register P3 contains the address ** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. */ case OP_Program: { /* jump */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 68676 68677 68678 68679 68680 68681 68682 68683 68684 68685 68686 68687 68688 68689 68690 68691 68692 68693 68694 68695 68696 68697 68698 68699 68700 68701 68702 68703 68704 68705 68706 68707 68708 68709 68710 68711 68712 68713 68714 68715 68716 68717 68718 68719 68720 68721 68722 68723 68724 68725 68726 68727 68728 68729 68730 68731 68732 68733 68734 68735 68736 68737 68738 68739 68740 68741 68742 68743 68744 68745 68746 68747 68748 68749 68750 68751 68752 68753 68754 68755 68756 68757 68758 68759 68760 68761 68762 68763 68764 68765 68766 68767 68768 68769 68770 68771 68772 68773 68774 68775 68776 68777 68778 68779 68780 68781 68782 68783 68784 68785 68786 68787 68788 68789 68790 68791 68792 68793 68794 68795 68796 68797 68798 68799 68800 68801 68802 68803 68804 68805 68806 68807 68808 68809 68810 68811 | ** exception using the RAISE() function. Register P3 contains the address ** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. */ case OP_Program: { /* jump */ #if 0 /* local variables moved into u.cb */ int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ Mem *pMem; /* Used to iterate through memory cells */ Mem *pEnd; /* Last memory cell in new array */ VdbeFrame *pFrame; /* New vdbe frame to execute in */ SubProgram *pProgram; /* Sub-program to execute */ void *t; /* Token identifying trigger */ #endif /* local variables moved into u.cb */ u.cb.pProgram = pOp->p4.pProgram; u.cb.pRt = &aMem[pOp->p3]; assert( memIsValid(u.cb.pRt) ); assert( u.cb.pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is ** disabled for backwards compatibility (p5 is set if this sub-program ** is really a trigger, not a foreign key action, and the flag set ** and cleared by the "PRAGMA recursive_triggers" command is clear). ** ** It is recursive invocation of triggers, at the SQL level, that is ** disabled. In some cases a single trigger may generate more than one ** SubProgram (if the trigger may be executed with more than one different ** ON CONFLICT algorithm). SubProgram structures associated with a ** single trigger all have the same value for the SubProgram.token ** variable. */ if( pOp->p5 ){ u.cb.t = u.cb.pProgram->token; for(u.cb.pFrame=p->pFrame; u.cb.pFrame && u.cb.pFrame->token!=u.cb.t; u.cb.pFrame=u.cb.pFrame->pParent); if( u.cb.pFrame ) break; } if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); break; } /* Register u.cb.pRt is used to store the memory required to save the state ** of the current program, and the memory required at runtime to execute ** the trigger program. If this trigger has been fired before, then u.cb.pRt ** is already allocated. Otherwise, it must be initialized. */ if( (u.cb.pRt->flags&MEM_Frame)==0 ){ /* SubProgram.nMem is set to the number of memory cells used by the ** program stored in SubProgram.aOp. As well as these, one memory ** cell is required for each cursor used by the program. Set local ** variable u.cb.nMem (and later, VdbeFrame.nChildMem) to this value. */ u.cb.nMem = u.cb.pProgram->nMem + u.cb.pProgram->nCsr; u.cb.nByte = ROUND8(sizeof(VdbeFrame)) + u.cb.nMem * sizeof(Mem) + u.cb.pProgram->nCsr * sizeof(VdbeCursor *); u.cb.pFrame = sqlite3DbMallocZero(db, u.cb.nByte); if( !u.cb.pFrame ){ goto no_mem; } sqlite3VdbeMemRelease(u.cb.pRt); u.cb.pRt->flags = MEM_Frame; u.cb.pRt->u.pFrame = u.cb.pFrame; u.cb.pFrame->v = p; u.cb.pFrame->nChildMem = u.cb.nMem; u.cb.pFrame->nChildCsr = u.cb.pProgram->nCsr; u.cb.pFrame->pc = pc; u.cb.pFrame->aMem = p->aMem; u.cb.pFrame->nMem = p->nMem; u.cb.pFrame->apCsr = p->apCsr; u.cb.pFrame->nCursor = p->nCursor; u.cb.pFrame->aOp = p->aOp; u.cb.pFrame->nOp = p->nOp; u.cb.pFrame->token = u.cb.pProgram->token; u.cb.pEnd = &VdbeFrameMem(u.cb.pFrame)[u.cb.pFrame->nChildMem]; for(u.cb.pMem=VdbeFrameMem(u.cb.pFrame); u.cb.pMem!=u.cb.pEnd; u.cb.pMem++){ u.cb.pMem->flags = MEM_Null; u.cb.pMem->db = db; } }else{ u.cb.pFrame = u.cb.pRt->u.pFrame; assert( u.cb.pProgram->nMem+u.cb.pProgram->nCsr==u.cb.pFrame->nChildMem ); assert( u.cb.pProgram->nCsr==u.cb.pFrame->nChildCsr ); assert( pc==u.cb.pFrame->pc ); } p->nFrame++; u.cb.pFrame->pParent = p->pFrame; u.cb.pFrame->lastRowid = lastRowid; u.cb.pFrame->nChange = p->nChange; p->nChange = 0; p->pFrame = u.cb.pFrame; p->aMem = aMem = &VdbeFrameMem(u.cb.pFrame)[-1]; p->nMem = u.cb.pFrame->nChildMem; p->nCursor = (u16)u.cb.pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; p->aOp = aOp = u.cb.pProgram->aOp; p->nOp = u.cb.pProgram->nOp; pc = -1; break; } /* Opcode: Param P1 P2 * * * ** ** This opcode is only ever present in sub-programs called via the ** OP_Program instruction. Copy a value currently stored in a memory ** cell of the calling (parent) frame to cell P2 in the current frames ** address space. This is used by trigger programs to access the new.* ** and old.* values. ** ** The address of the cell in the parent frame is determined by adding ** the value of the P1 argument to the value of the P1 argument to the ** calling OP_Program instruction. */ case OP_Param: { /* out2-prerelease */ #if 0 /* local variables moved into u.cc */ VdbeFrame *pFrame; Mem *pIn; #endif /* local variables moved into u.cc */ u.cc.pFrame = p->pFrame; u.cc.pIn = &u.cc.pFrame->aMem[pOp->p1 + u.cc.pFrame->aOp[u.cc.pFrame->pc].p1]; sqlite3VdbeMemShallowCopy(pOut, u.cc.pIn, MEM_Ephem); break; } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_FOREIGN_KEY /* Opcode: FkCounter P1 P2 * * * |
︙ | ︙ | |||
68804 68805 68806 68807 68808 68809 68810 | ** within a sub-program). Set the value of register P1 to the maximum of ** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemMax: { /* in2 */ | | | | | | | | | | | 68853 68854 68855 68856 68857 68858 68859 68860 68861 68862 68863 68864 68865 68866 68867 68868 68869 68870 68871 68872 68873 68874 68875 68876 68877 68878 68879 68880 68881 68882 | ** within a sub-program). Set the value of register P1 to the maximum of ** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemMax: { /* in2 */ #if 0 /* local variables moved into u.cd */ Mem *pIn1; VdbeFrame *pFrame; #endif /* local variables moved into u.cd */ if( p->pFrame ){ for(u.cd.pFrame=p->pFrame; u.cd.pFrame->pParent; u.cd.pFrame=u.cd.pFrame->pParent); u.cd.pIn1 = &u.cd.pFrame->aMem[pOp->p1]; }else{ u.cd.pIn1 = &aMem[pOp->p1]; } assert( memIsValid(u.cd.pIn1) ); sqlite3VdbeMemIntegerify(u.cd.pIn1); pIn2 = &aMem[pOp->p2]; sqlite3VdbeMemIntegerify(pIn2); if( u.cd.pIn1->u.i<pIn2->u.i){ u.cd.pIn1->u.i = pIn2->u.i; } break; } #endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Opcode: IfPos P1 P2 * * * ** |
︙ | ︙ | |||
68886 68887 68888 68889 68890 68891 68892 | ** structure that specifies the function. Use register ** P3 as the accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. */ case OP_AggStep: { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 68935 68936 68937 68938 68939 68940 68941 68942 68943 68944 68945 68946 68947 68948 68949 68950 68951 68952 68953 68954 68955 68956 68957 68958 68959 68960 68961 68962 68963 68964 68965 68966 68967 68968 68969 68970 68971 68972 68973 68974 68975 68976 68977 68978 68979 68980 68981 68982 68983 68984 68985 68986 68987 68988 68989 68990 68991 68992 68993 68994 68995 68996 68997 68998 68999 69000 69001 69002 69003 69004 69005 69006 69007 69008 69009 69010 69011 69012 69013 69014 69015 69016 69017 69018 69019 69020 69021 69022 69023 69024 69025 69026 69027 69028 69029 69030 69031 69032 69033 69034 69035 69036 69037 69038 69039 69040 69041 69042 69043 69044 69045 69046 69047 69048 69049 69050 69051 69052 69053 69054 69055 69056 69057 69058 69059 69060 69061 69062 69063 69064 69065 69066 69067 69068 69069 69070 69071 69072 69073 69074 69075 69076 69077 69078 69079 69080 69081 69082 69083 69084 69085 69086 69087 69088 69089 69090 69091 69092 69093 69094 69095 69096 69097 69098 69099 69100 69101 69102 69103 69104 69105 69106 69107 69108 69109 69110 69111 69112 69113 69114 69115 69116 69117 69118 69119 69120 69121 69122 69123 69124 69125 69126 69127 69128 69129 69130 69131 69132 69133 69134 69135 69136 69137 69138 69139 69140 69141 69142 69143 69144 69145 69146 69147 69148 69149 69150 69151 69152 69153 69154 69155 69156 69157 69158 69159 69160 69161 69162 | ** structure that specifies the function. Use register ** P3 as the accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. */ case OP_AggStep: { #if 0 /* local variables moved into u.ce */ int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; #endif /* local variables moved into u.ce */ u.ce.n = pOp->p5; assert( u.ce.n>=0 ); u.ce.pRec = &aMem[pOp->p2]; u.ce.apVal = p->apArg; assert( u.ce.apVal || u.ce.n==0 ); for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){ assert( memIsValid(u.ce.pRec) ); u.ce.apVal[u.ce.i] = u.ce.pRec; memAboutToChange(p, u.ce.pRec); sqlite3VdbeMemStoreType(u.ce.pRec); } u.ce.ctx.pFunc = pOp->p4.pFunc; assert( pOp->p3>0 && pOp->p3<=p->nMem ); u.ce.ctx.pMem = u.ce.pMem = &aMem[pOp->p3]; u.ce.pMem->n++; u.ce.ctx.s.flags = MEM_Null; u.ce.ctx.s.z = 0; u.ce.ctx.s.zMalloc = 0; u.ce.ctx.s.xDel = 0; u.ce.ctx.s.db = db; u.ce.ctx.isError = 0; u.ce.ctx.pColl = 0; if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); u.ce.ctx.pColl = pOp[-1].p4.pColl; } (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); /* IMP: R-24505-23230 */ if( u.ce.ctx.isError ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); rc = u.ce.ctx.isError; } sqlite3VdbeMemRelease(&u.ce.ctx.s); break; } /* Opcode: AggFinal P1 P2 * P4 * ** ** Execute the finalizer function for an aggregate. P1 is ** the memory location that is the accumulator for the aggregate. ** ** P2 is the number of arguments that the step function takes and ** P4 is a pointer to the FuncDef for this function. The P2 ** argument is not used by this opcode. It is only there to disambiguate ** functions that can take varying numbers of arguments. The ** P4 argument is only needed for the degenerate case where ** the step function was not previously called. */ case OP_AggFinal: { #if 0 /* local variables moved into u.cf */ Mem *pMem; #endif /* local variables moved into u.cf */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); u.cf.pMem = &aMem[pOp->p1]; assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); if( rc ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); } sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); UPDATE_MAX_BLOBSIZE(u.cf.pMem); if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ goto too_big; } break; } #ifndef SQLITE_OMIT_WAL /* Opcode: Checkpoint P1 P2 P3 * * ** ** Checkpoint database P1. This is a no-op if P1 is not currently in ** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL ** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns ** SQLITE_BUSY or not, respectively. Write the number of pages in the ** WAL after the checkpoint into mem[P3+1] and the number of pages ** in the WAL that have been checkpointed after the checkpoint ** completes into mem[P3+2]. However on an error, mem[P3+1] and ** mem[P3+2] are initialized to -1. */ case OP_Checkpoint: { #if 0 /* local variables moved into u.cg */ int i; /* Loop counter */ int aRes[3]; /* Results */ Mem *pMem; /* Write results here */ #endif /* local variables moved into u.cg */ u.cg.aRes[0] = 0; u.cg.aRes[1] = u.cg.aRes[2] = -1; assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE || pOp->p2==SQLITE_CHECKPOINT_FULL || pOp->p2==SQLITE_CHECKPOINT_RESTART ); rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.cg.aRes[1], &u.cg.aRes[2]); if( rc==SQLITE_BUSY ){ rc = SQLITE_OK; u.cg.aRes[0] = 1; } for(u.cg.i=0, u.cg.pMem = &aMem[pOp->p3]; u.cg.i<3; u.cg.i++, u.cg.pMem++){ sqlite3VdbeMemSetInt64(u.cg.pMem, (i64)u.cg.aRes[u.cg.i]); } break; }; #endif #ifndef SQLITE_OMIT_PRAGMA /* Opcode: JournalMode P1 P2 P3 * P5 ** ** Change the journal mode of database P1 to P3. P3 must be one of the ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback ** modes (delete, truncate, persist, off and memory), this is a simple ** operation. No IO is required. ** ** If changing into or out of WAL mode the procedure is more complicated. ** ** Write a string containing the final journal-mode to register P2. */ case OP_JournalMode: { /* out2-prerelease */ #if 0 /* local variables moved into u.ch */ Btree *pBt; /* Btree to change journal mode of */ Pager *pPager; /* Pager associated with pBt */ int eNew; /* New journal mode */ int eOld; /* The old journal mode */ const char *zFilename; /* Name of database file for pPager */ #endif /* local variables moved into u.ch */ u.ch.eNew = pOp->p3; assert( u.ch.eNew==PAGER_JOURNALMODE_DELETE || u.ch.eNew==PAGER_JOURNALMODE_TRUNCATE || u.ch.eNew==PAGER_JOURNALMODE_PERSIST || u.ch.eNew==PAGER_JOURNALMODE_OFF || u.ch.eNew==PAGER_JOURNALMODE_MEMORY || u.ch.eNew==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_QUERY ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); u.ch.pBt = db->aDb[pOp->p1].pBt; u.ch.pPager = sqlite3BtreePager(u.ch.pBt); u.ch.eOld = sqlite3PagerGetJournalMode(u.ch.pPager); if( u.ch.eNew==PAGER_JOURNALMODE_QUERY ) u.ch.eNew = u.ch.eOld; if( !sqlite3PagerOkToChangeJournalMode(u.ch.pPager) ) u.ch.eNew = u.ch.eOld; #ifndef SQLITE_OMIT_WAL u.ch.zFilename = sqlite3PagerFilename(u.ch.pPager); /* Do not allow a transition to journal_mode=WAL for a database ** in temporary storage or if the VFS does not support shared memory */ if( u.ch.eNew==PAGER_JOURNALMODE_WAL && (u.ch.zFilename[0]==0 /* Temp file */ || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */ ){ u.ch.eNew = u.ch.eOld; } if( (u.ch.eNew!=u.ch.eOld) && (u.ch.eOld==PAGER_JOURNALMODE_WAL || u.ch.eNew==PAGER_JOURNALMODE_WAL) ){ if( !db->autoCommit || db->activeVdbeCnt>1 ){ rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, db, "cannot change %s wal mode from within a transaction", (u.ch.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") ); break; }else{ if( u.ch.eOld==PAGER_JOURNALMODE_WAL ){ /* If leaving WAL mode, close the log file. If successful, the call ** to PagerCloseWal() checkpoints and deletes the write-ahead-log ** file. An EXCLUSIVE lock may still be held on the database file ** after a successful return. */ rc = sqlite3PagerCloseWal(u.ch.pPager); if( rc==SQLITE_OK ){ sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); } }else if( u.ch.eOld==PAGER_JOURNALMODE_MEMORY ){ /* Cannot transition directly from MEMORY to WAL. Use mode OFF ** as an intermediate */ sqlite3PagerSetJournalMode(u.ch.pPager, PAGER_JOURNALMODE_OFF); } /* Open a transaction on the database file. Regardless of the journal ** mode, this transaction always uses a rollback journal. */ assert( sqlite3BtreeIsInTrans(u.ch.pBt)==0 ); if( rc==SQLITE_OK ){ rc = sqlite3BtreeSetVersion(u.ch.pBt, (u.ch.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } } } #endif /* ifndef SQLITE_OMIT_WAL */ if( rc ){ u.ch.eNew = u.ch.eOld; } u.ch.eNew = sqlite3PagerSetJournalMode(u.ch.pPager, u.ch.eNew); pOut = &aMem[pOp->p2]; pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = (char *)sqlite3JournalModename(u.ch.eNew); pOut->n = sqlite3Strlen30(pOut->z); pOut->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pOut, encoding); break; }; #endif /* SQLITE_OMIT_PRAGMA */ |
︙ | ︙ | |||
69128 69129 69130 69131 69132 69133 69134 | /* Opcode: IncrVacuum P1 P2 * * * ** ** Perform a single step of the incremental vacuum procedure on ** the P1 database. If the vacuum has finished, jump to instruction ** P2. Otherwise, fall through to the next instruction. */ case OP_IncrVacuum: { /* jump */ | | | | | | 69177 69178 69179 69180 69181 69182 69183 69184 69185 69186 69187 69188 69189 69190 69191 69192 69193 69194 69195 69196 69197 69198 | /* Opcode: IncrVacuum P1 P2 * * * ** ** Perform a single step of the incremental vacuum procedure on ** the P1 database. If the vacuum has finished, jump to instruction ** P2. Otherwise, fall through to the next instruction. */ case OP_IncrVacuum: { /* jump */ #if 0 /* local variables moved into u.ci */ Btree *pBt; #endif /* local variables moved into u.ci */ assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); u.ci.pBt = db->aDb[pOp->p1].pBt; rc = sqlite3BtreeIncrVacuum(u.ci.pBt); if( rc==SQLITE_DONE ){ pc = pOp->p2 - 1; rc = SQLITE_OK; } break; } #endif |
︙ | ︙ | |||
69205 69206 69207 69208 69209 69210 69211 | ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from ** within a callback to a virtual table xSync() method. If it is, the error ** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { | | | | | | | 69254 69255 69256 69257 69258 69259 69260 69261 69262 69263 69264 69265 69266 69267 69268 69269 69270 69271 69272 69273 | ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from ** within a callback to a virtual table xSync() method. If it is, the error ** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { #if 0 /* local variables moved into u.cj */ VTable *pVTab; #endif /* local variables moved into u.cj */ u.cj.pVTab = pOp->p4.pVtab; rc = sqlite3VtabBegin(db, u.cj.pVTab); if( u.cj.pVTab ) importVtabErrMsg(p, u.cj.pVTab->pVtab); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VCreate P1 * * P4 * ** |
︙ | ︙ | |||
69249 69250 69251 69252 69253 69254 69255 | /* Opcode: VOpen P1 * * P4 * ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { | | | | | | | | | | | | | | | | | 69298 69299 69300 69301 69302 69303 69304 69305 69306 69307 69308 69309 69310 69311 69312 69313 69314 69315 69316 69317 69318 69319 69320 69321 69322 69323 69324 69325 69326 69327 69328 69329 69330 69331 69332 69333 69334 69335 69336 69337 | /* Opcode: VOpen P1 * * P4 * ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { #if 0 /* local variables moved into u.ck */ VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; #endif /* local variables moved into u.ck */ u.ck.pCur = 0; u.ck.pVtabCursor = 0; u.ck.pVtab = pOp->p4.pVtab->pVtab; u.ck.pModule = (sqlite3_module *)u.ck.pVtab->pModule; assert(u.ck.pVtab && u.ck.pModule); rc = u.ck.pModule->xOpen(u.ck.pVtab, &u.ck.pVtabCursor); importVtabErrMsg(p, u.ck.pVtab); if( SQLITE_OK==rc ){ /* Initialize sqlite3_vtab_cursor base class */ u.ck.pVtabCursor->pVtab = u.ck.pVtab; /* Initialise vdbe cursor object */ u.ck.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); if( u.ck.pCur ){ u.ck.pCur->pVtabCursor = u.ck.pVtabCursor; u.ck.pCur->pModule = u.ck.pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; u.ck.pModule->xClose(u.ck.pVtabCursor); } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
69301 69302 69303 69304 69305 69306 69307 | ** xFilter method. Registers P3+2..P3+1+argc are the argc ** additional parameters which are passed to ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. ** ** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* jump */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 69350 69351 69352 69353 69354 69355 69356 69357 69358 69359 69360 69361 69362 69363 69364 69365 69366 69367 69368 69369 69370 69371 69372 69373 69374 69375 69376 69377 69378 69379 69380 69381 69382 69383 69384 69385 69386 69387 69388 69389 69390 69391 69392 69393 69394 69395 69396 69397 69398 69399 69400 69401 69402 69403 69404 69405 69406 69407 69408 69409 69410 69411 69412 69413 69414 69415 69416 69417 69418 69419 69420 69421 69422 69423 69424 69425 69426 69427 69428 69429 69430 69431 69432 69433 69434 69435 69436 69437 69438 69439 69440 69441 69442 69443 69444 69445 69446 69447 69448 69449 69450 69451 69452 69453 69454 69455 69456 69457 69458 69459 69460 69461 69462 69463 69464 69465 69466 69467 69468 69469 69470 69471 69472 69473 69474 69475 69476 69477 69478 69479 69480 69481 69482 69483 69484 69485 69486 69487 69488 69489 69490 69491 69492 69493 69494 69495 69496 69497 69498 69499 69500 69501 69502 69503 69504 69505 69506 69507 69508 69509 69510 69511 69512 69513 69514 69515 69516 69517 69518 69519 69520 69521 69522 69523 69524 69525 69526 69527 69528 69529 69530 69531 69532 69533 69534 69535 69536 69537 69538 69539 69540 69541 69542 69543 69544 69545 69546 | ** xFilter method. Registers P3+2..P3+1+argc are the argc ** additional parameters which are passed to ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. ** ** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* jump */ #if 0 /* local variables moved into u.cl */ int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; int i; Mem **apArg; #endif /* local variables moved into u.cl */ u.cl.pQuery = &aMem[pOp->p3]; u.cl.pArgc = &u.cl.pQuery[1]; u.cl.pCur = p->apCsr[pOp->p1]; assert( memIsValid(u.cl.pQuery) ); REGISTER_TRACE(pOp->p3, u.cl.pQuery); assert( u.cl.pCur->pVtabCursor ); u.cl.pVtabCursor = u.cl.pCur->pVtabCursor; u.cl.pVtab = u.cl.pVtabCursor->pVtab; u.cl.pModule = u.cl.pVtab->pModule; /* Grab the index number and argc parameters */ assert( (u.cl.pQuery->flags&MEM_Int)!=0 && u.cl.pArgc->flags==MEM_Int ); u.cl.nArg = (int)u.cl.pArgc->u.i; u.cl.iQuery = (int)u.cl.pQuery->u.i; /* Invoke the xFilter method */ { u.cl.res = 0; u.cl.apArg = p->apArg; for(u.cl.i = 0; u.cl.i<u.cl.nArg; u.cl.i++){ u.cl.apArg[u.cl.i] = &u.cl.pArgc[u.cl.i+1]; sqlite3VdbeMemStoreType(u.cl.apArg[u.cl.i]); } p->inVtabMethod = 1; rc = u.cl.pModule->xFilter(u.cl.pVtabCursor, u.cl.iQuery, pOp->p4.z, u.cl.nArg, u.cl.apArg); p->inVtabMethod = 0; importVtabErrMsg(p, u.cl.pVtab); if( rc==SQLITE_OK ){ u.cl.res = u.cl.pModule->xEof(u.cl.pVtabCursor); } if( u.cl.res ){ pc = pOp->p2 - 1; } } u.cl.pCur->nullRow = 0; break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 P3 * * ** ** Store the value of the P2-th column of ** the row of the virtual-table that the ** P1 cursor is pointing to into register P3. */ case OP_VColumn: { #if 0 /* local variables moved into u.cm */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; #endif /* local variables moved into u.cm */ VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); u.cm.pDest = &aMem[pOp->p3]; memAboutToChange(p, u.cm.pDest); if( pCur->nullRow ){ sqlite3VdbeMemSetNull(u.cm.pDest); break; } u.cm.pVtab = pCur->pVtabCursor->pVtab; u.cm.pModule = u.cm.pVtab->pModule; assert( u.cm.pModule->xColumn ); memset(&u.cm.sContext, 0, sizeof(u.cm.sContext)); /* The output cell may already have a buffer allocated. Move ** the current contents to u.cm.sContext.s so in case the user-function ** can use the already allocated buffer instead of allocating a ** new one. */ sqlite3VdbeMemMove(&u.cm.sContext.s, u.cm.pDest); MemSetTypeFlag(&u.cm.sContext.s, MEM_Null); rc = u.cm.pModule->xColumn(pCur->pVtabCursor, &u.cm.sContext, pOp->p2); importVtabErrMsg(p, u.cm.pVtab); if( u.cm.sContext.isError ){ rc = u.cm.sContext.isError; } /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occurred to ensure any ** dynamic allocation in u.cm.sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&u.cm.sContext.s, encoding); sqlite3VdbeMemMove(u.cm.pDest, &u.cm.sContext.s); REGISTER_TRACE(pOp->p3, u.cm.pDest); UPDATE_MAX_BLOBSIZE(u.cm.pDest); if( sqlite3VdbeMemTooBig(u.cm.pDest) ){ goto too_big; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VNext P1 P2 * * * ** ** Advance virtual table P1 to the next row in its result set and ** jump to instruction P2. Or, if the virtual table has reached ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ #if 0 /* local variables moved into u.cn */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; #endif /* local variables moved into u.cn */ u.cn.res = 0; u.cn.pCur = p->apCsr[pOp->p1]; assert( u.cn.pCur->pVtabCursor ); if( u.cn.pCur->nullRow ){ break; } u.cn.pVtab = u.cn.pCur->pVtabCursor->pVtab; u.cn.pModule = u.cn.pVtab->pModule; assert( u.cn.pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during ** xNext(). Instead, if an error occurs, true is returned (indicating that ** data is available) and the error code returned when xColumn or ** some other method is next invoked on the save virtual table cursor. */ p->inVtabMethod = 1; rc = u.cn.pModule->xNext(u.cn.pCur->pVtabCursor); p->inVtabMethod = 0; importVtabErrMsg(p, u.cn.pVtab); if( rc==SQLITE_OK ){ u.cn.res = u.cn.pModule->xEof(u.cn.pCur->pVtabCursor); } if( !u.cn.res ){ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRename P1 * * P4 * ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xRename method. The value ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { #if 0 /* local variables moved into u.co */ sqlite3_vtab *pVtab; Mem *pName; #endif /* local variables moved into u.co */ u.co.pVtab = pOp->p4.pVtab->pVtab; u.co.pName = &aMem[pOp->p1]; assert( u.co.pVtab->pModule->xRename ); assert( memIsValid(u.co.pName) ); REGISTER_TRACE(pOp->p1, u.co.pName); assert( u.co.pName->flags & MEM_Str ); rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z); importVtabErrMsg(p, u.co.pVtab); p->expired = 0; break; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
69515 69516 69517 69518 69519 69520 69521 | ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { | | | | | | | | | | | | | | | | | | | | 69564 69565 69566 69567 69568 69569 69570 69571 69572 69573 69574 69575 69576 69577 69578 69579 69580 69581 69582 69583 69584 69585 69586 69587 69588 69589 69590 69591 69592 69593 69594 69595 69596 69597 69598 69599 69600 69601 69602 69603 69604 69605 69606 69607 69608 69609 69610 69611 69612 | ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { #if 0 /* local variables moved into u.cp */ sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; #endif /* local variables moved into u.cp */ assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace ); u.cp.pVtab = pOp->p4.pVtab->pVtab; u.cp.pModule = (sqlite3_module *)u.cp.pVtab->pModule; u.cp.nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); if( ALWAYS(u.cp.pModule->xUpdate) ){ u8 vtabOnConflict = db->vtabOnConflict; u.cp.apArg = p->apArg; u.cp.pX = &aMem[pOp->p3]; for(u.cp.i=0; u.cp.i<u.cp.nArg; u.cp.i++){ assert( memIsValid(u.cp.pX) ); memAboutToChange(p, u.cp.pX); sqlite3VdbeMemStoreType(u.cp.pX); u.cp.apArg[u.cp.i] = u.cp.pX; u.cp.pX++; } db->vtabOnConflict = pOp->p5; rc = u.cp.pModule->xUpdate(u.cp.pVtab, u.cp.nArg, u.cp.apArg, &u.cp.rowid); db->vtabOnConflict = vtabOnConflict; importVtabErrMsg(p, u.cp.pVtab); if( rc==SQLITE_OK && pOp->p1 ){ assert( u.cp.nArg>1 && u.cp.apArg[0] && (u.cp.apArg[0]->flags&MEM_Null) ); db->lastRowid = lastRowid = u.cp.rowid; } if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ if( pOp->p5==OE_Ignore ){ rc = SQLITE_OK; }else{ p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); } |
︙ | ︙ | |||
69609 69610 69611 69612 69613 69614 69615 | #ifndef SQLITE_OMIT_TRACE /* Opcode: Trace * * * P4 * ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { | | | | | | | | | | 69658 69659 69660 69661 69662 69663 69664 69665 69666 69667 69668 69669 69670 69671 69672 69673 69674 69675 69676 69677 69678 69679 69680 69681 69682 69683 69684 69685 69686 | #ifndef SQLITE_OMIT_TRACE /* Opcode: Trace * * * P4 * ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { #if 0 /* local variables moved into u.cq */ char *zTrace; char *z; #endif /* local variables moved into u.cq */ if( db->xTrace && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ u.cq.z = sqlite3VdbeExpandSql(p, u.cq.zTrace); db->xTrace(db->pTraceArg, u.cq.z); sqlite3DbFree(db, u.cq.z); } #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 && (u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); } #endif /* SQLITE_DEBUG */ break; } #endif |
︙ | ︙ | |||
70026 70027 70028 70029 70030 70031 70032 | sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE | | | | 70075 70076 70077 70078 70079 70080 70081 70082 70083 70084 70085 70086 70087 70088 70089 70090 70091 70092 70093 70094 70095 70096 70097 70098 70099 | sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE sqlite3VdbeChangeToNoop(v, 2); #else sqlite3VdbeChangeP1(v, 2, iDb); sqlite3VdbeChangeP2(v, 2, pTab->tnum); sqlite3VdbeChangeP3(v, 2, flags); sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); #endif /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ sqlite3VdbeChangeToNoop(v, 4 - flags); sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); sqlite3VdbeChangeP3(v, 3 + flags, iDb); /* Configure the number of columns. Configure the cursor to ** think that the table has one more column than it really ** does. An OP_Column to retrieve this imaginary column will ** always return an SQL NULL. This is useful because it means |
︙ | ︙ | |||
70244 70245 70246 70247 70248 70249 70250 70251 70252 70253 70254 70255 70256 70257 | ** memory). */ #ifndef SQLITE_OMIT_MERGE_SORT typedef struct VdbeSorterIter VdbeSorterIter; /* ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: ** ** As keys are added to the sorter, they are written to disk in a series ** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly ** the same as the cache-size allowed for temporary databases. In order | > | 70293 70294 70295 70296 70297 70298 70299 70300 70301 70302 70303 70304 70305 70306 70307 | ** memory). */ #ifndef SQLITE_OMIT_MERGE_SORT typedef struct VdbeSorterIter VdbeSorterIter; typedef struct SorterRecord SorterRecord; /* ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: ** ** As keys are added to the sorter, they are written to disk in a series ** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly ** the same as the cache-size allowed for temporary databases. In order |
︙ | ︙ | |||
70315 70316 70317 70318 70319 70320 70321 | ** aTree[] = { X, 0 0, 6 0, 3, 5, 6 } ** ** In other words, each time we advance to the next sorter element, log2(N) ** key comparison operations are required, where N is the number of segments ** being merged (rounded up to the next power of 2). */ struct VdbeSorter { | | < > > > > > > > > > > > > > > > | 70365 70366 70367 70368 70369 70370 70371 70372 70373 70374 70375 70376 70377 70378 70379 70380 70381 70382 70383 70384 70385 70386 70387 70388 70389 70390 70391 70392 70393 70394 70395 70396 70397 70398 70399 70400 70401 70402 70403 70404 70405 70406 70407 70408 70409 70410 70411 70412 70413 70414 70415 70416 | ** aTree[] = { X, 0 0, 6 0, 3, 5, 6 } ** ** In other words, each time we advance to the next sorter element, log2(N) ** key comparison operations are required, where N is the number of segments ** being merged (rounded up to the next power of 2). */ struct VdbeSorter { int nInMemory; /* Current size of pRecord list as PMA */ int nTree; /* Used size of aTree/aIter (power of 2) */ VdbeSorterIter *aIter; /* Array of iterators to merge */ int *aTree; /* Current state of incremental merge */ i64 iWriteOff; /* Current write offset within file pTemp1 */ i64 iReadOff; /* Current read offset within file pTemp1 */ sqlite3_file *pTemp1; /* PMA file 1 */ int nPMA; /* Number of PMAs stored in pTemp1 */ SorterRecord *pRecord; /* Head of in-memory record list */ int mnPmaSize; /* Minimum PMA size, in bytes */ int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */ UnpackedRecord *pUnpacked; /* Used to unpack keys */ }; /* ** The following type is an iterator for a PMA. It caches the current key in ** variables nKey/aKey. If the iterator is at EOF, pFile==0. */ struct VdbeSorterIter { i64 iReadOff; /* Current read offset */ i64 iEof; /* 1 byte past EOF for this iterator */ sqlite3_file *pFile; /* File iterator is reading from */ int nAlloc; /* Bytes of space at aAlloc */ u8 *aAlloc; /* Allocated space */ int nKey; /* Number of bytes in key */ u8 *aKey; /* Pointer to current key */ }; /* ** A structure to store a single record. All in-memory records are connected ** together into a linked list headed at VdbeSorter.pRecord using the ** SorterRecord.pNext pointer. */ struct SorterRecord { void *pVal; int nVal; SorterRecord *pNext; }; /* Minimum allowable value for the VdbeSorter.nWorking variable */ #define SORTER_MIN_WORKING 10 /* Maximum number of segments to merge in a single pass. */ #define SORTER_MAX_MERGE_COUNT 16 |
︙ | ︙ | |||
70368 70369 70370 70371 70372 70373 70374 | VdbeSorterIter *pIter /* Iterator to advance */ ){ int rc; /* Return Code */ int nRead; /* Number of bytes read */ int nRec = 0; /* Size of record in bytes */ int iOff = 0; /* Size of serialized size varint in bytes */ | > | | > > > | 70432 70433 70434 70435 70436 70437 70438 70439 70440 70441 70442 70443 70444 70445 70446 70447 70448 70449 70450 70451 | VdbeSorterIter *pIter /* Iterator to advance */ ){ int rc; /* Return Code */ int nRead; /* Number of bytes read */ int nRec = 0; /* Size of record in bytes */ int iOff = 0; /* Size of serialized size varint in bytes */ assert( pIter->iEof>=pIter->iReadOff ); if( pIter->iEof-pIter->iReadOff>5 ){ nRead = 5; }else{ nRead = (int)(pIter->iEof - pIter->iReadOff); } if( nRead<=0 ){ /* This is an EOF condition */ vdbeSorterIterZero(db, pIter); return SQLITE_OK; } rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); |
︙ | ︙ | |||
70440 70441 70442 70443 70444 70445 70446 | ** (i.e. if no IO error occurs), then *piOffset is set to the offset of ** the first byte past the end of the varint before returning. *piVal is ** set to the integer value read. If an error occurs, the final values of ** both *piOffset and *piVal are undefined. */ static int vdbeSorterReadVarint( sqlite3_file *pFile, /* File to read from */ | < < < < < < < | | 70508 70509 70510 70511 70512 70513 70514 70515 70516 70517 70518 70519 70520 70521 70522 70523 70524 70525 70526 70527 70528 70529 | ** (i.e. if no IO error occurs), then *piOffset is set to the offset of ** the first byte past the end of the varint before returning. *piVal is ** set to the integer value read. If an error occurs, the final values of ** both *piOffset and *piVal are undefined. */ static int vdbeSorterReadVarint( sqlite3_file *pFile, /* File to read from */ i64 *piOffset, /* IN/OUT: Read offset in pFile */ i64 *piVal /* OUT: Value read from file */ ){ u8 aVarint[9]; /* Buffer large enough for a varint */ i64 iOff = *piOffset; /* Offset in file to read from */ int rc; /* Return code */ rc = sqlite3OsRead(pFile, aVarint, 9, iOff); if( rc==SQLITE_OK ){ *piOffset += getVarint(aVarint, (u64 *)piVal); } return rc; } |
︙ | ︙ | |||
70486 70487 70488 70489 70490 70491 70492 | pIter->pFile = pSorter->pTemp1; pIter->iReadOff = iStart; pIter->nAlloc = 128; pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); if( !pIter->aAlloc ){ rc = SQLITE_NOMEM; }else{ | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 70547 70548 70549 70550 70551 70552 70553 70554 70555 70556 70557 70558 70559 70560 70561 70562 70563 70564 70565 70566 70567 70568 70569 70570 70571 70572 70573 70574 70575 70576 70577 70578 70579 70580 70581 70582 70583 70584 70585 70586 70587 70588 70589 70590 70591 70592 70593 70594 70595 70596 70597 70598 70599 70600 70601 70602 70603 70604 70605 70606 70607 70608 70609 70610 70611 70612 70613 70614 70615 70616 70617 70618 | pIter->pFile = pSorter->pTemp1; pIter->iReadOff = iStart; pIter->nAlloc = 128; pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); if( !pIter->aAlloc ){ rc = SQLITE_NOMEM; }else{ i64 nByte; /* Total size of PMA in bytes */ rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); *pnByte += nByte; pIter->iEof = pIter->iReadOff + nByte; } if( rc==SQLITE_OK ){ rc = vdbeSorterIterNext(db, pIter); } return rc; } /* ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, ** size nKey2 bytes). Argument pKeyInfo supplies the collation functions ** used by the comparison. If an error occurs, return an SQLite error code. ** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive ** value, depending on whether key1 is smaller, equal to or larger than key2. ** ** If the bOmitRowid argument is non-zero, assume both keys end in a rowid ** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid ** is true and key1 contains even a single NULL value, it is considered to ** be less than key2. Even if key2 also contains NULL values. ** ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace ** has been allocated and contains an unpacked record that is used as key2. */ static void vdbeSorterCompare( VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ int bOmitRowid, /* Ignore rowid field at end of keys */ void *pKey1, int nKey1, /* Left side of comparison */ void *pKey2, int nKey2, /* Right side of comparison */ int *pRes /* OUT: Result of comparison */ ){ KeyInfo *pKeyInfo = pCsr->pKeyInfo; VdbeSorter *pSorter = pCsr->pSorter; UnpackedRecord *r2 = pSorter->pUnpacked; int i; if( pKey2 ){ sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2); } if( bOmitRowid ){ r2->nField = pKeyInfo->nField; assert( r2->nField>0 ); for(i=0; i<r2->nField; i++){ if( r2->aMem[i].flags & MEM_Null ){ *pRes = -1; return; } } r2->flags |= UNPACKED_PREFIX_MATCH; } *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); } /* ** This function is called to compare two iterator keys when merging ** multiple b-tree segments. Parameter iOut is the index of the aTree[] ** value to recalculate. */ static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ VdbeSorter *pSorter = pCsr->pSorter; |
︙ | ︙ | |||
70529 70530 70531 70532 70533 70534 70535 | p2 = &pSorter->aIter[i2]; if( p1->pFile==0 ){ iRes = i2; }else if( p2->pFile==0 ){ iRes = i1; }else{ | | | | < | < | < < > > > > > | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < | < < | > | > > > | | | | > < | | < < < | < < | < < < < < < < < < < < < < < | | | | | < | | | | > > > | | > | | | < < < < < < < < < < | | > > > | < | | | < | | > > | | < < < | < | < | | < < < < < < < < | > > > | < > > | | | < | | | < < < | < < | < | | < < < | 70636 70637 70638 70639 70640 70641 70642 70643 70644 70645 70646 70647 70648 70649 70650 70651 70652 70653 70654 70655 70656 70657 70658 70659 70660 70661 70662 70663 70664 70665 70666 70667 70668 70669 70670 70671 70672 70673 70674 70675 70676 70677 70678 70679 70680 70681 70682 70683 70684 70685 70686 70687 70688 70689 70690 70691 70692 70693 70694 70695 70696 70697 70698 70699 70700 70701 70702 70703 70704 70705 70706 70707 70708 70709 70710 70711 70712 70713 70714 70715 70716 70717 70718 70719 70720 70721 70722 70723 70724 70725 70726 70727 70728 70729 70730 70731 70732 70733 70734 70735 70736 70737 70738 70739 70740 70741 70742 70743 70744 70745 70746 70747 70748 70749 70750 70751 70752 70753 70754 70755 70756 70757 70758 70759 70760 70761 70762 70763 70764 70765 70766 70767 70768 70769 70770 70771 70772 70773 70774 70775 70776 70777 70778 70779 70780 70781 70782 70783 70784 70785 70786 70787 70788 70789 70790 70791 70792 70793 70794 70795 70796 70797 70798 70799 70800 70801 70802 70803 70804 70805 70806 70807 70808 70809 70810 70811 70812 70813 70814 70815 70816 70817 70818 70819 70820 70821 70822 70823 70824 70825 70826 70827 70828 70829 70830 70831 70832 70833 70834 70835 70836 70837 70838 70839 70840 70841 70842 70843 70844 70845 70846 70847 70848 70849 70850 70851 70852 70853 70854 70855 70856 70857 70858 70859 70860 70861 70862 70863 70864 70865 70866 70867 70868 70869 70870 70871 70872 70873 70874 70875 70876 70877 70878 70879 70880 70881 70882 70883 70884 70885 70886 70887 70888 70889 70890 70891 70892 70893 70894 70895 70896 70897 70898 70899 70900 70901 70902 70903 70904 70905 70906 70907 70908 70909 70910 70911 70912 70913 70914 70915 70916 70917 70918 70919 70920 70921 70922 70923 70924 70925 70926 70927 70928 70929 70930 70931 | p2 = &pSorter->aIter[i2]; if( p1->pFile==0 ){ iRes = i2; }else if( p2->pFile==0 ){ iRes = i1; }else{ int res; assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */ vdbeSorterCompare( pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res ); if( res<=0 ){ iRes = i1; }else{ iRes = i2; } } pSorter->aTree[iOut] = iRes; return SQLITE_OK; } /* ** Initialize the temporary index cursor just opened as a sorter cursor. */ SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){ int pgsz; /* Page size of main database */ int mxCache; /* Cache size */ VdbeSorter *pSorter; /* The new sorter */ char *d; /* Dummy */ assert( pCsr->pKeyInfo && pCsr->pBt==0 ); pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter)); if( pSorter==0 ){ return SQLITE_NOMEM; } pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d); if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM; assert( pSorter->pUnpacked==(UnpackedRecord *)d ); if( !sqlite3TempInMemory(db) ){ pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; mxCache = db->aDb[0].pSchema->cache_size; if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING; pSorter->mxPmaSize = mxCache * pgsz; } return SQLITE_OK; } /* ** Free the list of sorted records starting at pRecord. */ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ SorterRecord *p; SorterRecord *pNext; for(p=pRecord; p; p=pNext){ pNext = p->pNext; sqlite3DbFree(db, p); } } /* ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. */ SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ VdbeSorter *pSorter = pCsr->pSorter; if( pSorter ){ if( pSorter->aIter ){ int i; for(i=0; i<pSorter->nTree; i++){ vdbeSorterIterZero(db, &pSorter->aIter[i]); } sqlite3DbFree(db, pSorter->aIter); } if( pSorter->pTemp1 ){ sqlite3OsCloseFree(pSorter->pTemp1); } vdbeSorterRecordFree(db, pSorter->pRecord); sqlite3DbFree(db, pSorter->pUnpacked); sqlite3DbFree(db, pSorter); pCsr->pSorter = 0; } } /* ** Allocate space for a file-handle and open a temporary file. If successful, ** set *ppFile to point to the malloc'd file-handle and return SQLITE_OK. ** Otherwise, set *ppFile to 0 and return an SQLite error code. */ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){ int dummy; return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile, SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy ); } /* ** Merge the two sorted lists p1 and p2 into a single list. ** Set *ppOut to the head of the new list. */ static void vdbeSorterMerge( VdbeCursor *pCsr, /* For pKeyInfo */ SorterRecord *p1, /* First list to merge */ SorterRecord *p2, /* Second list to merge */ SorterRecord **ppOut /* OUT: Head of merged list */ ){ SorterRecord *pFinal = 0; SorterRecord **pp = &pFinal; void *pVal2 = p2 ? p2->pVal : 0; while( p1 && p2 ){ int res; vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res); if( res<=0 ){ *pp = p1; pp = &p1->pNext; p1 = p1->pNext; pVal2 = 0; }else{ *pp = p2; pp = &p2->pNext; p2 = p2->pNext; if( p2==0 ) break; pVal2 = p2->pVal; } } *pp = p1 ? p1 : p2; *ppOut = pFinal; } /* ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error ** occurs. */ static int vdbeSorterSort(VdbeCursor *pCsr){ int i; SorterRecord **aSlot; SorterRecord *p; VdbeSorter *pSorter = pCsr->pSorter; aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); if( !aSlot ){ return SQLITE_NOMEM; } p = pSorter->pRecord; while( p ){ SorterRecord *pNext = p->pNext; p->pNext = 0; for(i=0; aSlot[i]; i++){ vdbeSorterMerge(pCsr, p, aSlot[i], &p); aSlot[i] = 0; } aSlot[i] = p; p = pNext; } p = 0; for(i=0; i<64; i++){ vdbeSorterMerge(pCsr, p, aSlot[i], &p); } pSorter->pRecord = p; sqlite3_free(aSlot); return SQLITE_OK; } /* ** Write the current contents of the in-memory linked-list to a PMA. Return ** SQLITE_OK if successful, or an SQLite error code otherwise. ** ** The format of a PMA is: ** ** * A varint. This varint contains the total number of bytes of content ** in the PMA (not including the varint itself). ** ** * One or more records packed end-to-end in order of ascending keys. ** Each record consists of a varint followed by a blob of data (the ** key). The varint is the number of bytes in the blob of data. */ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ int rc = SQLITE_OK; /* Return code */ VdbeSorter *pSorter = pCsr->pSorter; if( pSorter->nInMemory==0 ){ assert( pSorter->pRecord==0 ); return rc; } rc = vdbeSorterSort(pCsr); /* If the first temporary PMA file has not been opened, open it now. */ if( rc==SQLITE_OK && pSorter->pTemp1==0 ){ rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1); assert( rc!=SQLITE_OK || pSorter->pTemp1 ); assert( pSorter->iWriteOff==0 ); assert( pSorter->nPMA==0 ); } if( rc==SQLITE_OK ){ i64 iOff = pSorter->iWriteOff; SorterRecord *p; SorterRecord *pNext = 0; static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; pSorter->nPMA++; rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ pNext = p->pNext; rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); iOff += p->nVal; } sqlite3DbFree(db, p); } /* This assert verifies that unless an error has occurred, the size of ** the PMA on disk is the same as the expected size stored in ** pSorter->nInMemory. */ assert( rc!=SQLITE_OK || pSorter->nInMemory==( iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) )); pSorter->iWriteOff = iOff; if( rc==SQLITE_OK ){ /* Terminate each file with 8 extra bytes so that from any offset ** in the file we can always read 9 bytes without a SHORT_READ error */ rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); } pSorter->pRecord = p; } return rc; } /* ** Add a record to the sorter. */ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( sqlite3 *db, /* Database handle */ VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal /* Memory cell containing record */ ){ VdbeSorter *pSorter = pCsr->pSorter; int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ assert( pSorter ); pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n; pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord)); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ pNew->pVal = (void *)&pNew[1]; memcpy(pNew->pVal, pVal->z, pVal->n); pNew->nVal = pVal->n; pNew->pNext = pSorter->pRecord; pSorter->pRecord = pNew; } /* See if the contents of the sorter should now be written out. They ** are written out when either of the following are true: ** ** * The total memory allocated for the in-memory list is greater ** than (page-size * cache-size), or ** ** * The total memory allocated for the in-memory list is greater ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. */ if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( (pSorter->nInMemory>pSorter->mxPmaSize) || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) )){ rc = vdbeSorterListToPMA(db, pCsr); pSorter->nInMemory = 0; } return rc; } /* ** Helper function for sqlite3VdbeSorterRewind(). */ static int vdbeSorterInitMerge( |
︙ | ︙ | |||
70799 70800 70801 70802 70803 70804 70805 | i64 iWrite2 = 0; /* Write offset for pTemp2 */ int nIter; /* Number of iterators used */ int nByte; /* Bytes of space required for aIter/aTree */ int N = 2; /* Power of 2 >= nIter */ assert( pSorter ); | | | | < | > | > > > > | 70967 70968 70969 70970 70971 70972 70973 70974 70975 70976 70977 70978 70979 70980 70981 70982 70983 70984 70985 70986 70987 70988 70989 70990 70991 70992 | i64 iWrite2 = 0; /* Write offset for pTemp2 */ int nIter; /* Number of iterators used */ int nByte; /* Bytes of space required for aIter/aTree */ int N = 2; /* Power of 2 >= nIter */ assert( pSorter ); /* If no data has been written to disk, then do not do so now. Instead, ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly ** from the in-memory list. */ if( pSorter->nPMA==0 ){ *pbEof = !pSorter->pRecord; assert( pSorter->aTree==0 ); return vdbeSorterSort(pCsr); } /* Write the current b-tree to a PMA. Close the b-tree cursor. */ rc = vdbeSorterListToPMA(db, pCsr); if( rc!=SQLITE_OK ) return rc; /* Allocate space for aIter[] and aTree[]. */ nIter = pSorter->nPMA; if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT; assert( nIter>0 ); while( N<nIter ) N += N; nByte = N * (sizeof(int) + sizeof(VdbeSorterIter)); |
︙ | ︙ | |||
70894 70895 70896 70897 70898 70899 70900 | } /* ** Advance to the next element in the sorter. */ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ VdbeSorter *pSorter = pCsr->pSorter; | > > > | | < | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < | < < < < < | < | | > > > > > > > > > > > > > > > > > > > > > > > | 71066 71067 71068 71069 71070 71071 71072 71073 71074 71075 71076 71077 71078 71079 71080 71081 71082 71083 71084 71085 71086 71087 71088 71089 71090 71091 71092 71093 71094 71095 71096 71097 71098 71099 71100 71101 71102 71103 71104 71105 71106 71107 71108 71109 71110 71111 71112 71113 71114 71115 71116 71117 71118 71119 71120 71121 71122 71123 71124 71125 71126 71127 71128 71129 71130 71131 71132 71133 71134 71135 71136 71137 71138 71139 71140 71141 71142 71143 71144 71145 71146 71147 71148 71149 71150 71151 71152 71153 71154 71155 71156 71157 71158 71159 71160 71161 71162 71163 | } /* ** Advance to the next element in the sorter. */ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ VdbeSorter *pSorter = pCsr->pSorter; int rc; /* Return code */ if( pSorter->aTree ){ int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ int i; /* Index of aTree[] to recalculate */ rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]); for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){ rc = vdbeSorterDoCompare(pCsr, i); } *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0); }else{ SorterRecord *pFree = pSorter->pRecord; pSorter->pRecord = pFree->pNext; pFree->pNext = 0; vdbeSorterRecordFree(db, pFree); *pbEof = !pSorter->pRecord; rc = SQLITE_OK; } return rc; } /* ** Return a pointer to a buffer owned by the sorter that contains the ** current key. */ static void *vdbeSorterRowkey( VdbeSorter *pSorter, /* Sorter object */ int *pnKey /* OUT: Size of current key in bytes */ ){ void *pKey; if( pSorter->aTree ){ VdbeSorterIter *pIter; pIter = &pSorter->aIter[ pSorter->aTree[1] ]; *pnKey = pIter->nKey; pKey = pIter->aKey; }else{ *pnKey = pSorter->pRecord->nVal; pKey = pSorter->pRecord->pVal; } return pKey; } /* ** Copy the current sorter key into the memory cell pOut. */ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ VdbeSorter *pSorter = pCsr->pSorter; void *pKey; int nKey; /* Sorter key to copy into pOut */ pKey = vdbeSorterRowkey(pSorter, &nKey); if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ return SQLITE_NOMEM; } pOut->n = nKey; MemSetTypeFlag(pOut, MEM_Blob); memcpy(pOut->z, pKey, nKey); return SQLITE_OK; } /* ** Compare the key in memory cell pVal with the key that the sorter cursor ** passed as the first argument currently points to. For the purposes of ** the comparison, ignore the rowid field at the end of each record. ** ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). ** Otherwise, set *pRes to a negative, zero or positive value if the ** key in pVal is smaller than, equal to or larger than the current sorter ** key. */ SQLITE_PRIVATE int sqlite3VdbeSorterCompare( VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal, /* Value to compare to current sorter key */ int *pRes /* OUT: Result of comparison */ ){ VdbeSorter *pSorter = pCsr->pSorter; void *pKey; int nKey; /* Sorter key to compare pVal with */ pKey = vdbeSorterRowkey(pSorter, &nKey); vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); return SQLITE_OK; } #endif /* #ifndef SQLITE_OMIT_MERGE_SORT */ /************** End of vdbesort.c ********************************************/ /************** Begin file journal.c *****************************************/ /* ** 2007 August 22 |
︙ | ︙ | |||
73697 73698 73699 73700 73701 73702 73703 | struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; | > | | 73916 73917 73918 73919 73920 73921 73922 73923 73924 73925 73926 73927 73928 73929 73930 73931 | struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; pNewItem->addrFillSub = pOldItem->addrFillSub; pNewItem->regReturn = pOldItem->regReturn; pNewItem->isCorrelated = pOldItem->isCorrelated; pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); pNewItem->notIndexed = pOldItem->notIndexed; pNewItem->pIndex = pOldItem->pIndex; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; |
︙ | ︙ | |||
74257 74258 74259 74260 74261 74262 74263 | ** successful here. */ assert(v); if( iCol<0 ){ int iMem = ++pParse->nMem; int iAddr; | | < | 74477 74478 74479 74480 74481 74482 74483 74484 74485 74486 74487 74488 74489 74490 74491 | ** successful here. */ assert(v); if( iCol<0 ){ int iMem = ++pParse->nMem; int iAddr; iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; sqlite3VdbeJumpHere(v, iAddr); }else{ Index *pIdx; /* Iterator variable */ |
︙ | ︙ | |||
74289 74290 74291 74292 74293 74294 74295 | && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ int iMem = ++pParse->nMem; int iAddr; char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); | | < | 74508 74509 74510 74511 74512 74513 74514 74515 74516 74517 74518 74519 74520 74521 74522 | && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ int iMem = ++pParse->nMem; int iAddr; char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); eType = IN_INDEX_INDEX; sqlite3VdbeJumpHere(v, iAddr); |
︙ | ︙ | |||
74371 74372 74373 74374 74375 74376 74377 | #ifndef SQLITE_OMIT_SUBQUERY SQLITE_PRIVATE int sqlite3CodeSubselect( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ int isRowid /* If true, LHS of IN operator is a rowid */ ){ | | < | < | | 74589 74590 74591 74592 74593 74594 74595 74596 74597 74598 74599 74600 74601 74602 74603 74604 74605 74606 74607 74608 74609 74610 74611 74612 74613 74614 74615 74616 74617 74618 74619 74620 74621 74622 74623 74624 74625 74626 74627 | #ifndef SQLITE_OMIT_SUBQUERY SQLITE_PRIVATE int sqlite3CodeSubselect( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ int rMayHaveNull, /* Register that records whether NULLs exist in RHS */ int isRowid /* If true, LHS of IN operator is a rowid */ ){ int testAddr = -1; /* One-time test address */ int rReg = 0; /* Register storing resulting */ Vdbe *v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return 0; sqlite3ExprCachePush(pParse); /* This code must be run in its entirety every time it is encountered ** if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ int mem = ++pParse->nMem; testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); } #ifndef SQLITE_OMIT_EXPLAIN if( pParse->explain==2 ){ char *zMsg = sqlite3MPrintf( pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ", pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId ); sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); } #endif switch( pExpr->op ){ |
︙ | ︙ | |||
74489 74490 74491 74492 74493 74494 74495 | int iValToIns; /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ | | | | | 74705 74706 74707 74708 74709 74710 74711 74712 74713 74714 74715 74716 74717 74718 74719 74720 74721 | int iValToIns; /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){ sqlite3VdbeChangeToNoop(v, testAddr); testAddr = -1; } /* Evaluate the expression and insert it into the temp table */ if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); }else{ r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); |
︙ | ︙ | |||
74560 74561 74562 74563 74564 74565 74566 | } rReg = dest.iParm; ExprSetIrreducible(pExpr); break; } } | | | | 74776 74777 74778 74779 74780 74781 74782 74783 74784 74785 74786 74787 74788 74789 74790 74791 | } rReg = dest.iParm; ExprSetIrreducible(pExpr); break; } } if( testAddr>=0 ){ sqlite3VdbeJumpHere(v, testAddr); } sqlite3ExprCachePop(pParse, 1); return rReg; } #endif /* SQLITE_OMIT_SUBQUERY */ |
︙ | ︙ | |||
75083 75084 75085 75086 75087 75088 75089 | AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ assert( pCol->iMem>0 ); inReg = pCol->iMem; break; }else if( pAggInfo->useSortingIdx ){ | | | 75299 75300 75301 75302 75303 75304 75305 75306 75307 75308 75309 75310 75311 75312 75313 | AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ assert( pCol->iMem>0 ); inReg = pCol->iMem; break; }else if( pAggInfo->useSortingIdx ){ sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); break; } /* Otherwise, fall thru into the TK_COLUMN case */ } case TK_COLUMN: { if( pExpr->iTable<0 ){ |
︙ | ︙ | |||
81241 81242 81243 81244 81245 81246 81247 81248 81249 81250 81251 81252 81253 81254 81255 | */ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ int addr1; /* Address of top of loop */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regIdxKey; /* Registers containing the index key */ int regRecord; /* Register holding assemblied index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); | > < < < < < < < < < | 81457 81458 81459 81460 81461 81462 81463 81464 81465 81466 81467 81468 81469 81470 81471 81472 81473 81474 81475 81476 81477 81478 81479 | */ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */ int addr1; /* Address of top of loop */ int addr2; /* Address to jump to for next iteration */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regIdxKey; /* Registers containing the index key */ int regRecord; /* Register holding assemblied index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, db->aDb[iDb].zName ) ){ return; } #endif |
︙ | ︙ | |||
81283 81284 81285 81286 81287 81288 81289 81290 | pKey = sqlite3IndexKeyinfo(pParse, pIndex); sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); if( memRootPage>=0 ){ sqlite3VdbeChangeP5(v, 1); } /* Open the sorter cursor if we are to use one. */ | > < | | | < > < > | | | | > > | > > > > > | > | > > > > | > | | 81491 81492 81493 81494 81495 81496 81497 81498 81499 81500 81501 81502 81503 81504 81505 81506 81507 81508 81509 81510 81511 81512 81513 81514 81515 81516 81517 81518 81519 81520 81521 81522 81523 81524 81525 81526 81527 81528 81529 81530 81531 81532 81533 81534 81535 81536 81537 81538 81539 81540 81541 81542 81543 81544 81545 81546 81547 81548 81549 81550 81551 81552 81553 81554 81555 81556 81557 81558 81559 81560 81561 | pKey = sqlite3IndexKeyinfo(pParse, pIndex); sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); if( memRootPage>=0 ){ sqlite3VdbeChangeP5(v, 1); } #ifndef SQLITE_OMIT_MERGE_SORT /* Open the sorter cursor if we are to use one. */ iSorter = pParse->nTab++; sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); #endif /* Open the table. Loop through all rows of the table, inserting index ** records into the sorter. */ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); addr2 = addr1 + 1; regRecord = sqlite3GetTempReg(pParse); regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1); #ifndef SQLITE_OMIT_MERGE_SORT sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); sqlite3VdbeJumpHere(v, addr1); addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); if( pIndex->onError!=OE_None ){ int j2 = sqlite3VdbeCurrentAddr(v) + 3; sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); addr2 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); sqlite3HaltConstraint( pParse, OE_Abort, "indexed columns are not unique", P4_STATIC ); }else{ addr2 = sqlite3VdbeCurrentAddr(v); } sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord); sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); #else if( pIndex->onError!=OE_None ){ const int regRowid = regIdxKey + pIndex->nColumn; const int j2 = sqlite3VdbeCurrentAddr(v) + 2; void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey); /* The registers accessed by the OP_IsUnique opcode were allocated ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey() ** call above. Just before that function was freed they were released ** (made available to the compiler for reuse) using ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique ** opcode use the values stored within seems dangerous. However, since ** we can be sure that no other temp registers have been allocated ** since sqlite3ReleaseTempRange() was called, it is safe to do so. */ sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); sqlite3HaltConstraint( pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); } sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); #endif sqlite3ReleaseTempReg(pParse, regRecord); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_Close, iTab); sqlite3VdbeAddOp1(v, OP_Close, iIdx); sqlite3VdbeAddOp1(v, OP_Close, iSorter); } |
︙ | ︙ | |||
92210 92211 92212 92213 92214 92215 92216 92217 92218 92219 92220 92221 92222 92223 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; if( db->mallocFailed ) { clearSelect(db, pNew); if( pNew!=&standin ) sqlite3DbFree(db, pNew); pNew = 0; } return pNew; } /* ** Delete the given Select structure and all of its substructures. */ | > > | 92431 92432 92433 92434 92435 92436 92437 92438 92439 92440 92441 92442 92443 92444 92445 92446 | pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; if( db->mallocFailed ) { clearSelect(db, pNew); if( pNew!=&standin ) sqlite3DbFree(db, pNew); pNew = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); } return pNew; } /* ** Delete the given Select structure and all of its substructures. */ |
︙ | ︙ | |||
92540 92541 92542 92543 92544 92545 92546 92547 92548 92549 92550 92551 | Select *pSelect, /* The whole SELECT statement */ int regData /* Register holding data to be sorted */ ){ Vdbe *v = pParse->pVdbe; int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); | > > > > > > | | 92763 92764 92765 92766 92767 92768 92769 92770 92771 92772 92773 92774 92775 92776 92777 92778 92779 92780 92781 92782 92783 92784 92785 92786 92787 92788 | Select *pSelect, /* The whole SELECT statement */ int regData /* Register holding data to be sorted */ ){ Vdbe *v = pParse->pVdbe; int nExpr = pOrderBy->nExpr; int regBase = sqlite3GetTempRange(pParse, nExpr+2); int regRecord = sqlite3GetTempReg(pParse); int op; sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); if( pSelect->selFlags & SF_UseSorter ){ op = OP_SorterInsert; }else{ op = OP_IdxInsert; } sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); if( pSelect->iLimit ){ int addr1, addr2; int iLimit; if( pSelect->iOffset ){ iLimit = pSelect->iOffset+1; |
︙ | ︙ | |||
93014 93015 93016 93017 93018 93019 93020 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ pseudoTab = pParse->nTab++; sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); regRowid = 0; }else{ regRowid = sqlite3GetTempReg(pParse); } | > > > > > > > > > > | | | > | 93243 93244 93245 93246 93247 93248 93249 93250 93251 93252 93253 93254 93255 93256 93257 93258 93259 93260 93261 93262 93263 93264 93265 93266 93267 93268 93269 93270 | if( eDest==SRT_Output || eDest==SRT_Coroutine ){ pseudoTab = pParse->nTab++; sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); regRowid = 0; }else{ regRowid = sqlite3GetTempReg(pParse); } if( p->selFlags & SF_UseSorter ){ int regSortOut = ++pParse->nMem; int ptab2 = pParse->nTab++; sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); codeOffset(v, p, addrContinue); sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); codeOffset(v, p, addrContinue); sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); } switch( eDest ){ case SRT_Table: case SRT_EphemTab: { testcase( eDest==SRT_Table ); testcase( eDest==SRT_EphemTab ); sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); |
︙ | ︙ | |||
93069 93070 93071 93072 93073 93074 93075 | } sqlite3ReleaseTempReg(pParse, regRow); sqlite3ReleaseTempReg(pParse, regRowid); /* The bottom of the loop */ sqlite3VdbeResolveLabel(v, addrContinue); | > > > | > | 93309 93310 93311 93312 93313 93314 93315 93316 93317 93318 93319 93320 93321 93322 93323 93324 93325 93326 93327 | } sqlite3ReleaseTempReg(pParse, regRow); sqlite3ReleaseTempReg(pParse, regRowid); /* The bottom of the loop */ sqlite3VdbeResolveLabel(v, addrContinue); if( p->selFlags & SF_UseSorter ){ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); }else{ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); } sqlite3VdbeResolveLabel(v, addrBreak); if( eDest==SRT_Output || eDest==SRT_Coroutine ){ sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); } } /* |
︙ | ︙ | |||
95901 95902 95903 95904 95905 95906 95907 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; Select *pSub = pItem->pSelect; int isAggSub; | | > > > > < > > > > > > > > > > > > > > > > > > > > > < < > > > > > | 96145 96146 96147 96148 96149 96150 96151 96152 96153 96154 96155 96156 96157 96158 96159 96160 96161 96162 96163 96164 96165 96166 96167 96168 96169 96170 96171 96172 96173 96174 96175 96176 96177 96178 96179 96180 96181 96182 96183 96184 96185 96186 96187 96188 96189 96190 96191 96192 96193 96194 96195 96196 96197 96198 96199 96200 96201 96202 96203 96204 96205 96206 96207 96208 96209 96210 96211 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ struct SrcList_item *pItem = &pTabList->a[i]; SelectDest dest; Select *pSub = pItem->pSelect; int isAggSub; if( pSub==0 ) continue; if( pItem->addrFillSub ){ sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); continue; } /* Increment Parse.nHeight by the height of the largest expression ** tree refered to by this, the parent select. The child select ** may contain expression trees of at most ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit ** more conservative than necessary, but much easier than enforcing ** an exact limit. */ pParse->nHeight += sqlite3SelectExprHeight(p); isAggSub = (pSub->selFlags & SF_Aggregate)!=0; if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ /* This subquery can be absorbed into its parent. */ if( isAggSub ){ isAgg = 1; p->selFlags |= SF_Aggregate; } i = -1; }else{ /* Generate a subroutine that will fill an ephemeral table with ** the content of this subquery. pItem->addrFillSub will point ** to the address of the generated subroutine. pItem->regReturn ** is a register allocated to hold the subroutine return address */ int topAddr; int onceAddr = 0; int retAddr; assert( pItem->addrFillSub==0 ); pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){ /* If the subquery is no correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ int regOnce = ++pParse->nMem; onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); } if( /*pParse->nErr ||*/ db->mallocFailed ){ goto select_end; } pParse->nHeight -= sqlite3SelectExprHeight(p); pTabList = p->pSrc; if( !IgnorableOrderby(pDest) ){ |
︙ | ︙ | |||
96035 96036 96037 96038 96039 96040 96041 96042 96043 96044 96045 96046 96047 96048 | } /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); p->nSelectRow = (double)LARGEST_INT64; computeLimitRegisters(pParse, p, iEnd); /* Open a virtual index to use for the distinct set. */ if( p->selFlags & SF_Distinct ){ KeyInfo *pKeyInfo; distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); | > > > > | 96306 96307 96308 96309 96310 96311 96312 96313 96314 96315 96316 96317 96318 96319 96320 96321 96322 96323 | } /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); p->nSelectRow = (double)LARGEST_INT64; computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && addrSortIndex>=0 ){ sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen; p->selFlags |= SF_UseSorter; } /* Open a virtual index to use for the distinct set. */ if( p->selFlags & SF_Distinct ){ KeyInfo *pKeyInfo; distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); |
︙ | ︙ | |||
96063 96064 96065 96066 96067 96068 96069 | if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral ** into an OP_Noop. */ if( addrSortIndex>=0 && pOrderBy==0 ){ | | | 96338 96339 96340 96341 96342 96343 96344 96345 96346 96347 96348 96349 96350 96351 96352 | if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral ** into an OP_Noop. */ if( addrSortIndex>=0 && pOrderBy==0 ){ sqlite3VdbeChangeToNoop(v, addrSortIndex); p->addrOpenEphm[2] = -1; } if( pWInfo->eDistinct ){ VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ assert( addrDistinctIndex>=0 ); |
︙ | ︙ | |||
96129 96130 96131 96132 96133 96134 96135 96136 96137 96138 96139 96140 96141 96142 | int iBMem; /* First Mem address for previous GROUP BY */ int iUseFlag; /* Mem address holding flag indicating that at least ** one row of the input to the aggregator has been ** processed */ int iAbortFlag; /* Mem address which causes query abort if positive */ int groupBySort; /* Rows come from source in GROUP BY order */ int addrEnd; /* End of processing for this SELECT */ /* Remove any and all aliases between the result set and the ** GROUP BY clause. */ if( pGroupBy ){ int k; /* Loop counter */ struct ExprList_item *pItem; /* For looping over expression in a list */ | > > | 96404 96405 96406 96407 96408 96409 96410 96411 96412 96413 96414 96415 96416 96417 96418 96419 | int iBMem; /* First Mem address for previous GROUP BY */ int iUseFlag; /* Mem address holding flag indicating that at least ** one row of the input to the aggregator has been ** processed */ int iAbortFlag; /* Mem address which causes query abort if positive */ int groupBySort; /* Rows come from source in GROUP BY order */ int addrEnd; /* End of processing for this SELECT */ int sortPTab = 0; /* Pseudotable used to decode sorting results */ int sortOut = 0; /* Output register from the sorter */ /* Remove any and all aliases between the result set and the ** GROUP BY clause. */ if( pGroupBy ){ int k; /* Loop counter */ struct ExprList_item *pItem; /* For looping over expression in a list */ |
︙ | ︙ | |||
96190 96191 96192 96193 96194 96195 96196 | int addrTopOfLoop; /* Top of the input loop */ int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ int regReset; /* Return address register for reset subroutine */ /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out | | | | 96467 96468 96469 96470 96471 96472 96473 96474 96475 96476 96477 96478 96479 96480 96481 96482 96483 96484 96485 96486 | int addrTopOfLoop; /* Top of the input loop */ int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ int regReset; /* Return address register for reset subroutine */ /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out ** that we do not need it after all, the OP_SorterOpen instruction ** will be converted into a Noop. */ sAggInfo.sortingIdx = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); /* Initialize memory locations used by GROUP BY aggregate processing */ iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; |
︙ | ︙ | |||
96276 96277 96278 96279 96280 96281 96282 | sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); } j++; } } regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); | | > > > | > > > | > | 96553 96554 96555 96556 96557 96558 96559 96560 96561 96562 96563 96564 96565 96566 96567 96568 96569 96570 96571 96572 96573 96574 96575 96576 96577 96578 96579 96580 96581 96582 96583 96584 96585 96586 96587 96588 96589 96590 96591 96592 96593 | sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); } j++; } } regRecord = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); sqlite3WhereEnd(pWInfo); sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); sAggInfo.useSortingIdx = 1; sqlite3ExprCacheClear(pParse); } /* Evaluate the current GROUP BY terms and store in b0, b1, b2... ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) ** Then compare the current GROUP BY terms against the GROUP BY terms ** from the previous row currently stored in a0, a1, a2... */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); sqlite3ExprCacheClear(pParse); if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut); } for(j=0; j<pGroupBy->nExpr; j++){ if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ sAggInfo.directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)pKeyInfo, P4_KEYINFO); |
︙ | ︙ | |||
96334 96335 96336 96337 96338 96339 96340 | updateAccumulator(pParse, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ | | | | 96618 96619 96620 96621 96622 96623 96624 96625 96626 96627 96628 96629 96630 96631 96632 96633 96634 96635 | updateAccumulator(pParse, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); }else{ sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } /* Output the final row of result */ sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output final row")); |
︙ | ︙ | |||
100523 100524 100525 100526 100527 100528 100529 100530 100531 100532 100533 100534 100535 100536 100537 100538 100539 100540 100541 | } } return mask; } static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ Bitmask mask = 0; while( pS ){ mask |= exprListTableUsage(pMaskSet, pS->pEList); mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); mask |= exprTableUsage(pMaskSet, pS->pWhere); mask |= exprTableUsage(pMaskSet, pS->pHaving); pS = pS->pPrior; } return mask; } /* ** Return TRUE if the given operator is one of the operators that is | > > > > > > > > | 100807 100808 100809 100810 100811 100812 100813 100814 100815 100816 100817 100818 100819 100820 100821 100822 100823 100824 100825 100826 100827 100828 100829 100830 100831 100832 100833 | } } return mask; } static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ Bitmask mask = 0; while( pS ){ SrcList *pSrc = pS->pSrc; mask |= exprListTableUsage(pMaskSet, pS->pEList); mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); mask |= exprTableUsage(pMaskSet, pS->pWhere); mask |= exprTableUsage(pMaskSet, pS->pHaving); if( ALWAYS(pSrc!=0) ){ int i; for(i=0; i<pSrc->nSrc; i++){ mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect); mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn); } } pS = pS->pPrior; } return mask; } /* ** Return TRUE if the given operator is one of the operators that is |
︙ | ︙ | |||
102050 102051 102052 102053 102054 102055 102056 | Bitmask extraCols; /* Bitmap of additional columns */ /* Generate code to skip over the creation and initialization of the ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); regIsInit = ++pParse->nMem; | | < | 102342 102343 102344 102345 102346 102347 102348 102349 102350 102351 102352 102353 102354 102355 102356 | Bitmask extraCols; /* Bitmap of additional columns */ /* Generate code to skip over the creation and initialization of the ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); regIsInit = ++pParse->nMem; addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ nColumn = 0; pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; idxCols = 0; |
︙ | ︙ | |||
115987 115988 115989 115990 115991 115992 115993 | char *p2 = a2; char *p; char *aOut; int bFirstOut = 0; *paOut = 0; *pnOut = 0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 116278 116279 116280 116281 116282 116283 116284 116285 116286 116287 116288 116289 116290 116291 116292 116293 116294 116295 116296 116297 116298 116299 116300 116301 116302 116303 116304 116305 116306 116307 116308 116309 116310 116311 116312 116313 116314 116315 116316 116317 116318 116319 116320 116321 116322 | char *p2 = a2; char *p; char *aOut; int bFirstOut = 0; *paOut = 0; *pnOut = 0; /* Allocate space for the output. Both the input and output doclists ** are delta encoded. If they are in ascending order (bDescDoclist==0), ** then the first docid in each list is simply encoded as a varint. For ** each subsequent docid, the varint stored is the difference between the ** current and previous docid (a positive number - since the list is in ** ascending order). ** ** The first docid written to the output is therefore encoded using the ** same number of bytes as it is in whichever of the input lists it is ** read from. And each subsequent docid read from the same input list ** consumes either the same or less bytes as it did in the input (since ** the difference between it and the previous value in the output must ** be a positive value less than or equal to the delta value read from ** the input list). The same argument applies to all but the first docid ** read from the 'other' list. And to the contents of all position lists ** that will be copied and merged from the input to the output. ** ** However, if the first docid copied to the output is a negative number, ** then the encoding of the first docid from the 'other' input list may ** be larger in the output than it was in the input (since the delta value ** may be a larger positive integer than the actual docid). ** ** The space required to store the output is therefore the sum of the ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** ** A symetric argument may be made if the doclists are in descending ** order. */ aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); if( !aOut ) return SQLITE_NOMEM; p = aOut; fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); while( p1 || p2 ){ sqlite3_int64 iDiff = DOCID_CMP(i1, i2); |
︙ | ︙ | |||
116014 116015 116016 116017 116018 116019 116020 116021 116022 116023 116024 116025 116026 116027 | fts3PoslistCopy(&p, &p2); fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); } } *paOut = aOut; *pnOut = (p-aOut); return SQLITE_OK; } /* ** This function does a "phrase" merge of two doclists. In a phrase merge, ** the output contains a copy of each position from the right-hand input ** doclist for which there is a position in the left-hand input doclist | > | 116335 116336 116337 116338 116339 116340 116341 116342 116343 116344 116345 116346 116347 116348 116349 | fts3PoslistCopy(&p, &p2); fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); } } *paOut = aOut; *pnOut = (p-aOut); assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); return SQLITE_OK; } /* ** This function does a "phrase" merge of two doclists. In a phrase merge, ** the output contains a copy of each position from the right-hand input ** doclist for which there is a position in the left-hand input doclist |
︙ | ︙ |
Changes to SQLite.Interop/src/core/sqlite3.h.
︙ | ︙ | |||
105 106 107 108 109 110 111 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.8" #define SQLITE_VERSION_NUMBER 3007008 | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.8" #define SQLITE_VERSION_NUMBER 3007008 #define SQLITE_SOURCE_ID "2011-09-17 15:34:50 29c4d0dd43d41650e54824afd70dd40f1b91cc86" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteConnection.cs.
︙ | ︙ | |||
661 662 663 664 665 666 667 | get { return _dataSource; } } /// <summary> | | | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | get { return _dataSource; } } /// <summary> /// Returns the string "main". /// </summary> #if !PLATFORM_COMPACTFRAMEWORK [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public override string Database { get |
︙ | ︙ | |||
963 964 965 966 967 968 969 970 971 972 973 974 975 976 | return SQLiteVersion; //if (_connectionState != ConnectionState.Open) // throw new InvalidOperationException(); //return _sql.Version; } } /// <summary> /// Returns the version of the underlying SQLite database engine /// </summary> public static string SQLiteVersion { get { return SQLite3.SQLiteVersion; } | > > > > > > > > > > > > > > > > > > | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 | return SQLiteVersion; //if (_connectionState != ConnectionState.Open) // throw new InvalidOperationException(); //return _sql.Version; } } /// <summary> /// Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on /// this connection. /// </summary> #if !PLATFORM_COMPACTFRAMEWORK [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] #endif public int Changes { get { if (_sql == null) throw new InvalidOperationException("Database connection not valid for getting number of changes."); return _sql.Changes; } } /// <summary> /// Returns the version of the underlying SQLite database engine /// </summary> public static string SQLiteVersion { get { return SQLite3.SQLiteVersion; } |
︙ | ︙ |