Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the sorter logic to eliminate the need for pseudo-tables and remove the code that implemented them. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b9e5f3c6df1cd09036a5da7cda2c8cef |
User & Date: | drh 2013-07-30 02:47:27.137 |
Context
2013-07-30
| ||
11:55 | Reenable fts5 hooks in where.c. check-in: c748d90f94 user: dan tags: trunk | |
02:47 | Update the sorter logic to eliminate the need for pseudo-tables and remove the code that implemented them. check-in: b9e5f3c6df user: drh tags: trunk | |
02:11 | Provide more detail in the P4 column in EXPLAIN output. check-in: 34abc4149f user: drh tags: trunk | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
930 931 932 933 934 935 936 | iTab = pOrderBy->iECursor; regRow = sqlite4GetTempReg(pParse); if( eDest!=SRT_Output && eDest!=SRT_Coroutine ){ regRowid = sqlite4GetTempReg(pParse); } if( p->selFlags & SF_UseSorter ){ | < < < < | | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 | iTab = pOrderBy->iECursor; regRow = sqlite4GetTempReg(pParse); if( eDest!=SRT_Output && eDest!=SRT_Coroutine ){ regRowid = sqlite4GetTempReg(pParse); } if( p->selFlags & SF_UseSorter ){ addr = 1 + sqlite4VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); codeOffset(v, p, addrContinue); sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow); sqlite4VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ addr = 1 + sqlite4VdbeAddOp2(v, OP_Sort, iTab, addrBreak); codeOffset(v, p, addrContinue); sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRow); } switch( eDest ){ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
2810 2811 2812 2813 2814 2815 2816 | case OP_SorterOpen: { /* VdbeCursor *pCx; */ pOp->opcode = OP_OpenEphemeral; pc--; break; } | < < < < < < < < < < < < < < < < < < < < < < < < < < | 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 | case OP_SorterOpen: { /* VdbeCursor *pCx; */ pOp->opcode = OP_OpenEphemeral; pc--; break; } /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
︙ | ︙ | |||
2969 2970 2971 2972 2973 2974 2975 | pC->nullRow = 0; pC->sSeekKey.n = 0; pC->rowChnged = 1; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); assert( pC!=0 ); | < | 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 | pC->nullRow = 0; pC->sSeekKey.n = 0; pC->rowChnged = 1; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); assert( pC!=0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); /* Encode a database key consisting of the contents of the P4 registers ** starting at register P3. Have the vdbecodec module allocate an extra ** free byte at the end of the database key (see below). */ |
︙ | ︙ | |||
3495 3496 3497 3498 3499 3500 3501 | /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->nullRow==0 ); | < | 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 | /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->nullRow==0 ); assert( pC->pKVCur!=0 ); pCrsr = pC->pKVCur; if( pOp->opcode==OP_RowKey ){ rc = sqlite4KVCursorKey(pCrsr, &pData, &nData); if( pOp->p5 ){ nData = sqlite4VdbeShortKey(pData, nData, 1, 0); |
︙ | ︙ | |||
3551 3552 3553 3554 3555 3556 3557 | pKey = &aMem[pOp->p2]; aIncr = &aMem[pOp->p3]; nTotal = pOp->p4.i; pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->nullRow==0 ); | < | 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 | pKey = &aMem[pOp->p2]; aIncr = &aMem[pOp->p3]; nTotal = pOp->p4.i; pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->nullRow==0 ); assert( pC->pKVCur!=0 ); assert( pOp->p4type==P4_INT32 ); rc = sqlite4KVCursorKey(pC->pKVCur, &pNew, &nNew); if( rc==SQLITE4_OK ){ assert( pKey->flags & (MEM_Blob|MEM_Null) ); if( pKey->flags & MEM_Blob ){ |
︙ | ︙ | |||
3610 3611 3612 3613 3614 3615 3616 | sqlite4_num vNum; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->sSeekKey.n==0 ); | < | 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 | sqlite4_num vNum; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->sSeekKey.n==0 ); if( pC->nullRow ){ pOut->flags = MEM_Null; break; #ifndef SQLITE4_OMIT_VIRTUALTABLE }else if( pC->pVtabCursor ){ pVtab = pC->pVtabCursor->pVtab; pModule = pVtab->pModule; |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
56 57 58 59 60 61 62 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int iDb; /* Index of cursor database in db->aDb[] (or -1) */ int iRoot; /* Root page of the table */ int nField; /* Number of fields in the header */ Bool nullRow; /* True if pointing to a row with no data */ Bool rowChnged; /* True if row has changed out from under pDecoder */ i64 seqCount; /* Sequence counter */ | < | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int iDb; /* Index of cursor database in db->aDb[] (or -1) */ int iRoot; /* Root page of the table */ int nField; /* Number of fields in the header */ Bool nullRow; /* True if pointing to a row with no data */ Bool rowChnged; /* True if row has changed out from under pDecoder */ i64 seqCount; /* Sequence counter */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ Fts5Cursor *pFts; /* Fts5 cursor object (or NULL) */ RowDecoder *pDecoder; /* Decoder for row content */ sqlite4_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite4_module *pModule; /* Module for cursor pVtabCursor */ sqlite4_buffer sSeekKey; /* Key for deferred seek */ }; |
︙ | ︙ |
Changes to src/vdbecodec.c.
︙ | ︙ | |||
85 86 87 88 89 90 91 | if( pCur==0 ){ rc = sqlite4KVCursorData(p->pKVCur, 0, -1, &p->a, &p->n); return rc; } if( pCur->rowChnged ){ p->a = 0; p->aKey = 0; | | | | < < < < < < < < | | < < < < < < < < | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | if( pCur==0 ){ rc = sqlite4KVCursorData(p->pKVCur, 0, -1, &p->a, &p->n); return rc; } if( pCur->rowChnged ){ p->a = 0; p->aKey = 0; pCur->rowChnged = 0; } if( p->a ) return SQLITE4_OK; rc = sqlite4VdbeCursorMoveto(pCur); if( rc ) return rc; if( pCur->nullRow ){ p->a = 0; p->n = 0; return SQLITE4_OK; } assert( pCur->pKVCur!=0 ); return sqlite4KVCursorData(pCur->pKVCur, 0, -1, &p->a, &p->n); } /* ** Make sure the p->aKey and p->nKey fields are valid and current. */ static int decoderFetchKey(RowDecoder *p){ VdbeCursor *pCur = p->pCur; int rc; if( pCur==0 ){ rc = sqlite4KVCursorKey(p->pKVCur, &p->aKey, &p->nKey); return rc; } assert( p->a!=0 ); if( p->aKey ) return SQLITE4_OK; assert( pCur->pKVCur!=0 ); return sqlite4KVCursorKey(pCur->pKVCur, &p->aKey, &p->nKey); } /* ** Decode a blob from a key. The blob-key is in a[0] through a[n-1]. ** xorMask is either 0x00 for ascending order or 0xff for descending. ** Store the blob in pOut. */ |
︙ | ︙ |