aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2004-05-28 16:00:21 +0000
committerdrh <drh@noemail.net>2004-05-28 16:00:21 +0000
commit51846b56edaba72e986cd7128f38547690c48671 (patch)
treef6b4001f3d42bdca49717dff08c6b7d0b135c11d /src
parent76d505baadc5afeaab6cdfb862c8a666a9f2eb5c (diff)
downloadsqlite-51846b56edaba72e986cd7128f38547690c48671.tar.gz
sqlite-51846b56edaba72e986cd7128f38547690c48671.zip
Factor common code for generating index keys into a procedure. Other
speed improvements and bug fixes. (CVS 1487) FossilOrigin-Name: 6661bb5f9c1692f94b8b7d900b6be07f027e6324
Diffstat (limited to 'src')
-rw-r--r--src/build.c17
-rw-r--r--src/delete.c41
-rw-r--r--src/pragma.c14
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/utf.c8
-rw-r--r--src/util.c8
-rw-r--r--src/vdbe.c32
-rw-r--r--src/vdbeaux.c9
8 files changed, 76 insertions, 56 deletions
diff --git a/src/build.c b/src/build.c
index 92efbf084..bf208acd2 100644
--- a/src/build.c
+++ b/src/build.c
@@ -23,7 +23,7 @@
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.196 2004/05/28 12:33:31 danielk1977 Exp $
+** $Id: build.c,v 1.197 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1875,7 +1875,7 @@ void sqlite3CreateIndex(
}
sqlite3VdbeAddOp(v, OP_String, 0, 0);
if( pStart && pEnd ){
- sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", n);
+ sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
sqlite3VdbeAddOp(v, OP_String, 0, 0);
n = Addr(pEnd->z) - Addr(pName->z) + 1;
sqlite3VdbeChangeP3(v, -1, pName->z, n);
@@ -1890,17 +1890,8 @@ void sqlite3CreateIndex(
sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol);
lbl2 = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
- lbl1 = sqlite3VdbeAddOp(v, OP_Recno, 2, 0);
- for(i=0; i<pIndex->nColumn; i++){
- int iCol = pIndex->aiColumn[i];
- if( pTab->iPKey==iCol ){
- sqlite3VdbeAddOp(v, OP_Dup, i, 0);
- }else{
- sqlite3VdbeAddOp(v, OP_Column, 2, iCol);
- }
- }
- sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
- sqlite3IndexAffinityStr(v, pIndex);
+ lbl1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3GenerateIndexKey(v, pIndex, 2);
sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
"indexed columns are not unique", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Next, 2, lbl1);
diff --git a/src/delete.c b/src/delete.c
index 2e69961d7..bd77b59bc 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
-** $Id: delete.c,v 1.70 2004/05/26 10:11:05 danielk1977 Exp $
+** $Id: delete.c,v 1.71 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
@@ -379,17 +379,34 @@ void sqlite3GenerateRowIndexDelete(
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
int j;
if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
- sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
- for(j=0; j<pIdx->nColumn; j++){
- int idx = pIdx->aiColumn[j];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp(v, OP_Dup, j, 0);
- }else{
- sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
- }
- }
- sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
- sqlite3IndexAffinityStr(v, pIdx);
+ sqlite3GenerateIndexKey(v, pIdx, iCur);
sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
}
}
+
+/*
+** Generate code that will assemble an index key and put it on the top
+** of the tack. The key with be for index pIdx which is an index on pTab.
+** iCur is the index of a cursor open on the pTab table and pointing to
+** the entry that needs indexing.
+*/
+void sqlite3GenerateIndexKey(
+ Vdbe *v, /* Generate code into this VDBE */
+ Index *pIdx, /* The index for which to generate a key */
+ int iCur /* Cursor number for the pIdx->pTable table */
+){
+ int j;
+ Table *pTab = pIdx->pTable;
+
+ sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+ for(j=0; j<pIdx->nColumn; j++){
+ int idx = pIdx->aiColumn[j];
+ if( idx==pTab->iPKey ){
+ sqlite3VdbeAddOp(v, OP_Dup, j, 0);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
+ }
+ }
+ sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+ sqlite3IndexAffinityStr(v, pIdx);
+}
diff --git a/src/pragma.c b/src/pragma.c
index 002408bc2..19552f245 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.32 2004/05/26 10:11:06 danielk1977 Exp $
+** $Id: pragma.c,v 1.33 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -642,17 +642,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
{ OP_Concat, 4, 0, 0},
{ OP_Callback, 1, 0, 0},
};
- sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
- for(k=0; k<pIdx->nColumn; k++){
- int idx = pIdx->aiColumn[k];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
- }else{
- sqlite3VdbeAddOp(v, OP_Column, 1, idx);
- }
- }
- sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
- sqlite3IndexAffinityStr(v, pIdx);
+ sqlite3GenerateIndexKey(v, pIdx, 1);
jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7f7e049dd..c19a6cc35 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.259 2004/05/28 12:33:31 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.260 2004/05/28 16:00:22 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
@@ -1267,6 +1267,7 @@ int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
+void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
int sqlite3OpenTableAndIndices(Parse*, Table*, int);
diff --git a/src/utf.c b/src/utf.c
index 255df323a..ff51eed51 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.12 2004/05/27 09:28:43 danielk1977 Exp $
+** $Id: utf.c,v 1.13 2004/05/28 16:00:22 drh Exp $
**
** Notes on UTF-8:
**
@@ -25,9 +25,9 @@
**
** Notes on UTF-16: (with wwww+1==uuuuu)
**
-** Word-0 Word-1 Value
-** 110110wwwwxxxxxx 110111yyyyyyyyyy 000uuuuu xxxxxxyy yyyyyyyy
-** xxxxxxxxyyyyyyyy 00000000 xxxxxxxx yyyyyyyy
+** Word-0 Word-1 Value
+** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx
+** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx
**
**
** BOM or Byte Order Mark:
diff --git a/src/util.c b/src/util.c
index 92dff9131..4aea0c802 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.93 2004/05/28 11:37:28 danielk1977 Exp $
+** $Id: util.c,v 1.94 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -393,7 +393,7 @@ void sqlite3SetNString(char **pz, ...){
while( (z = va_arg(ap, const char*))!=0 ){
n = va_arg(ap, int);
if( n<=0 ) n = strlen(z);
- strncpy(zResult, z, n);
+ memcpy(zResult, z, n);
zResult += n;
}
*zResult = 0;
@@ -1330,7 +1330,3 @@ void *sqlite3HexToBlob(const char *z){
}
return zBlob;
}
-
-
-
-
diff --git a/src/vdbe.c b/src/vdbe.c
index e695961b9..22b61be7f 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.344 2004/05/28 11:37:28 danielk1977 Exp $
+** $Id: vdbe.c,v 1.345 2004/05/28 16:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1869,7 +1869,11 @@ case OP_Column: {
aType = pC->aType;
aOffset = pC->aOffset;
}else{
- aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
+ if( pC && pC->aType ){
+ aType = pC->aType;
+ }else{
+ aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
+ }
aOffset = &aType[nField];
if( aType==0 ){
goto no_mem;
@@ -1944,6 +1948,7 @@ case OP_Column: {
zData = sMem.z;
}
sqlite3VdbeSerialGet(zData, aType[p2], pTos);
+ sqlite3VdbeMemMakeWriteable(pTos);
pTos->enc = db->enc;
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
@@ -2049,6 +2054,7 @@ case OP_MakeRecord: {
int addRowid; /* True to append a rowid column at the end */
u32 serial_type; /* Type field */
int containsNull; /* True if any of the data fields are NULL */
+ char zTemp[NBFS]; /* Space to hold small records */
Mem *pData0 = &pTos[1-nField];
assert( pData0>=p->aStack );
@@ -2094,9 +2100,13 @@ case OP_MakeRecord: {
}
/* Allocate space for the new record. */
- zNewRecord = sqliteMallocRaw(nByte);
- if( !zNewRecord ){
- goto no_mem;
+ if( nByte>sizeof(zTemp) ){
+ zNewRecord = sqliteMallocRaw(nByte);
+ if( !zNewRecord ){
+ goto no_mem;
+ }
+ }else{
+ zNewRecord = zTemp;
}
/* Write the record */
@@ -2131,8 +2141,16 @@ case OP_MakeRecord: {
}
pTos++;
pTos->n = nByte;
- pTos->z = zNewRecord;
- pTos->flags = MEM_Blob | MEM_Dyn;
+ if( nByte<=sizeof(zTemp) ){
+ assert( zNewRecord==zTemp );
+ pTos->z = pTos->zShort;
+ memcpy(pTos->zShort, zTemp, nByte);
+ pTos->flags = MEM_Blob | MEM_Short;
+ }else{
+ assert( zNewRecord!=zTemp );
+ pTos->z = zNewRecord;
+ pTos->flags = MEM_Blob | MEM_Dyn;
+ }
/* If P2 is non-zero, and if the key contains a NULL value, and if this
** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 1ad5d3c8b..4bb52261d 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1219,6 +1219,13 @@ u32 sqlite3VdbeSerialType(Mem *pMem){
*/
int sqlite3VdbeSerialTypeLen(u32 serial_type){
assert( serial_type!=0 );
+ if( serial_type>6 ){
+ return (serial_type-12)/2;
+ }else{
+ static u8 aSize[] = { 0, 1, 2, 4, 8, 8, 0, };
+ return aSize[serial_type];
+ }
+#if 0
switch(serial_type){
case 6: return 0; /* NULL */
case 1: return 1; /* 1 byte integer */
@@ -1229,6 +1236,7 @@ int sqlite3VdbeSerialTypeLen(u32 serial_type){
}
assert( serial_type>=12 );
return ((serial_type-12)>>1); /* text or blob */
+#endif
}
/*
@@ -1329,7 +1337,6 @@ int sqlite3VdbeSerialGet(
}else{
pMem->flags = MEM_Blob | MEM_Ephem;
}
- sqlite3VdbeMemMakeWriteable(pMem);
return len;
}