mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Improved comments on the OP_Column changes. Optimize out loading of overflow
pages for content with zero length. Add test cases for the latter. FossilOrigin-Name: 0e05679db7aa302a49e087a81f85203844b98cbe
This commit is contained in:
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Further\sperformance\stweaks\sto\sOP_Column.
|
C Improved\scomments\son\sthe\sOP_Column\schanges.\s\sOptimize\sout\sloading\sof\soverflow\npages\sfor\scontent\swith\szero\slength.\s\sAdd\stest\scases\sfor\sthe\slatter.
|
||||||
D 2013-11-20T19:28:03.982
|
D 2013-11-20T20:58:00.360
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0
|
|||||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||||
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
|
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
|
||||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||||
F src/vdbe.c 1a6e2c9413fca3b2d00c49e85a861e0adc8b6c6a
|
F src/vdbe.c 987f375b8ba5b5c3d0ded64191f72706221f76f9
|
||||||
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
|
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
|
||||||
F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72
|
F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72
|
||||||
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
|
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
|
||||||
@ -573,7 +573,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584
|
|||||||
F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057
|
F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057
|
||||||
F test/fts4unicode.test e28ba1a14181e709dcdf47455f207adf14c7cfe0
|
F test/fts4unicode.test e28ba1a14181e709dcdf47455f207adf14c7cfe0
|
||||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||||
F test/func.test c7e80a44eebac8604397eb2ad83d0d5d9d541237
|
F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8
|
||||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||||
F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
|
F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
|
||||||
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
|
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
|
||||||
@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 7c914e3997d2b28164a2fa7eb4398262b6ddb4b2
|
P 0e3f5df695216a27602a53eed5d25231b055adc8
|
||||||
R 72749b37eba95a49879e9308fdcd90bb
|
R 7b4a6a3b4e08d369fabb1ea696a3ba02
|
||||||
U drh
|
U drh
|
||||||
Z 441207295dddfadd80f4cc85b77f0a53
|
Z a02194f256e2495862011254263d6e91
|
||||||
|
@ -1 +1 @@
|
|||||||
0e3f5df695216a27602a53eed5d25231b055adc8
|
0e05679db7aa302a49e087a81f85203844b98cbe
|
46
src/vdbe.c
46
src/vdbe.c
@ -2284,11 +2284,11 @@ case OP_Column: {
|
|||||||
aType = pC->aType;
|
aType = pC->aType;
|
||||||
aOffset = pC->aOffset;
|
aOffset = pC->aOffset;
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
assert( pC->pVtabCursor==0 );
|
assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
|
||||||
#endif
|
#endif
|
||||||
pCrsr = pC->pCursor;
|
pCrsr = pC->pCursor;
|
||||||
assert( pCrsr!=0 || pC->pseudoTableReg>0 );
|
assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
|
||||||
assert( pC->pseudoTableReg==0 || pC->nullRow );
|
assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
|
||||||
|
|
||||||
/* If the cursor cache is stale, bring it up-to-date */
|
/* If the cursor cache is stale, bring it up-to-date */
|
||||||
rc = sqlite3VdbeCursorMoveto(pC);
|
rc = sqlite3VdbeCursorMoveto(pC);
|
||||||
@ -2339,12 +2339,15 @@ case OP_Column: {
|
|||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pC->cacheStatus = p->cacheCtr;
|
pC->cacheStatus = p->cacheCtr;
|
||||||
pC->iHdrOffset = getVarint32(pC->aRow, offset);
|
pC->iHdrOffset = getVarint32(pC->aRow, offset);
|
||||||
pC->nHdrParsed = 0;
|
pC->nHdrParsed = 0;
|
||||||
aOffset[0] = offset;
|
aOffset[0] = offset;
|
||||||
if( avail<offset ){
|
if( avail<offset ){
|
||||||
|
/* pC->aRow does not have to hold the entire row, but it does at least
|
||||||
|
** need to cover the header of the record. If pC->aRow does not contain
|
||||||
|
** the complete header, then set it to zero, forcing the header to be
|
||||||
|
** dynamically allocated. */
|
||||||
pC->aRow = 0;
|
pC->aRow = 0;
|
||||||
pC->szRow = 0;
|
pC->szRow = 0;
|
||||||
}
|
}
|
||||||
@ -2368,8 +2371,8 @@ case OP_Column: {
|
|||||||
** parsed and valid information is in aOffset[] and aType[].
|
** parsed and valid information is in aOffset[] and aType[].
|
||||||
*/
|
*/
|
||||||
if( pC->nHdrParsed<=p2 ){
|
if( pC->nHdrParsed<=p2 ){
|
||||||
/* If there is more header available for parsing, try to extract
|
/* If there is more header available for parsing in the record, try
|
||||||
** additional fields up through the p2-th field
|
** to extract additional fields up through the p2+1-th field
|
||||||
*/
|
*/
|
||||||
if( pC->iHdrOffset<aOffset[0] ){
|
if( pC->iHdrOffset<aOffset[0] ){
|
||||||
/* Make sure zData points to enough of the record to cover the header. */
|
/* Make sure zData points to enough of the record to cover the header. */
|
||||||
@ -2430,9 +2433,10 @@ case OP_Column: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If after nHdrParsed is still not up to p2, that means that the record
|
/* If after trying to extra new entries from the header, nHdrParsed is
|
||||||
** has fewer than p2 columns. So the result will be either the default
|
** still not up to p2, that means that the record has fewer than p2
|
||||||
** value or a NULL. */
|
** columns. So the result will be either the default value or a NULL.
|
||||||
|
*/
|
||||||
if( pC->nHdrParsed<=p2 ){
|
if( pC->nHdrParsed<=p2 ){
|
||||||
if( pOp->p4type==P4_MEM ){
|
if( pOp->p4type==P4_MEM ){
|
||||||
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
|
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
|
||||||
@ -2443,33 +2447,33 @@ case OP_Column: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the column information. If aOffset[p2] is non-zero, then
|
/* Extract the content for the p2+1-th column. Control can only
|
||||||
** deserialize the value from the record. If aOffset[p2] is zero,
|
** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are
|
||||||
** then there are not enough fields in the record to satisfy the
|
** all valid.
|
||||||
** request. In this case, set the value NULL or to P4 if P4 is
|
|
||||||
** a pointer to a Mem object.
|
|
||||||
*/
|
*/
|
||||||
assert( p2<pC->nHdrParsed );
|
assert( p2<pC->nHdrParsed );
|
||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
if( pC->szRow>=aOffset[p2+1] ){
|
if( pC->szRow>=aOffset[p2+1] ){
|
||||||
/* This is the common case where the whole row fits on a single page */
|
/* This is the common case where the desired content fits on the original
|
||||||
|
** page - where the content is not on an overflow page */
|
||||||
VdbeMemRelease(pDest);
|
VdbeMemRelease(pDest);
|
||||||
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
|
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
|
||||||
}else{
|
}else{
|
||||||
/* This branch happens only when the row overflows onto multiple pages */
|
/* This branch happens only when content is on overflow pages */
|
||||||
t = aType[p2];
|
t = aType[p2];
|
||||||
if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
|
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
|
||||||
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
|
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
|
||||||
|
|| (len = sqlite3VdbeSerialTypeLen(t))==0
|
||||||
){
|
){
|
||||||
/* Content is irrelevant for the typeof() function and for
|
/* Content is irrelevant for the typeof() function and for
|
||||||
** the length(X) function if X is a blob. So we might as well use
|
** the length(X) function if X is a blob. So we might as well use
|
||||||
** bogus content rather than reading content from disk. NULL works
|
** bogus content rather than reading content from disk. NULL works
|
||||||
** for text and blob and whatever is in the payloadSize64 variable
|
** for text and blob and whatever is in the payloadSize64 variable
|
||||||
** will work for everything else. */
|
** will work for everything else. Content is also irrelevant if
|
||||||
zData = t<12 ? (u8*)&payloadSize64 : 0;
|
** the content length is 0. */
|
||||||
|
zData = t<=13 ? (u8*)&payloadSize64 : 0;
|
||||||
sMem.zMalloc = 0;
|
sMem.zMalloc = 0;
|
||||||
}else{
|
}else{
|
||||||
len = sqlite3VdbeSerialTypeLen(t);
|
|
||||||
memset(&sMem, 0, sizeof(sMem));
|
memset(&sMem, 0, sizeof(sMem));
|
||||||
sqlite3VdbeMemMove(&sMem, pDest);
|
sqlite3VdbeMemMove(&sMem, pDest);
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,
|
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,
|
||||||
|
@ -1319,6 +1319,24 @@ do_test func-29.6 {
|
|||||||
set x
|
set x
|
||||||
} {1}
|
} {1}
|
||||||
|
|
||||||
|
# The OP_Column opcode has an optimization that avoids loading content
|
||||||
|
# for fields with content-length=0 when the content offset is on an overflow
|
||||||
|
# page. Make sure the optimization works.
|
||||||
|
#
|
||||||
|
do_execsql_test func-29.10 {
|
||||||
|
CREATE TABLE t29b(a,b,c,d,e,f,g,h,i);
|
||||||
|
INSERT INTO t29b
|
||||||
|
VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01');
|
||||||
|
SELECT typeof(c), typeof(d), typeof(e), typeof(f),
|
||||||
|
typeof(g), typeof(h), typeof(i) FROM t29b;
|
||||||
|
} {null integer integer text blob text blob}
|
||||||
|
do_execsql_test func-29.11 {
|
||||||
|
SELECT length(f), length(g), length(h), length(i) FROM t29b;
|
||||||
|
} {0 0 1 1}
|
||||||
|
do_execsql_test func-29.12 {
|
||||||
|
SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b;
|
||||||
|
} {'' X'' 'x' X'01'}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric
|
# EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric
|
||||||
# unicode code point corresponding to the first character of the string
|
# unicode code point corresponding to the first character of the string
|
||||||
# X.
|
# X.
|
||||||
|
Reference in New Issue
Block a user