1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Limit the total data in a single row to 2^16-1 bytes. (CVS 248)

FossilOrigin-Name: 8fdec4d8b6043471f21235bc8918c9a8d838f508
This commit is contained in:
drh
2001-09-15 13:15:12 +00:00
parent b3e05a662a
commit 092d0350d5
8 changed files with 95 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
C Removing\ssome\ssurplus\sfiles.\s(CVS\s1723) C Limit\sthe\stotal\sdata\sin\sa\ssingle\srow\sto\s2^16-1\sbytes.\s(CVS\s248)
D 2001-09-15T00:59:33 D 2001-09-15T13:15:13
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 6f4536369ce59b0ee7941f743c65c2c7f703ad2a F Makefile.in 6f4536369ce59b0ee7941f743c65c2c7f703ad2a
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -13,7 +13,7 @@ F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3 F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3
F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16 F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c 3adf545b8e072000923f7e0f7f91d33072a9f869 F src/btree.c 56a7d11c558bda94611eb62f91744c2c4dc46d08
F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b
F src/build.c 8359e553db8138d09f44957e2d1bcc9b8720117b F src/build.c 8359e553db8138d09f44957e2d1bcc9b8720117b
F src/delete.c c84b5a26e29fda3c3de51345073a76bb161271fd F src/delete.c c84b5a26e29fda3c3de51345073a76bb161271fd
@@ -22,15 +22,15 @@ F src/insert.c 750a44c0d205779b2c42b0791a163937cfb00e74
F src/main.c 73be8d00a8a9bbec715a6260840a19020a074090 F src/main.c 73be8d00a8a9bbec715a6260840a19020a074090
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
F src/pager.c 048c20ac85485ca87ed33d6b7711375a3444f817 F src/pager.c 048c20ac85485ca87ed33d6b7711375a3444f817
F src/pager.h bb9136e833de46bc84aafd8403713d3c46fcbfdf F src/pager.h 61573be9fbbb658997bea92b26173b441b9fb3c3
F src/parse.y 8b30e072208c3dfabd97c7d06f0924f194919533 F src/parse.y 8b30e072208c3dfabd97c7d06f0924f194919533
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9 F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
F src/random.c b626726c4f0066610739e52e7431adae7ccd9651 F src/random.c b626726c4f0066610739e52e7431adae7ccd9651
F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84 F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84
F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726 F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 1d6a7d13284c3861e61bd0b71491fda613613c68 F src/sqlite.h.in 7446bbd8c4f519b78614893d517b405c4dfb10a4
F src/sqliteInt.h c7c0580ceb9b5ce92c6fc7ef9434320952b14dc0 F src/sqliteInt.h b8738f1f16ae31a0a79bcb2ee01cea2b0979d1a2
F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6 F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4 F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
@@ -38,8 +38,8 @@ F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670
F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53 F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53
F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6 F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6
F src/update.c 8a9d514c7f3bfe5d99fe3dfc1ad92ed3e9daea47 F src/update.c 8a9d514c7f3bfe5d99fe3dfc1ad92ed3e9daea47
F src/util.c f3f1550fb7a02348c3d0a0969951e489806e055b F src/util.c fedf96bcda329ff56e0eff7bc212c99d29ad0397
F src/vdbe.c d5bb5d8dda994779e4d20de5e4a31edf995269ff F src/vdbe.c 1568f677376cb4b7ee5d278676703099a2f00eef
F src/vdbe.h b9d60d90aeb3acb5dbc1cdac6b0201991921b272 F src/vdbe.h b9d60d90aeb3acb5dbc1cdac6b0201991921b272
F src/where.c b831b506e17cb592d9781ed066f3459cef768318 F src/where.c b831b506e17cb592d9781ed066f3459cef768318
F test/all.test 5cefdb035b45639ddbb9f80324185b0f0a9ebda2 F test/all.test 5cefdb035b45639ddbb9f80324185b0f0a9ebda2
@@ -97,7 +97,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
P 264f23315e682909abb47912f48733f641772a4c P 8ad996fdac6801768e94ca1710a0a3da03e1e7ea
R b059993507a776d66a3417f913643af9 R fb8c894a127521efc4c282893bba574b
U drh U drh
Z 6c5da555882197ba94055adde72070fe Z 73558ca3364f1614cb7a802241ae4415

View File

@@ -1 +1 @@
8ad996fdac6801768e94ca1710a0a3da03e1e7ea 8fdec4d8b6043471f21235bc8918c9a8d838f508

