]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Limit the total data in a single row to 2^16-1 bytes. (CVS 248)
authordrh <drh@noemail.net>
Sat, 15 Sep 2001 13:15:12 +0000 (13:15 +0000)
committerdrh <drh@noemail.net>
Sat, 15 Sep 2001 13:15:12 +0000 (13:15 +0000)
FossilOrigin-Name: 8fdec4d8b6043471f21235bc8918c9a8d838f508

manifest
manifest.uuid
src/btree.c
src/pager.h
src/sqlite.h.in
src/sqliteInt.h
src/util.c
src/vdbe.c

index 56603b0a9e8c639869206af9a9ffd98e34dbe384..58d57245dcc249fb7d1cc45eef528341bd5159f8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Removing\ssome\ssurplus\sfiles.\s(CVS\s1723)
-D 2001-09-15T00:59:33
+C Limit\sthe\stotal\sdata\sin\sa\ssingle\srow\sto\s2^16-1\sbytes.\s(CVS\s248)
+D 2001-09-15T13:15:13
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 6f4536369ce59b0ee7941f743c65c2c7f703ad2a
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -13,7 +13,7 @@ F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
 F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3
 F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
-F src/btree.c 3adf545b8e072000923f7e0f7f91d33072a9f869
+F src/btree.c 56a7d11c558bda94611eb62f91744c2c4dc46d08
 F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b
 F src/build.c 8359e553db8138d09f44957e2d1bcc9b8720117b
 F src/delete.c c84b5a26e29fda3c3de51345073a76bb161271fd
@@ -22,15 +22,15 @@ F src/insert.c 750a44c0d205779b2c42b0791a163937cfb00e74
 F src/main.c 73be8d00a8a9bbec715a6260840a19020a074090
 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
 F src/pager.c 048c20ac85485ca87ed33d6b7711375a3444f817
-F src/pager.h bb9136e833de46bc84aafd8403713d3c46fcbfdf
+F src/pager.h 61573be9fbbb658997bea92b26173b441b9fb3c3
 F src/parse.y 8b30e072208c3dfabd97c7d06f0924f194919533
 F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
 F src/random.c b626726c4f0066610739e52e7431adae7ccd9651
 F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84
 F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
-F src/sqlite.h.in 1d6a7d13284c3861e61bd0b71491fda613613c68
-F src/sqliteInt.h c7c0580ceb9b5ce92c6fc7ef9434320952b14dc0
+F src/sqlite.h.in 7446bbd8c4f519b78614893d517b405c4dfb10a4
+F src/sqliteInt.h b8738f1f16ae31a0a79bcb2ee01cea2b0979d1a2
 F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
 F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
 F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
@@ -38,8 +38,8 @@ F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670
 F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53
 F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6
 F src/update.c 8a9d514c7f3bfe5d99fe3dfc1ad92ed3e9daea47
-F src/util.c f3f1550fb7a02348c3d0a0969951e489806e055b
-F src/vdbe.c d5bb5d8dda994779e4d20de5e4a31edf995269ff
+F src/util.c fedf96bcda329ff56e0eff7bc212c99d29ad0397
+F src/vdbe.c 1568f677376cb4b7ee5d278676703099a2f00eef
 F src/vdbe.h b9d60d90aeb3acb5dbc1cdac6b0201991921b272
 F src/where.c b831b506e17cb592d9781ed066f3459cef768318
 F test/all.test 5cefdb035b45639ddbb9f80324185b0f0a9ebda2
@@ -97,7 +97,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
 F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
 F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P 264f23315e682909abb47912f48733f641772a4c
-R b059993507a776d66a3417f913643af9
+P 8ad996fdac6801768e94ca1710a0a3da03e1e7ea
+R fb8c894a127521efc4c282893bba574b
 U drh
-Z 6c5da555882197ba94055adde72070fe
+Z 73558ca3364f1614cb7a802241ae4415
index e27bc380e48f7e6811795d80ae76f10199709e2d..7a820ce72c3d10607f28a98138a8ea741dd0e9c5 100644 (file)
@@ -1 +1 @@
-8ad996fdac6801768e94ca1710a0a3da03e1e7ea
\ No newline at end of file
+8fdec4d8b6043471f21235bc8918c9a8d838f508
\ No newline at end of file
index 3baa48733a4d36af75a8aab84bafde7ab6ddb926..2dc2d4c6762cf15c9220e7162f2d248f879e04a3 100644 (file)
@@ -21,7 +21,7 @@
 **   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.
 ** For a detailed discussion of BTrees, refer to
 ** Change these typedefs when porting to new architectures.
 */
 typedef unsigned int uptr;
