Compare commits

..

1 Commits

Author SHA1 Message Date
drh 4b973dfd11 Experiments with an OP_Unpack opcode that extracts multiple columns from
a record without caching.

FossilOrigin-Name: 39ae92f5c63de4b95502f438dc7e9f2669efdf91
2015-10-15 20:17:15 +00:00
17 changed files with 180 additions and 197 deletions
+6 -8
View File
@@ -292,9 +292,9 @@ NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
# will run on the platform that is doing the build.
#
!IF $(USE_FULLWARN)!=0
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
BCC = $(NCC) -nologo -W4
!ELSE
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
BCC = $(NCC) -nologo -W3
!ENDIF
# Check if assembly code listings should be generated for the source
@@ -322,13 +322,13 @@ NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
# same unless your are cross-compiling.)
#
!IF $(USE_FULLWARN)!=0
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1
!ELSE
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
TCC = $(CC) -nologo -W3
!ENDIF
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
# Check if we want to use the "stdcall" calling convention when compiling.
# This is not supported by the compilers for non-x86 platforms. It should
@@ -800,9 +800,7 @@ LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
# If either debugging or symbols are enabled, enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
LDFLAGS = /DEBUG $(LDOPTS)
!ELSE
LDFLAGS = $(LDOPTS)
LDFLAGS = /DEBUG
!ENDIF
# Start with the Tcl related linker options.
+1 -1
View File
@@ -1 +1 @@
3.9.1
3.9.0
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.9.1.
# Generated by GNU Autoconf 2.69 for sqlite 3.9.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.9.1'
PACKAGE_STRING='sqlite 3.9.1'
PACKAGE_VERSION='3.9.0'
PACKAGE_STRING='sqlite 3.9.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1458,7 +1458,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.9.1 to adapt to many kinds of systems.
\`configure' configures sqlite 3.9.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1523,7 +1523,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.9.1:";;
short | recursive ) echo "Configuration of sqlite 3.9.0:";;
esac
cat <<\_ACEOF
@@ -1643,7 +1643,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.9.1
sqlite configure 3.9.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2062,7 +2062,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.9.1, which was
It was created by sqlite $as_me 3.9.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -11946,7 +11946,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.9.1, which was
This file was extended by sqlite $as_me 3.9.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12012,7 +12012,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.9.1
sqlite config.status 3.9.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+5 -19
View File
@@ -28,6 +28,7 @@
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h> /* amalgamator: keep */
#include <stdlib.h>
#include <stdarg.h>
@@ -42,17 +43,8 @@ SQLITE_EXTENSION_INIT1
** Versions of isspace(), isalnum() and isdigit() to which it is safe
** to pass signed char values.
*/
#ifdef sqlite3Isdigit
/* Use the SQLite core versions if this routine is part of the
** SQLite amalgamation */
# define safe_isdigit(x) sqlite3Isdigit(x)
# define safe_isalnum(x) sqlite3Isalnum(x)
#else
/* Use the standard library for separate compilation */
#include <ctype.h> /* amalgamator: keep */
# define safe_isdigit(x) isdigit((unsigned char)(x))
# define safe_isalnum(x) isalnum((unsigned char)(x))
#endif
#define safe_isdigit(x) isdigit((unsigned char)(x))
#define safe_isalnum(x) isalnum((unsigned char)(x))
/*
** Growing our own isspace() routine this way is twice as fast as
@@ -60,7 +52,7 @@ SQLITE_EXTENSION_INIT1
** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
*/
static const char jsonIsSpace[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -522,13 +514,7 @@ static void jsonReturn(
int_as_real: /* fall through to real */;
}
case JSON_REAL: {
double r;
#ifdef SQLITE_AMALGAMATION
const char *z = pNode->u.zJContent;
sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
#else
r = strtod(pNode->u.zJContent, 0);
#endif
double r = strtod(pNode->u.zJContent, 0);
sqlite3_result_double(pCtx, r);
break;
}
+22 -22
View File
@@ -1,10 +1,10 @@
C Change\sthe\scode\sgenerator\sfor\sUPDATE\sto\sgenerate\scode\sin\san\sorder\sthat\smight\nrun\smore\sefficiently\sin\smany\scases.
D 2015-10-17T01:00:03.352
C Experiments\swith\san\sOP_Unpack\sopcode\sthat\sextracts\smultiple\scolumns\sfrom\na\srecord\swithout\scaching.
D 2015-10-15T20:17:15.103
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e
F Makefile.msc 8e42cb55739cd8c12e1fd25401956e2019448f6a
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION a47917b59f38b632b3a8662d14fd20f94956bdd0
F VERSION cacf16a72f9a03cd06b939a764e32f6f53254c7f
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -35,7 +35,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 762a66c6eb9331f8af21f5d00b610bd61eaf8e14 x
F configure 99485c9c0446d1236a78a53de6f2737f45f0aca5 x
F configure.ac f36bd4fb8c53eed8374c5a5ef319807c08c23fa9
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -195,7 +195,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
F ext/misc/json1.c 4f45afd9dbcd6feca8c528251efbb7fc09299a09
F ext/misc/json1.c fed5b948168f26f39e67d898b03d93dd00e75196
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
@@ -280,7 +280,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af
F src/btree.c 0b74bc28b2dc907cba03b5b4b3b81584273be699
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
@@ -290,7 +290,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44
F src/expr.c d9896fda47a8f67d0ed203e1fa981444424200c6
F src/expr.c e8765542b21bc7ff801ca82d5cf11f0b13a219af
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
@@ -338,7 +338,7 @@ F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c dbf1fb82317043304da334a33206add211487f96
F src/select.c a4478981ce53cb7e28d0252417deece6ad5fe693
F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
@@ -397,17 +397,17 @@ F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22
F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 04ed5f0334d313221cd084d46c5c2e0ad29ecb52
F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c e9315575bed64f9aa559151283c873be34143914
F src/vdbe.c a0a2aea6a146e2479bdb7dba584f3e625ceccc30
F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
F src/vdbeInt.h 777dd76d513347acb1a71d94df2be00516add637
F src/vdbeInt.h 8b867eac234e28627ffcace3cd4b4b79bbec664b
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c 906bc74ea90707b57a23e4264727fff7b48d0cb5
F src/vdbeaux.c fd00b489ab3f44f2dca1e4344faf289b7bfcf649
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
F src/vdbemem.c 19b3036aa4d676e7103b0fb5efd6327da455f915
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
@@ -815,7 +815,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
F test/json101.test 83e6ebfb3cef6329853ab854403ec82b1787b537
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
@@ -1341,7 +1341,7 @@ F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/fuzzershell.c b36096cdbcb4af985a2d6c20093d61e55b49bfe1
F tool/fuzzershell.c 87cc3d6f00239d786d231954289f106131989cc7
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
@@ -1387,14 +1387,14 @@ F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 0df371d1a51c2028aefa4c704707773750317689
R 54a047417394c2361e73646ac2a70fb9
T *branch * improved-update
T *sym-improved-update *
P 871e091df651b2275a672c35ff938bd4b6db0d7f
R 12f17dff849f2a06a10012eebf93b957
T *branch * unpack-opcode
T *sym-unpack-opcode *
T -sym-trunk *
U drh
Z 6145fe123cad180747a41342b799e5b4
Z 51853eb094abb609c64d30de1af24213
+1 -1
View File
@@ -1 +1 @@
c6239bf943fc42b8fc1ece95c9268240b7c53e80
39ae92f5c63de4b95502f438dc7e9f2669efdf91
+1 -3
View File
@@ -4499,9 +4499,7 @@ static int accessPayload(
/* If required, populate the overflow page-list cache. */
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
assert( pCur->aOverflow[iIdx]==0
|| pCur->aOverflow[iIdx]==nextPage
|| CORRUPT_DB );
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
pCur->aOverflow[iIdx] = nextPage;
}
-4
View File
@@ -3356,10 +3356,6 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
**
** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
** factored out into initialization code.
**
** The SQLITE_ECEL_REF flag means that expressions in the list with
** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
** in registers at srcReg, and so the value can be copied from there.
*/
int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
+8 -9
View File
@@ -1230,15 +1230,16 @@ static void generateSortTail(
codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
bSeq = 0;
sqlite3VdbeAddOp4Int(v, OP_Unpack, regSortOut, regRow, nSortData, nKey);
}else{
addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
iSortTab = iTab;
bSeq = 1;
}
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
for(i=0; i<nSortData; i++){
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
}
switch( eDest ){
case SRT_EphemTab: {
@@ -5340,11 +5341,9 @@ int sqlite3Select(
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
sortOut, sortPTab);
}
for(j=0; j<pGroupBy->nExpr; j++){
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
}else{
sqlite3VdbeAddOp4Int(v, OP_Unpack, sortOut, iBMem, pGroupBy->nExpr, 0);
}else{
for(j=0; j<pGroupBy->nExpr; j++){
sAggInfo.directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
+18 -21
View File
@@ -496,13 +496,6 @@ void sqlite3Update(
** table and index records, and as the values for any new.* references
** made by triggers.
**
** As an optimization, the array is loaded in two passes. The first pass
** loads unchanged values using OP_Column opcodes so that they can be
** cached and potentially reused by subsequent expressions. Also, the
** OP_Columns are loaded in reverse order so that the row type/offset cache
** inside the OP_Column implementation in the VDBE will warm up completely
** on the first opcode, rather than incrementally across each opcode.
**
** If there are one or more BEFORE triggers, then do not populate the
** registers associated with columns that are (a) not modified by
** this UPDATE statement and (b) not accessed by new.* references. The
@@ -514,21 +507,25 @@ void sqlite3Update(
newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
for(i=pTab->nCol-1; i>=0; i--){
if( aXRef[i]>=0 && i!=pTab->iPKey ) continue;
if( i!=pTab->iPKey
&& (0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i))!=0)
){
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
for(i=0; i<pTab->nCol; i++){
if( (j = aXRef[i])>=0 && i!=pTab->iPKey ){
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
if( i==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}else{
j = aXRef[i];
if( j>=0 ){
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
/* This branch loads the value of a column that will not be changed
** into a register. This is done if there are no BEFORE triggers, or
** if there are one or more BEFORE triggers that use this value via
** a new.* reference in a trigger program.
*/
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
}
+89 -31
View File
@@ -2368,7 +2368,7 @@ case OP_Column: {
const u8 *zHdr; /* Next unparsed byte of the header */
const u8 *zEndHdr; /* Pointer to first byte after the header */
u32 offset; /* Offset into the data */
u64 offset64; /* 64-bit offset */
u32 szField; /* Number of bytes in the content of a field */
u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
u16 fx; /* pDest->flags value */
@@ -2439,6 +2439,19 @@ case OP_Column: {
pC->nHdrParsed = 0;
aOffset[0] = offset;
/* Make sure a corrupt database has not given us an oversize header.
** Do this now to avoid an oversize memory allocation.
**
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
** types use so much data space that there can only be 4096 and 32 of
** them, respectively. So the maximum header length results from a
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
if( avail<offset ){
/* pC->aRow does not have to hold the entire row, but it does at least
@@ -2447,20 +2460,6 @@ case OP_Column: {
** dynamically allocated. */
pC->aRow = 0;
pC->szRow = 0;
/* Make sure a corrupt database has not given us an oversize header.
** Do this now to avoid an oversize memory allocation.
**
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
** types use so much data space that there can only be 4096 and 32 of
** them, respectively. So the maximum header length results from a
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}
/* The following goto is an optimization. It can be omitted and
@@ -2483,8 +2482,11 @@ case OP_Column: {
/* Make sure zData points to enough of the record to cover the header. */
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
if( rc!=SQLITE_OK ) goto op_column_error;
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
!pC->isTable, &sMem);
if( rc!=SQLITE_OK ){
goto op_column_error;
}
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
@@ -2492,32 +2494,44 @@ case OP_Column: {
/* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
i = pC->nHdrParsed;
offset64 = aOffset[i];
offset = aOffset[i];
zHdr = zData + pC->iHdrOffset;
zEndHdr = zData + aOffset[0];
assert( i<=p2 && zHdr<zEndHdr );
do{
if( (t = zHdr[0])<0x80 ){
if( zHdr[0]<0x80 ){
t = zHdr[0];
zHdr++;
offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
}else{
zHdr += sqlite3GetVarint32(zHdr, &t);
offset64 += sqlite3VdbeSerialTypeLen(t);
}
pC->aType[i++] = t;
aOffset[i] = (u32)(offset64 & 0xffffffff);
pC->aType[i] = t;
szField = sqlite3VdbeSerialTypeLen(t);
offset += szField;
if( offset<szField ){ /* True if offset overflows */
zHdr = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
break;
}
i++;
aOffset[i] = offset;
}while( i<=p2 && zHdr<zEndHdr );
pC->nHdrParsed = i;
pC->iHdrOffset = (u32)(zHdr - zData);
if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
if( pC->aRow==0 ){
sqlite3VdbeMemRelease(&sMem);
sMem.flags = MEM_Null;
}
/* The record is corrupt if any of the following are true:
** (1) the bytes of the header extend past the declared header size
** (zHdr>zEndHdr)
** (2) the entire header was used but not all data was used
** (zHdr==zEndHdr && offset!=pC->payloadSize)
** (3) the end of the data extends beyond the end of the record.
** (offset > pC->payloadSize)
*/
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
|| (offset64 > pC->payloadSize)
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
|| (offset > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
@@ -2536,8 +2550,6 @@ case OP_Column: {
}
goto op_column_out;
}
}else{
t = pC->aType[p2];
}
/* Extract the content for the p2+1-th column. Control can only
@@ -2548,7 +2560,7 @@ case OP_Column: {
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
assert( t==pC->aType[p2] );
t = pC->aType[p2];
if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
@@ -2602,6 +2614,51 @@ op_column_error:
break;
}
/* Opcode: Unpack P1 P2 P3 P4 *
** Synopsis: r[P2@P3] = unpack(P1)
**
** Decode the P3 fields of the record object held in register P1
** start with the P4-th field and store the values in registers P2
** and following.
*/
case OP_Unpack: {
const unsigned char *aKey;
int d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
int nField;
u32 serial_type;
int iOfst; /* Skip this many fields */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags & MEM_Blob );
aKey = (const unsigned char*)pIn1->z;
pOut = &aMem[pOp->p2];
nField = pOp->p3;
assert( pOp->p4type==P4_INT32 );
iOfst = pOp->p4.i;
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
while( idx<szHdr && d<=pIn1->n ){
idx += getVarint32(&aKey[idx], serial_type);
if( iOfst ){
iOfst--;
d += sqlite3VdbeSerialTypeLen(serial_type);
}else{
memAboutToChange(p, pOut);
sqlite3VdbeMemSetNull(pOut);
pOut->enc = encoding;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pOut);
REGISTER_TRACE((int)(pOut - aMem), pOut);
pOut++;
if( (++u)>=nField ) break;
}
}
break;
}
/* Opcode: Affinity P1 P2 * P4 *
** Synopsis: affinity(r[P1@P2])
**
@@ -2660,7 +2717,7 @@ case OP_MakeRecord: {
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] header */
int j; /* Space used in zNewRecord[] content */
u32 len; /* Length of a field */
int len; /* Length of a field */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -2710,7 +2767,8 @@ case OP_MakeRecord: {
pRec = pLast;
do{
assert( memIsValid(pRec) );
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
len = sqlite3VdbeSerialTypeLen(serial_type);
if( pRec->flags & MEM_Zero ){
if( nData ){
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+1 -2
View File
@@ -412,8 +412,7 @@ int sqlite3VdbeCursorRestore(VdbeCursor*);
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
u32 sqlite3VdbeSerialTypeLen(u32);
u8 sqlite3VdbeOneByteSerialTypeLen(u8);
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
u32 sqlite3VdbeSerialType(Mem*, int);
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
+9 -39
View File
@@ -2940,13 +2940,11 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){
/*
** Return the serial-type for the value stored in pMem.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
int flags = pMem->flags;
u32 n;
assert( pLen!=0 );
if( flags&MEM_Null ){
*pLen = 0;
return 0;
}
if( flags&MEM_Int ){
@@ -2960,23 +2958,15 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
u = i;
}
if( u<=127 ){
if( (i&1)==i && file_format>=4 ){
*pLen = 0;
return 8+(u32)u;
}else{
*pLen = 1;
return 1;
}
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
}
if( u<=32767 ){ *pLen = 2; return 2; }
if( u<=8388607 ){ *pLen = 3; return 3; }
if( u<=2147483647 ){ *pLen = 4; return 4; }
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
*pLen = 8;
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
if( u<=2147483647 ) return 4;
if( u<=MAX_6BYTE ) return 5;
return 6;
}
if( flags&MEM_Real ){
*pLen = 8;
return 7;
}
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
@@ -2985,46 +2975,26 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( flags & MEM_Zero ){
n += pMem->u.nZero;
}
*pLen = n;
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
/*
** The sizes for serial types less than 128
** The sizes for serial types less than 12
*/
static const u8 sqlite3SmallTypeSizes[] = {
/* 0 1 2 3 4 5 6 7 8 9 */
/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0
};
/*
** Return the length of the data corresponding to the supplied serial-type.
*/
u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
if( serial_type>=128 ){
if( serial_type>=12 ){
return (serial_type-12)/2;
}else{
assert( serial_type<12
|| sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
return sqlite3SmallTypeSizes[serial_type];
}
}
u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
assert( serial_type<128 );
return sqlite3SmallTypeSizes[serial_type];
}
/*
** If we are on an architecture with mixed-endian floating
+4 -3
View File
@@ -1427,16 +1427,17 @@ static void recordFunc(
sqlite3_value **argv
){
const int file_format = 1;
u32 iSerial; /* Serial type */
int iSerial; /* Serial type */
int nSerial; /* Bytes of space for iSerial as varint */
u32 nVal; /* Bytes of space required for argv[0] */
int nVal; /* Bytes of space required for argv[0] */
int nRet;
sqlite3 *db;
u8 *aRet;
UNUSED_PARAMETER( argc );
iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
iSerial = sqlite3VdbeSerialType(argv[0], file_format);
nSerial = sqlite3VarintLen(iSerial);
nVal = sqlite3VdbeSerialTypeLen(iSerial);
db = sqlite3_context_db_handle(context);
nRet = 1 + nSerial + nVal;
-17
View File
@@ -324,22 +324,5 @@ do_execsql_test json-6.4 {
SELECT json_valid('["a",55,"b",72]');
} {1}
# White-space tests. Note that form-feed is not white-space in JSON.
# ticket [57eec374ae1d0a1d4a23077a95f4e173fe269113]
#
foreach {tn isvalid ws} {
7.1 1 char(0x20)
7.2 1 char(0x09)
7.3 1 char(0x0A)
7.4 1 char(0x0D)
7.5 0 char(0x0C)
7.6 1 char(0x20,0x09,0x0a,0x0d,0x20)
7.7 0 char(0x20,0x09,0x0a,0x0c,0x0d,0x20)
} {
do_execsql_test json-$tn.1 \
"SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s',
$::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \
$isvalid
}
finish_test
+6
View File
@@ -726,6 +726,12 @@ int main(int argc, char **argv){
#ifndef SQLITE_OMIT_TRACE
sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0);
#endif
#ifdef SQLITE_ENABLE_JSON1
{
extern int sqlite3_json_init(sqlite3*);
sqlite3_json_init(db);
}
#endif
sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
-8
View File
@@ -1,16 +1,8 @@
#!/bin/tclsh
#
# SUMMARY:
# Run this script in the same directory as the "vdbe_profile.out" file.
# This script summarizes the results contained in that file.
#
# DETAILS:
# Compile SQLite using the -DVDBE_PROFILE option on Linux. This causes
# performance information about individual VDBE operations to be appended
# to the "vdbe_profile.out" file. After content has been accumulated in
# vdbe_profile.out, run this script to analyze the output and generate a
# report.
#
if {![file readable vdbe_profile.out]} {
error "run this script in the same directory as the vdbe_profile.out file"
}