View File

@@ -21,7 +21,7 @@
** http://www.hwaci.com/drh/ ** http://www.hwaci.com/drh/
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.27 2001/09/14 18:54:08 drh Exp $ ** $Id: btree.c,v 1.28 2001/09/15 13:15:13 drh Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** For a detailed discussion of BTrees, refer to
@@ -73,9 +73,12 @@
** Change these typedefs when porting to new architectures. ** Change these typedefs when porting to new architectures.
*/ */
typedef unsigned int uptr; typedef unsigned int uptr;
/* typedef unsigned int u32; -- already defined in sqliteInt.h */
typedef unsigned short int u16; /* There are already definedin sqliteInt.h...
typedef unsigned char u8; ** typedef unsigned int u32;
** typedef unsigned short int u16;
** typedef unsigned char u8;
*/
/* /*
** This macro casts a pointer to an integer. Useful for doing ** This macro casts a pointer to an integer. Useful for doing

View File

@@ -25,7 +25,7 @@
** subsystem. The page cache subsystem reads and writes a file a page ** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback. ** at a time and provides a journal for rollback.
** **
** @(#) $Id: pager.h,v 1.9 2001/09/14 18:54:09 drh Exp $ ** @(#) $Id: pager.h,v 1.10 2001/09/15 13:15:13 drh Exp $
*/ */
/* /*
@@ -33,6 +33,12 @@
*/ */
#define SQLITE_PAGE_SIZE 1024 #define SQLITE_PAGE_SIZE 1024
/*
** Maximum number of pages in one database. (This is a limitation of
** imposed by 4GB files size limits.)
*/
#define SQLITE_MAX_PAGE 1073741823
/* /*
** The type used to represent a page number. The first page in a file ** The type used to represent a page number. The first page in a file
** is called page 1. 0 is used to represent "not a page". ** is called page 1. 0 is used to represent "not a page".

View File

@@ -24,7 +24,7 @@
** This header file defines the interface that the sqlite library ** This header file defines the interface that the sqlite library
** presents to client programs. ** presents to client programs.
** **
** @(#) $Id: sqlite.h.in,v 1.15 2001/09/15 00:57:29 drh Exp $ ** @(#) $Id: sqlite.h.in,v 1.16 2001/09/15 13:15:13 drh Exp $
*/ */
#ifndef _SQLITE_H_ #ifndef _SQLITE_H_
#define _SQLITE_H_ #define _SQLITE_H_
@@ -161,6 +161,7 @@ int sqlite_exec(
#define SQLITE_PROTOCOL 14 /* Database lock protocol error */ #define SQLITE_PROTOCOL 14 /* Database lock protocol error */
#define SQLITE_EMPTY 15 /* Database table is empty */ #define SQLITE_EMPTY 15 /* Database table is empty */
#define SQLITE_SCHEMA 16 /* The database schema changed */ #define SQLITE_SCHEMA 16 /* The database schema changed */
#define SQLITE_TOOBIG 17 /* Too much data for one row of a table */
/* This function causes any pending database operation to abort and /* This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically ** return at its earliest opportunity. This routine is typically

View File

@@ -23,7 +23,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.48 2001/09/15 00:57:29 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.49 2001/09/15 13:15:13 drh Exp $
*/ */
#include "sqlite.h" #include "sqlite.h"
#include "vdbe.h" #include "vdbe.h"
@@ -42,9 +42,12 @@
#define TEMP_PAGES 25 #define TEMP_PAGES 25
/* /*
** The paging system deals with 32-bit integers. ** Integers of known sizes. These typedefs much change for architectures
** where the sizes very.
*/ */
typedef unsigned int u32; typedef unsigned int u32; /* 4-byte unsigned integer */
typedef unsigned short int u16; /* 2-byte unsigned integer */
typedef unsigned char u8; /* 1-byte unsigned integer */
/* /*
** If memory allocation problems are found, recompile with ** If memory allocation problems are found, recompile with

View File

@@ -26,7 +26,7 @@
** This file contains functions for allocating memory, comparing ** This file contains functions for allocating memory, comparing
** strings, and stuff like that. ** strings, and stuff like that.
** **
** $Id: util.c,v 1.23 2001/09/15 00:57:29 drh Exp $ ** $Id: util.c,v 1.24 2001/09/15 13:15:13 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdarg.h> #include <stdarg.h>
@@ -997,6 +997,7 @@ const char *sqliteErrStr(int rc){
case SQLITE_PROTOCOL: z = "database locking protocol failure"; break; case SQLITE_PROTOCOL: z = "database locking protocol failure"; break;
case SQLITE_EMPTY: z = "table contains no data"; break; case SQLITE_EMPTY: z = "table contains no data"; break;
case SQLITE_SCHEMA: z = "database schema has changed"; break; case SQLITE_SCHEMA: z = "database schema has changed"; break;
case SQLITE_TOOBIG: z = "too much data for one table row"; break;
default: z = "unknown error"; break; default: z = "unknown error"; break;
} }
return z; return z;

View File

@@ -41,7 +41,7 @@
** But other routines are also provided to help in building up ** But other routines are also provided to help in building up
** a program instruction by instruction. ** a program instruction by instruction.
** **
** $Id: vdbe.c,v 1.67 2001/09/15 00:57:29 drh Exp $ ** $Id: vdbe.c,v 1.68 2001/09/15 13:15:13 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -456,7 +456,7 @@ int sqliteVdbeMakeLabel(Vdbe *p){
i = p->nLabel++; i = p->nLabel++;
if( i>=p->nLabelAlloc ){ if( i>=p->nLabelAlloc ){
p->nLabelAlloc = p->nLabelAlloc*2 + 10; p->nLabelAlloc = p->nLabelAlloc*2 + 10;
p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(int)); p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
} }
if( p->aLabel==0 ){ if( p->aLabel==0 ){
p->nLabel = 0; p->nLabel = 0;
@@ -1774,22 +1774,24 @@ case OP_NotNull: {
** Convert the top P1 entries of the stack into a single entry ** Convert the top P1 entries of the stack into a single entry
** suitable for use as a data record in a database table. To do this ** suitable for use as a data record in a database table. To do this
** all entries (except NULLs) are converted to strings and ** all entries (except NULLs) are converted to strings and
** concatenated. The null-terminators are preserved by the concatation ** concatenated. The null-terminators are included on all string
** and serve as a boundry marker between columns. The lowest entry ** except for NULL columns which are represented by zero bytes.
** The lowest entry
** on the stack is the first in the concatenation and the top of ** on the stack is the first in the concatenation and the top of
** the stack is the last. After all columns are concatenated, an ** the stack is the last. After all columns are concatenated, an
** index header is added. The index header consists of P1 integers ** index header is added. The index header consists of P1 16-bit integers
** which hold the offset of the beginning of each column data from the ** which hold the offset of the beginning of each column data from the
** beginning of the completed record including the header. Header ** beginning of the completed record including the header.
** entries for NULL fields point to where the first byte of the column **
** would have been stored if the column had held any bytes. ** The OP_Column opcode is used to unpack a record manufactured with
** the opcode.
*/ */
case OP_MakeRecord: { case OP_MakeRecord: {
char *zNewRecord; char *zNewRecord;
int nByte; int nByte;
int nField; int nField;
int i, j; int i, j;
int addr; u16 addr;
nField = pOp->p1; nField = pOp->p1;
VERIFY( if( p->tos+1<nField ) goto not_enough_stack; ) VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
@@ -1800,14 +1802,18 @@ case OP_MakeRecord: {
nByte += aStack[i].n; nByte += aStack[i].n;
} }
} }
nByte += sizeof(int)*nField; nByte += sizeof(addr)*nField;
if( nByte>65535 ){
rc = SQLITE_TOOBIG;
goto abort_due_to_error;
}
zNewRecord = sqliteMalloc( nByte ); zNewRecord = sqliteMalloc( nByte );
if( zNewRecord==0 ) goto no_mem; if( zNewRecord==0 ) goto no_mem;
j = 0; j = 0;
addr = sizeof(int)*nField; addr = sizeof(addr)*nField;
for(i=p->tos-nField+1; i<=p->tos; i++){ for(i=p->tos-nField+1; i<=p->tos; i++){
memcpy(&zNewRecord[j], (char*)&addr, sizeof(int)); memcpy(&zNewRecord[j], (char*)&addr, sizeof(addr));
j += sizeof(int); j += sizeof(addr);
if( (aStack[i].flags & STK_Null)==0 ){ if( (aStack[i].flags & STK_Null)==0 ){
addr += aStack[i].n; addr += aStack[i].n;
} }
@@ -1906,7 +1912,7 @@ case OP_MakeIdxKey: {
nField = pOp->p1; nField = pOp->p1;
VERIFY( if( p->tos+1<nField ) goto not_enough_stack; ) VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
nByte = sizeof(int); nByte = sizeof(u32);
for(i=p->tos-nField+1; i<=p->tos; i++){ for(i=p->tos-nField+1; i<=p->tos; i++){
if( aStack[i].flags & STK_Null ){ if( aStack[i].flags & STK_Null ){
nByte++; nByte++;
@@ -1927,7 +1933,7 @@ case OP_MakeIdxKey: {
} }
zNewKey[j++] = 0; zNewKey[j++] = 0;
Integerify(p, p->tos-nField); Integerify(p, p->tos-nField);
memcpy(&zNewKey[j], &aStack[p->tos-nField].i, sizeof(int)); memcpy(&zNewKey[j], &aStack[p->tos-nField].i, sizeof(u32));
PopStack(p, nField+1); PopStack(p, nField+1);
VERIFY( NeedStack(p, p->tos+1); ) VERIFY( NeedStack(p, p->tos+1); )
p->tos++; p->tos++;
@@ -2369,15 +2375,12 @@ case OP_KeyAsData: {
/* Opcode: Column P1 P2 * /* Opcode: Column P1 P2 *
** **
** Interpret the data in the most recent fetch from cursor P1 ** Interpret the data that cursor P1 points to as
** is a structure built using the MakeRecord instruction. ** a structure built using the MakeRecord instruction.
** Push onto the stack the value of the P2-th field of that ** (See the MakeRecord opcode for additional information about
** structure. ** the format of the data.)
** ** Push onto the stack the value of the P2-th column contained
** The value pushed is a pointer to the data stored in the cursor. ** in the data.
** The value will go away the next time the cursor is modified in
** any way. Make a copy of the string (using
** "Concat 1 0 0") if it needs to persist longer than that.
** **
** If the KeyAsData opcode has previously executed on this cursor, ** If the KeyAsData opcode has previously executed on this cursor,
** then the field might be extracted from the key rather than the ** then the field might be extracted from the key rather than the
@@ -2385,7 +2388,7 @@ case OP_KeyAsData: {
*/ */
case OP_Column: { case OP_Column: {
int amt, offset, nCol, payloadSize; int amt, offset, nCol, payloadSize;
int aHdr[10]; u16 aHdr[10];
static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]); static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
int i = pOp->p1; int i = pOp->p1;
int p2 = pOp->p2; int p2 = pOp->p2;
@@ -2417,14 +2420,14 @@ case OP_Column: {
** three times. ** three times.
*/ */
(*xSize)(pCrsr, &payloadSize); (*xSize)(pCrsr, &payloadSize);
if( payloadSize < sizeof(int)*(p2+1) ){ if( payloadSize < sizeof(aHdr[0])*(p2+1) ){
rc = SQLITE_CORRUPT; rc = SQLITE_CORRUPT;
goto abort_due_to_error; goto abort_due_to_error;
} }
if( p2+1<mxHdr ){ if( p2+1<mxHdr ){
(*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr); (*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr);
nCol = aHdr[0]; nCol = aHdr[0];
nCol /= sizeof(int); nCol /= sizeof(aHdr[0]);
offset = aHdr[p2]; offset = aHdr[p2];
if( p2 == nCol-1 ){ if( p2 == nCol-1 ){
amt = payloadSize - offset; amt = payloadSize - offset;
@@ -2432,13 +2435,14 @@ case OP_Column: {
amt = aHdr[p2+1] - offset; amt = aHdr[p2+1] - offset;
} }
}else{ }else{
sqliteBtreeData(pCrsr, 0, sizeof(int), (char*)&nCol); sqliteBtreeData(pCrsr, 0, sizeof(aHdr[0]), (char*)aHdr);
nCol /= sizeof(int); nCol = aHdr[0]/sizeof(aHdr[0]);
if( p2 == nCol-1 ){ if( p2 == nCol-1 ){
(*xRead)(pCrsr, sizeof(int)*p2, sizeof(int), (char*)&offset); (*xRead)(pCrsr, sizeof(aHdr[0])*p2, sizeof(aHdr[0]), (char*)aHdr);
offset = aHdr[0];
amt = payloadSize - offset; amt = payloadSize - offset;
}else{ }else{
(*xRead)(pCrsr, sizeof(int)*p2, sizeof(int)*2, (char*)aHdr); (*xRead)(pCrsr, sizeof(aHdr[0])*p2, sizeof(aHdr[0])*2, (char*)aHdr);
offset = aHdr[0]; offset = aHdr[0];
amt = aHdr[1] - offset; amt = aHdr[1] - offset;
} }
@@ -2447,6 +2451,10 @@ case OP_Column: {
rc = SQLITE_CORRUPT; rc = SQLITE_CORRUPT;
goto abort_due_to_error; goto abort_due_to_error;
} }
/* amt and offset now hold the offset to the start of data and the
** amount of data. Go get the data and put it on the stack.
*/
if( amt==0 ){ if( amt==0 ){
aStack[tos].flags = STK_Null; aStack[tos].flags = STK_Null;
}else{ }else{
@@ -2480,7 +2488,7 @@ case OP_Recno: {
if( p->aCsr[i].recnoIsValid ){ if( p->aCsr[i].recnoIsValid ){
v = p->aCsr[i].lastRecno; v = p->aCsr[i].lastRecno;
}else{ }else{
sqliteBtreeKey(pCrsr, 0, sizeof(int), (char*)&v); sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v);
} }
aStack[tos].i = v; aStack[tos].i = v;
aStack[tos].flags = STK_Int; aStack[tos].flags = STK_Int;
@@ -2626,7 +2634,7 @@ case OP_NextIdx: {
if( rx!=SQLITE_OK ) goto abort_due_to_error; if( rx!=SQLITE_OK ) goto abort_due_to_error;
} }
sqliteBtreeKeySize(pCur, &size); sqliteBtreeKeySize(pCur, &size);
if( res>0 || size!=pCrsr->nKey+sizeof(int) || if( res>0 || size!=pCrsr->nKey+sizeof(u32) ||
sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey || sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey ||
strncmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0 strncmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
){ ){
@@ -2634,7 +2642,7 @@ case OP_NextIdx: {
POPSTACK; POPSTACK;
}else{ }else{
int recno; int recno;
sqliteBtreeKey(pCur, pCrsr->nKey, sizeof(int), (char*)&recno); sqliteBtreeKey(pCur, pCrsr->nKey, sizeof(u32), (char*)&recno);
p->aCsr[i].lastRecno = aStack[tos].i = recno; p->aCsr[i].lastRecno = aStack[tos].i = recno;
p->aCsr[i].recnoIsValid = 1; p->aCsr[i].recnoIsValid = 1;
aStack[tos].flags = STK_Int; aStack[tos].flags = STK_Int;
@@ -2812,7 +2820,7 @@ case OP_ListWrite: {
VERIFY( if( p->tos<0 ) goto not_enough_stack; ) VERIFY( if( p->tos<0 ) goto not_enough_stack; )
pKeylist = p->apList[i]; pKeylist = p->apList[i];
if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){ if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(int) ); pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
if( pKeylist==0 ) goto no_mem; if( pKeylist==0 ) goto no_mem;
pKeylist->nKey = 1000; pKeylist->nKey = 1000;
pKeylist->nRead = 0; pKeylist->nRead = 0;
@@ -3774,11 +3782,23 @@ default: {
}else if( aStack[i].flags & STK_Real ){ }else if( aStack[i].flags & STK_Real ){
fprintf(p->trace, " r:%g", aStack[i].r); fprintf(p->trace, " r:%g", aStack[i].r);
}else if( aStack[i].flags & STK_Str ){ }else if( aStack[i].flags & STK_Str ){
if( aStack[i].flags & STK_Dyn ){ int j, k;
fprintf(p->trace, " z:[%.11s]", zStack[i]); char zBuf[100];
}else{ zBuf[0] = ' ';
fprintf(p->trace, " s:[%.11s]", zStack[i]); zBuf[1] = (aStack[i].flags & STK_Dyn)!=0 ? 'z' : 's';
zBuf[2] = ':';
k = 3;
for(j=0; j<15 && j<aStack[i].n; j++){
int c = zStack[i][j];
if( c==0 && j==aStack[i].n-1 ) break;
if( isprint(c) && !isspace(c) ){
zBuf[k++] = c;
}else{
zBuf[k++] = '.';
}
} }
zBuf[k++] = 0;
fprintf(p->trace, "%s", zBuf);
}else{ }else{
fprintf(p->trace, " ???"); fprintf(p->trace, " ???");
} }