-/*  typedef unsigned int u32; -- already defined in sqliteInt.h */
-typedef unsigned short int u16;
-typedef unsigned char u8;
+
+/* There are already definedin sqliteInt.h...
+** typedef unsigned int u32;
+** typedef unsigned short int u16;
+** typedef unsigned char u8;
+*/
 
 /*
 ** This macro casts a pointer to an integer.  Useful for doing
index 8ae8b9ee6d4ce3b7e86723ade5bfaa03415c4001..363704658578350bb0f2e89a1e58f10e3df12305 100644 (file)
@@ -25,7 +25,7 @@
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** 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 $
 */
 
 /*
 */
 #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
 ** is called page 1.  0 is used to represent "not a page".
index 60aa491bf24ebb555139d4d66177dfb2ad1cf29a..c22b9cb3cfd58696640d21a38696eaa3d3d09485 100644 (file)
@@ -24,7 +24,7 @@
 ** This header file defines the interface that the sqlite library
 ** 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_
 #define _SQLITE_H_
@@ -161,6 +161,7 @@ int sqlite_exec(
 #define SQLITE_PROTOCOL  14   /* Database lock protocol error */
 #define SQLITE_EMPTY     15   /* Database table is empty */
 #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
 ** return at its earliest opportunity.  This routine is typically
index 134653bc7fc2fa453ae75615fa1899b6cb712fa3..8ea3e3949e6fc8aa8a5da5eca593b1e587027e8b 100644 (file)
@@ -23,7 +23,7 @@
 *************************************************************************
 ** 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 "vdbe.h"
 #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
index b894f2300ae07fcb86f4fb6791d943d247db6b4e..58103ba8dc0a7ee585362b6c97b42f7b3286b04e 100644 (file)
@@ -26,7 +26,7 @@
 ** This file contains functions for allocating memory, comparing
 ** 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 <stdarg.h>
@@ -997,6 +997,7 @@ const char *sqliteErrStr(int rc){
     case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
     case SQLITE_EMPTY:      z = "table contains no data";                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;
   }
   return z;
index e25dca46466d828110cb16ff509fe0111b49f200..6414dc538b3d597bd132d0a2bc5841ad0af11185 100644 (file)
@@ -41,7 +41,7 @@
 ** But other routines are also provided to help in building up
 ** 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 <ctype.h>
@@ -456,7 +456,7 @@ int sqliteVdbeMakeLabel(Vdbe *p){
   i = p->nLabel++;
   if( i>=p->nLabelAlloc ){
     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 ){
     p->nLabel = 0;
@@ -1774,22 +1774,24 @@ case OP_NotNull: {
 ** 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
 ** all entries (except NULLs) are converted to strings and 
-** concatenated.  The null-terminators are preserved by the concatation
-** and serve as a boundry marker between columns.  The lowest entry
+** concatenated.  The null-terminators are included on all string
+** 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
 ** 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
-** beginning of the completed record including the header.  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.
+** beginning of the completed record including the header.
+**
+** The OP_Column opcode is used to unpack a record manufactured with
+** the opcode.
 */
 case OP_MakeRecord: {
   char *zNewRecord;
   int nByte;
   int nField;
   int i, j;
-  int addr;
+  u16 addr;
 
   nField = pOp->p1;
   VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
@@ -1800,14 +1802,18 @@ case OP_MakeRecord: {
       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 );
   if( zNewRecord==0 ) goto no_mem;
   j = 0;
-  addr = sizeof(int)*nField;
+  addr = sizeof(addr)*nField;
   for(i=p->tos-nField+1; i<=p->tos; i++){
-    memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
-    j += sizeof(int);
+    memcpy(&zNewRecord[j], (char*)&addr, sizeof(addr));
+    j += sizeof(addr);
     if( (aStack[i].flags & STK_Null)==0 ){
       addr += aStack[i].n;
     }
@@ -1906,7 +1912,7 @@ case OP_MakeIdxKey: {
 
   nField = pOp->p1;
   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++){
     if( aStack[i].flags & STK_Null ){
       nByte++;
@@ -1927,7 +1933,7 @@ case OP_MakeIdxKey: {
   }
   zNewKey[j++] = 0;
   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);
   VERIFY( NeedStack(p, p->tos+1); )
   p->tos++;
@@ -2369,15 +2375,12 @@ case OP_KeyAsData: {
 
 /* Opcode: Column P1 P2 *
 **
-** Interpret the data in the most recent fetch from cursor P1
-** is a structure built using the MakeRecord instruction.
-** Push onto the stack the value of the P2-th field of that
-** structure.
-** 
-** The value pushed is a pointer to the data stored in the cursor.
-** 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.
+** Interpret the data that cursor P1 points to as
+** a structure built using the MakeRecord instruction.
+** (See the MakeRecord opcode for additional information about
+** the format of the data.)
+** Push onto the stack the value of the P2-th column contained
+** in the data.
 **
 ** If the KeyAsData opcode has previously executed on this cursor,
 ** then the field might be extracted from the key rather than the
@@ -2385,7 +2388,7 @@ case OP_KeyAsData: {
 */
 case OP_Column: {
   int amt, offset, nCol, payloadSize;
-  int aHdr[10];
+  u16 aHdr[10];
   static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
   int i = pOp->p1;
   int p2 = pOp->p2;
@@ -2417,14 +2420,14 @@ case OP_Column: {
     ** three times.
     */
     (*xSize)(pCrsr, &payloadSize);
-    if( payloadSize < sizeof(int)*(p2+1) ){
+    if( payloadSize < sizeof(aHdr[0])*(p2+1) ){
       rc = SQLITE_CORRUPT;
       goto abort_due_to_error;
     }
     if( p2+1<mxHdr ){
       (*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr);
       nCol = aHdr[0];
-      nCol /= sizeof(int);
+      nCol /= sizeof(aHdr[0]);
       offset = aHdr[p2];
       if( p2 == nCol-1 ){
         amt = payloadSize - offset;
@@ -2432,13 +2435,14 @@ case OP_Column: {
         amt = aHdr[p2+1] - offset;
       }
     }else{
-      sqliteBtreeData(pCrsr, 0, sizeof(int), (char*)&nCol);
-      nCol /= sizeof(int);
+      sqliteBtreeData(pCrsr, 0, sizeof(aHdr[0]), (char*)aHdr);
+      nCol = aHdr[0]/sizeof(aHdr[0]);
       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;
       }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];
         amt = aHdr[1] - offset;
       }
@@ -2447,6 +2451,10 @@ case OP_Column: {
       rc = SQLITE_CORRUPT;
       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 ){
       aStack[tos].flags = STK_Null;
     }else{
@@ -2480,7 +2488,7 @@ case OP_Recno: {
     if( p->aCsr[i].recnoIsValid ){
       v = p->aCsr[i].lastRecno;
     }else{
-      sqliteBtreeKey(pCrsr, 0, sizeof(int), (char*)&v);
+      sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v);
     }
     aStack[tos].i = v;
     aStack[tos].flags = STK_Int;
@@ -2626,7 +2634,7 @@ case OP_NextIdx: {
       if( rx!=SQLITE_OK ) goto abort_due_to_error;
     }
     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 ||
       strncmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
     ){
@@ -2634,7 +2642,7 @@ case OP_NextIdx: {
       POPSTACK;
     }else{
       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].recnoIsValid = 1;
       aStack[tos].flags = STK_Int;
@@ -2812,7 +2820,7 @@ case OP_ListWrite: {
   VERIFY( if( p->tos<0 ) goto not_enough_stack; )
   pKeylist = p->apList[i];
   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;
     pKeylist->nKey = 1000;
     pKeylist->nRead = 0;
@@ -3774,11 +3782,23 @@ default: {
         }else if( aStack[i].flags & STK_Real ){
           fprintf(p->trace, " r:%g", aStack[i].r);
         }else if( aStack[i].flags & STK_Str ){
-          if( aStack[i].flags & STK_Dyn ){
-            fprintf(p->trace, " z:[%.11s]", zStack[i]);
-          }else{
-            fprintf(p->trace, " s:[%.11s]", zStack[i]);
+          int j, k;
+          char zBuf[100];
+          zBuf[0] = ' ';
+          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{
           fprintf(p->trace, " ???");
         }