aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2001-09-15 14:43:39 +0000
committerdrh <drh@noemail.net>2001-09-15 14:43:39 +0000
commit872ff86f2c0ee7b171c46609f49af16a0cc31b9c (patch)
treed5208a227baa24aef6ca3994f8381d6eb1f4a2f3
parent092d0350d5bcfe2d1a02dc3a821b474c9c0ecdbd (diff)
downloadsqlite-872ff86f2c0ee7b171c46609f49af16a0cc31b9c.tar.gz
sqlite-872ff86f2c0ee7b171c46609f49af16a0cc31b9c.zip
Separate columns in keys using nulls instead of tabs. (CVS 249)
FossilOrigin-Name: 8e2f3f751ea342372c94977ff27baaff5126009a
-rw-r--r--manifest14
-rw-r--r--manifest.uuid2
-rw-r--r--src/sqliteInt.h8
-rw-r--r--src/vdbe.c70
4 files changed, 57 insertions, 37 deletions
diff --git a/manifest b/manifest
index 58d57245d..10e36a8b3 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Limit\sthe\stotal\sdata\sin\sa\ssingle\srow\sto\s2^16-1\sbytes.\s(CVS\s248)
-D 2001-09-15T13:15:13
+C Separate\scolumns\sin\skeys\susing\snulls\sinstead\sof\stabs.\s(CVS\s249)
+D 2001-09-15T14:43:39
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 6f4536369ce59b0ee7941f743c65c2c7f703ad2a
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -30,7 +30,7 @@ F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84
F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in 7446bbd8c4f519b78614893d517b405c4dfb10a4
-F src/sqliteInt.h b8738f1f16ae31a0a79bcb2ee01cea2b0979d1a2
+F src/sqliteInt.h cba5f573a4ceb742e864cc4c19abc7062775517f
F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
@@ -39,7 +39,7 @@ F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53
F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6
F src/update.c 8a9d514c7f3bfe5d99fe3dfc1ad92ed3e9daea47
F src/util.c fedf96bcda329ff56e0eff7bc212c99d29ad0397
-F src/vdbe.c 1568f677376cb4b7ee5d278676703099a2f00eef
+F src/vdbe.c 5fac42c8de36778c980da02048433bc992a3c57c
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 8ad996fdac6801768e94ca1710a0a3da03e1e7ea
-R fb8c894a127521efc4c282893bba574b
+P 8fdec4d8b6043471f21235bc8918c9a8d838f508
+R e83f8668f9cad78aebdc309129b17220
U drh
-Z 73558ca3364f1614cb7a802241ae4415
+Z a7c29380928c91f61d2d3ff358c4cb25
diff --git a/manifest.uuid b/manifest.uuid
index 7a820ce72..954acfbaf 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-8fdec4d8b6043471f21235bc8918c9a8d838f508 \ No newline at end of file
+8e2f3f751ea342372c94977ff27baaff5126009a \ No newline at end of file
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 8ea3e3949..a22061aac 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -23,7 +23,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.49 2001/09/15 13:15:13 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.50 2001/09/15 14:43:39 drh Exp $
*/
#include "sqlite.h"
#include "vdbe.h"
@@ -50,6 +50,12 @@ typedef unsigned short int u16; /* 2-byte unsigned integer */
typedef unsigned char u8; /* 1-byte unsigned integer */
/*
+** The maximum number of bytes of data that can be put into a single
+** row of a single table.
+*/
+#define MAX_BYTES_PER_ROW 65535
+
+/*
** If memory allocation problems are found, recompile with
**
** -DMEMORY_DEBUG=1
diff --git a/src/vdbe.c b/src/vdbe.c
index 6414dc538..6adf20e33 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -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.68 2001/09/15 13:15:13 drh Exp $
+** $Id: vdbe.c,v 1.69 2001/09/15 14:43:39 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1803,7 +1803,7 @@ case OP_MakeRecord: {
}
}
nByte += sizeof(addr)*nField;
- if( nByte>65535 ){
+ if( nByte>MAX_BYTES_PER_ROW ){
rc = SQLITE_TOOBIG;
goto abort_due_to_error;
}
@@ -1837,9 +1837,10 @@ case OP_MakeRecord: {
**
** Convert the top P1 entries of the stack into a single entry suitable
** for use as the key in an index or a sort. The top P1 records are
-** concatenated with a tab character (ASCII 0x09) used as a record
-** separator. The entire concatenation is null-terminated. The
-** lowest entry in the stack is the first field and the top of the
+** converted to strings and merged. The null-terminator on each string
+** is retained and used as a separator. The entire string is also
+** null-terminated.
+** The lowest entry in the stack is the first field and the top of the
** stack becomes the last.
**
** If P2 is not zero, then the original entries remain on the stack
@@ -1866,17 +1867,21 @@ case OP_MakeKey: {
nByte += aStack[i].n;
}
}
+ if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
+ rc = SQLITE_TOOBIG;
+ goto abort_due_to_error;
+ }
zNewKey = sqliteMalloc( nByte );
if( zNewKey==0 ) goto no_mem;
j = 0;
for(i=p->tos-nField+1; i<=p->tos; i++){
- if( (aStack[i].flags & STK_Null)==0 ){
- memcpy(&zNewKey[j], zStack[i], aStack[i].n-1);
- j += aStack[i].n-1;
+ if( aStack[i].flags & STK_Null ){
+ zNewKey[j++] = 0;
+ }else{
+ memcpy(&zNewKey[j], zStack[i], aStack[i].n);
+ j += aStack[i].n;
}
- if( i<p->tos ) zNewKey[j++] = '\t';
}
- zNewKey[j] = 0;
if( pOp->p2==0 ) PopStack(p, nField);
VERIFY( NeedStack(p, p->tos+1); )
p->tos++;
@@ -1897,7 +1902,7 @@ case OP_MakeKey: {
** entry (the lowest on the stack) is an integer record number.
**
** The converstion of the first P1 string entries occurs just like in
-** MakeKey. Each entry is separated from the others by a tab (ASCII 0x09).
+** MakeKey. Each entry is separated from the others by a null.
** The entire concatenation is null-terminated. The lowest entry
** in the stack is the first field and the top of the stack becomes the
** last.
@@ -1921,17 +1926,21 @@ case OP_MakeIdxKey: {
nByte += aStack[i].n;
}
}
+ if( nByte>MAX_BYTES_PER_ROW ){
+ rc = SQLITE_TOOBIG;
+ goto abort_due_to_error;
+ }
zNewKey = sqliteMalloc( nByte );
if( zNewKey==0 ) goto no_mem;
j = 0;
for(i=p->tos-nField+1; i<=p->tos; i++){
- if( (aStack[i].flags & STK_Null)==0 ){
- memcpy(&zNewKey[j], zStack[i], aStack[i].n-1);
- j += aStack[i].n-1;
+ if( aStack[i].flags & STK_Null ){
+ zNewKey[j++] = 0;
+ }else{
+ memcpy(&zNewKey[j], zStack[i], aStack[i].n);
+ j += aStack[i].n;
}
- if( i<p->tos ) zNewKey[j++] = '\t';
}
- zNewKey[j++] = 0;
Integerify(p, p->tos-nField);
memcpy(&zNewKey[j], &aStack[p->tos-nField].i, sizeof(u32));
PopStack(p, nField+1);
@@ -2581,8 +2590,10 @@ case OP_Next: {
** but the key used for PutIdx and DeleteIdx should be built using
** MakeIdxKey. The difference is that MakeIdxKey adds a 4-bytes
** record number to the end of the key in order to specify a particular
-** entry in the index. MakeKey specifies zero or more entries in the
-** index that all have common values.
+** entry in the index. MakeKey omits the 4-byte record number.
+** The search that this BeginIdx instruction initiates will span all
+** entries in the index where the MakeKey generated key matches all
+** but the last four bytes of the MakeIdxKey generated key.
*/
case OP_BeginIdx: {
int i = pOp->p1;
@@ -2594,10 +2605,10 @@ case OP_BeginIdx: {
if( Stringify(p, tos) ) goto no_mem;
if( pCrsr->zKey ) sqliteFree(pCrsr->zKey);
pCrsr->nKey = aStack[tos].n;
- pCrsr->zKey = sqliteMalloc( 2*(pCrsr->nKey + 1) );
+ pCrsr->zKey = sqliteMalloc( 2*pCrsr->nKey );
if( pCrsr->zKey==0 ) goto no_mem;
- pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey+1];
- strncpy(pCrsr->zKey, zStack[tos], aStack[tos].n);
+ pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey];
+ memcpy(pCrsr->zKey, zStack[tos], aStack[tos].n);
pCrsr->zKey[aStack[tos].n] = 0;
rx = sqliteBtreeMoveto(pCrsr->pCursor, zStack[tos], aStack[tos].n, &res);
pCrsr->atFirst = rx==SQLITE_OK && res>0;
@@ -2610,10 +2621,12 @@ case OP_BeginIdx: {
/* Opcode: NextIdx P1 P2 *
**
** The P1 cursor points to an SQL index for which a BeginIdx operation
-** has been issued. This operation retrieves the next record number and
-** pushes that record number onto the stack. Or, if there are no more
-** record numbers for the given key, this opcode pushes nothing onto the
-** stack but instead jumps to instruction P2.
+** has been issued. This operation retrieves the next record from that
+** cursor and verifies that the key on the record matches the key that
+** was pulled from the stack by the BeginIdx instruction. If they do
+** match, then the last 4 bytes of the key on the record hold a record
+** number and that record number is extracted and pushed on the stack.
+** If the keys do not match, there is an immediate jump to instruction P2.
*/
case OP_NextIdx: {
int i = pOp->p1;
@@ -2636,7 +2649,7 @@ case OP_NextIdx: {
sqliteBtreeKeySize(pCur, &size);
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
+ memcmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
){
pc = pOp->p2 - 1;
POPSTACK;
@@ -3786,9 +3799,9 @@ default: {
char zBuf[100];
zBuf[0] = ' ';
zBuf[1] = (aStack[i].flags & STK_Dyn)!=0 ? 'z' : 's';
- zBuf[2] = ':';
+ zBuf[2] = '[';
k = 3;
- for(j=0; j<15 && j<aStack[i].n; j++){
+ for(j=0; j<20 && j<aStack[i].n; j++){
int c = zStack[i][j];
if( c==0 && j==aStack[i].n-1 ) break;
if( isprint(c) && !isspace(c) ){
@@ -3797,6 +3810,7 @@ default: {
zBuf[k++] = '.';
}
}
+ zBuf[k++] = ']';
zBuf[k++] = 0;
fprintf(p->trace, "%s", zBuf);
}else{