Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch branch-3.28-in-early-out-fail Excluding Merge-Ins
This is equivalent to a diff from 0ecda43371 to 8301da31d0
2020-09-01
| ||
02:02 | Improvements to the IN-early-out optimization so that it works more efficiently when there are two or more indexed IN clauses on a single table. (check-in: 49b7631e86 user: drh tags: branch-3.28) | |
2020-08-31
| ||
19:19 | An attempt to improve the performance of the IN-early-out optimization (see check-in [09fffbdf9f2f6ce3]) by avoiding unnecessary calls to the b-tree search algorithm in OP_IfNoHope when the index key is at hand and the same answer can be obtained by doing a quick key comparison. Update: Experiment did not work out. (Closed-Leaf check-in: 8301da31d0 user: drh tags: branch-3.28-in-early-out-fail) | |
16:31 | An attempt to improve the performance of the IN-early-out optimization (see check-in [09fffbdf9f2f6ce3]) by avoiding unnecessary calls to the b-tree search algorithm in OP_IfNoHope when the index key is at hand and the same answer can be obtained by doing a quick key comparison. Update 2020-08-31: This experiment did not work out. A better approach is now on trunk. (check-in: e9d983c683 user: drh tags: in-early-out-fail) | |
2020-08-17
| ||
21:03 | When doing an UPDATE or DELETE using a multi-column index where only a few of the earlier columns of the index are useful for the index lookup, postpone doing the main table seek until after all WHERE clause constraints have been evaluated, in case those constraints can be covered by unused later terms of the index, thus avoiding unnecessary main table seeks. (check-in: 0ecda43371 user: dan tags: branch-3.28) | |
2020-08-14
| ||
21:51 | When doing an UPDATE or DELETE using a multi-column index where only a few of the earlier columns of the index are useful for the index lookup, postpone doing the main table seek until after all WHERE clause constraints have been evaluated, in case those constraints can be covered by unused later terms of the index, thus avoiding unnecessary main table seeks. (check-in: 7fee0b1075 user: drh tags: trunk) | |
2020-05-06
| ||
18:46 | Provide the SQLITE_DEFAULT_LEGACY_ALTER_TABLE compile-time option. (check-in: b2325a6e1c user: drh tags: branch-3.28) | |
Changes to src/vdbe.c.
︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | */ #if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE) # define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) #else # define UPDATE_MAX_BLOBSIZE(P) #endif #ifdef SQLITE_DEBUG /* This is a validation routine that occurs only inside of assert() ** statements. Its purpose is to verify that the generated bytecode ** is correct. It only runs on debugging builds. ** ** Verify that the pOp opcode is an OP_SeekGE or OP_SeekLE that is ** followed by a corresponding OP_IdxGT or OP_IdxLT, possibly with ** an intervening OP_SeekHit. Return 1 if the constraint is true. ** Return 0 if something unexpected is seen. */ static int seekFollowedByPairedIdxCompare(VdbeOp *pOp){ VdbeOp *pNext; /* Find the subsequent opcode. We are allowed to skip over a single ** OP_SeekHit against the same cursor with a P2 value of 1. */ pNext = pOp + 1; if( pNext->opcode==OP_SeekHit ){ if( pNext->p2!=1 ) return 0; if( pNext->p1!=pOp->p1 ) return 0; pNext++; } /* This routine verifies that the opcodes are correct for a ** BTREE_SEEK_EQ lookup. So the two opcodes involved must be either: ** ** * OP_SeekGE followed by OP_IdxGT ** * OP_SeekLE followed by OP_IdxLT */ if( pOp->opcode==OP_SeekGE ){ if( pNext->opcode!=OP_IdxGT ) return 0; }else if( pOp->opcode==OP_SeekLE ){ if( pNext->opcode!=OP_IdxLT ) return 0; }else{ return 0; } /* The OP_SeekXX and OP_IdxXX must have the same arguments. */ if( pOp->p1!=pNext->p1 ) return 0; if( pOp->p2!=pNext->p2 ) return 0; if( pOp->p3!=pNext->p3 ) return 0; if( pOp->p4.i!=pNext->p4.i ) return 0; return 1; } #endif /* SQLITE_DEBUG */ /* ** Invoke the VDBE coverage callback, if that callback is defined. This ** feature is used for test suite validation only and does not appear an ** production builds. ** ** M is the type of branch. I is the direction taken for this instance of ** the branch. |
︙ | |||
4003 4004 4005 4006 4007 4008 4009 | 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 | - - - + + + + + - + - - - + - - - | } rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ if( rc!=SQLITE_OK ){ goto abort_due_to_error; } }else{ |
︙ | |||
4096 4097 4098 4099 4100 4101 4102 | 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 | - - + + - - + + - - + + | } seek_not_found: assert( pOp->p2>0 ); VdbeBranchTaken(res!=0,2); if( res ){ goto jump_to_p2; }else if( eqOnly ){ |
︙ | |||
4157 4158 4159 4160 4161 4162 4163 | 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 | - - - - - - - - - - - - - - - - - - - - - - - - - - - | ** ** This operation leaves the cursor in a state where it cannot be ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** ** See also: Found, NotExists, NoConflict, IfNoHope */ |
︙ | |||
4207 4208 4209 4210 4211 4212 4213 | 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 | - - - - - - - - + | ** ** This operation leaves the cursor in a state where it cannot be ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** ** See also: NotFound, Found, NotExists */ |
︙ | |||
5538 5539 5540 5541 5542 5543 5544 | 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 | - - - - + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | ** key that omits the PRIMARY KEY or ROWID. Compare this key value against ** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or ** ROWID on the P1 index. ** ** If the P1 index entry is less than or equal to the key value then jump ** to P2. Otherwise fall through to the next instruction. */ |
︙ |
Changes to src/vdbeInt.h.
︙ | |||
81 82 83 84 85 86 87 | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | - + | #ifdef SQLITE_DEBUG u8 seekOp; /* Most recent seek operation on this cursor */ u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ |
︙ |
Changes to src/wherecode.c.
︙ | |||
1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 | 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 | + + + - + | sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); } op = aEndOp[bRev*2 + endEq]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ |
︙ |