Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Adjustments to the implementation of LIMIT so that it uses fewer opcodes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
39d5b292d27faf00ab58ff4074f91f7a |
User & Date: | drh 2009-11-12 03:13:26.000 |
Context
2009-11-12
| ||
03:46 | Suppress excess OP_Null opcodes caused by binary IS or IS NOT operators that are converted into unary ISNULL or NOTNULL operators. (check-in: cff1b36ab2 user: drh tags: trunk) | |
03:13 | Adjustments to the implementation of LIMIT so that it uses fewer opcodes. (check-in: 39d5b292d2 user: drh tags: trunk) | |
2009-11-11
| ||
23:58 | If the sector size is unspecified (initially 0) then set it to 512, not to 32. (check-in: 8861b5c160 user: drh tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
677 678 679 680 681 682 683 | } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ assert( pOrderBy==0 ); /* If there is an ORDER BY, the call to ** pushOntoSorter() would have cleared p->iLimit */ | < | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ assert( pOrderBy==0 ); /* If there is an ORDER BY, the call to ** pushOntoSorter() would have cleared p->iLimit */ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); } } /* ** Given an expression list, generate a KeyInfo structure that records ** the collating sequence for each expression in that expression list. ** |
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 | ** the reuse of the same limit and offset registers across multiple ** SELECT statements. */ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ Vdbe *v = 0; int iLimit = 0; int iOffset; | | > > > > > > > > | | | | > | 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 | ** the reuse of the same limit and offset registers across multiple ** SELECT statements. */ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ Vdbe *v = 0; int iLimit = 0; int iOffset; int addr1, n; if( p->iLimit ) return; /* ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ sqlite3ExprCacheClear(pParse); assert( p->pOffset==0 || p->pLimit!=0 ); if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return; /* VDBE should have already been allocated */ if( sqlite3ExprIsInteger(p->pLimit, &n) ){ if( n==0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); }else{ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); } }else{ sqlite3ExprCode(pParse, p->pLimit, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ sqlite3ExprCode(pParse, p->pOffset, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); |
︙ | ︙ | |||
1877 1878 1879 1880 1881 1882 1883 | break; } } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ | < | | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 | break; } } /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); } /* Generate the subroutine return */ sqlite3VdbeResolveLabel(v, iContinue); sqlite3VdbeAddOp1(v, OP_Return, regReturn); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
5021 5022 5023 5024 5025 5026 5027 | assert( pIn1->flags&MEM_Int ); if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } break; } | | > | > | 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 | assert( pIn1->flags&MEM_Int ); if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfZero P1 P2 P3 * * ** ** The register P1 must contain an integer. Add literal P3 to the ** value in register P1. If the result is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a register that does ** not contain an integer. An assertion fault will result if you try. */ case OP_IfZero: { /* jump, in1 */ assert( pIn1->flags&MEM_Int ); pIn1->u.i += pOp->p3; if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; } break; } /* Opcode: AggStep * P2 P3 P4 P5 |
︙ | ︙ |