diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/delete.c | 4 | ||||
-rw-r--r-- | src/expr.c | 8 | ||||
-rw-r--r-- | src/insert.c | 7 | ||||
-rw-r--r-- | src/select.c | 17 | ||||
-rw-r--r-- | src/vdbe.c | 118 | ||||
-rw-r--r-- | src/where.c | 8 |
6 files changed, 56 insertions, 106 deletions
diff --git a/src/delete.c b/src/delete.c index 5f326908b..868bbd2ac 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.74 2004/06/16 12:00:49 danielk1977 Exp $ +** $Id: delete.c,v 1.75 2004/06/17 07:53:02 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -413,6 +413,6 @@ void sqlite3GenerateIndexKey( sqlite3VdbeAddOp(v, OP_Column, iCur, idx); } } - sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); sqlite3IndexAffinityStr(v, pIdx); } diff --git a/src/expr.c b/src/expr.c index 568447bf4..39978d068 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.143 2004/06/16 12:00:50 danielk1977 Exp $ +** $Id: expr.c,v 1.144 2004/06/17 07:53:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -911,7 +911,7 @@ int sqlite3ExprResolveIds( /* Evaluate the expression and insert it into the temp table */ sqlite3ExprCode(pParse, pE2); - sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0); } @@ -1314,7 +1314,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* Figure out the affinity to use to create a key from the results ** of the expression. affinityStr stores a static string suitable for - ** P3 of OP_MakeKey. + ** P3 of OP_MakeRecord. */ affStr = sqlite3AffinityString(comparisonAffinity(pExpr)); @@ -1329,7 +1329,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_Pop, 2, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7); - sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC); /* addr + 4 */ + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); /* addr + 4 */ sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7); sqlite3VdbeAddOp(v, OP_AddImm, -1, 0); /* addr + 6 */ diff --git a/src/insert.c b/src/insert.c index 8dedbbbee..ef4f03d7c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.111 2004/06/16 12:00:54 danielk1977 Exp $ +** $Id: insert.c,v 1.112 2004/06/17 07:53:03 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -867,7 +867,7 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1); } } - jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0); + jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); sqlite3IndexAffinityStr(v, pIdx); /* Find out what action to take in case there is an indexing conflict */ @@ -936,8 +936,9 @@ void sqlite3GenerateConstraintChecks( default: assert(0); } contAddr = sqlite3VdbeCurrentAddr(v); + assert( contAddr<(1<<24) ); #if NULL_DISTINCT_FOR_UNIQUE - sqlite3VdbeChangeP2(v, jumpInst1, contAddr); + sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24)); #endif sqlite3VdbeChangeP2(v, jumpInst2, contAddr); } diff --git a/src/select.c b/src/select.c index 9c601423c..27e7f1193 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.191 2004/06/16 12:02:47 danielk1977 Exp $ +** $Id: select.c,v 1.192 2004/06/17 07:53:03 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -316,7 +316,7 @@ static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){ for(i=0; i<pOrderBy->nExpr; i++){ sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr); } - sqlite3VdbeAddOp(v, OP_MakeKey, pOrderBy->nExpr, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0); sqlite3VdbeAddOp(v, OP_SortPut, 0, 0); } @@ -384,8 +384,9 @@ static int selectInnerLoop( #if NULL_ALWAYS_DISTINCT sqlite3VdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqlite3VdbeCurrentAddr(v)+7); #endif - /* Deliberately leave the affinity string off of the following OP_MakeKey */ - sqlite3VdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1); + /* Deliberately leave the affinity string off of the following + ** OP_MakeRecord */ + sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0); sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); @@ -452,7 +453,7 @@ static int selectInnerLoop( char aff = (iParm>>16)&0xFF; aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff); affStr = sqlite3AffinityString(aff); - sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, affStr, P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); } @@ -579,7 +580,7 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeOp3(v, OP_MakeKey, 1, 0, "n", P3_STATIC); + sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); break; @@ -2514,9 +2515,9 @@ int sqlite3Select( for(i=0; i<pGroupBy->nExpr; i++){ sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr); } - /* No affinity string is attached to the following OP_MakeKey + /* No affinity string is attached to the following OP_MakeRecord ** because we do not need to do any coercion of datatypes. */ - sqlite3VdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0); lbl1 = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1); for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){ diff --git a/src/vdbe.c b/src/vdbe.c index 742dec22c..979889d65 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.377 2004/06/16 12:02:54 danielk1977 Exp $ +** $Id: vdbe.c,v 1.378 2004/06/17 07:53:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2092,66 +2092,6 @@ case OP_Column: { break; } -/* Opcode: MakeKey P1 P2 P3 -** -** Convert the top P1 entries of the stack into a single entry suitable -** for use as the key in an index. If P2 is zero, then the original -** entries are popped off the stack. If P2 is not zero, the original -** entries remain on the stack. -** -** P3 is interpreted in the same way as for MakeIdxKey. -*/ -/* Opcode: MakeIdxKey P1 P2 P3 -** -** Convert the top P1 entries of the stack into a single entry suitable -** for use as the key in an index. In addition, take one additional integer -** off of the stack, treat that integer as an eight-byte record number, and -** append the integer to the key as a varint. Thus a total of P1+1 entries -** are popped from the stack for this instruction and a single entry is -** pushed back. -** -** If P2 is not zero and one or more of the P1 entries that go into the -** generated key is NULL, then jump to P2 after the new key has been -** pushed on the stack. In other words, jump to P2 if the key is -** guaranteed to be unique. This jump can be used to skip a subsequent -** uniqueness test. -** -** P3 may be a string that is P1 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth -** field of the index key (i.e. the first character of P3 corresponds to the -** lowest element on the stack). -** -** Character Column affinity -** ------------------------------ -** 'n' NUMERIC -** 'i' INTEGER -** 't' TEXT -** 'o' NONE -** -** If P3 is NULL then no datatype coercion occurs. -*/ -/* Opcode MakeRecord P1 * P3 -** -** Convert the top P1 entries of the stack into a single entry -** suitable for use as a data record in a database table. The -** details of the format are irrelavant as long as the OP_Column -** opcode can decode the record later. Refer to source code -** comments for the details of the record format. -** -** P3 may be a string that is P1 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth -** field of the index key (i.e. the first character of P3 corresponds to the -** lowest element on the stack). -** -** Character Column affinity -** ------------------------------ -** 'n' NUMERIC -** 'i' INTEGER -** 't' TEXT -** 'o' NONE -** -** If P3 is NULL then all index fields have the affinity NONE. -*/ /* Opcode MakeRecord P1 P2 P3 ** ** Convert the top abs(P1) entries of the stack into a single entry @@ -2165,8 +2105,12 @@ case OP_Column: { ** The original stack entries are popped from the stack if P1>0 but ** remain on the stack if P1<0. ** -** If P2 is not zero and one or more of the entries are NULL, then jump -** to P2. This feature can be used to skip a uniqueness test on indices. +** The P2 argument is divided into two 16-bit words before it is processed. +** If the hi-word is non-zero, then an extra integer is read from the stack +** and appended to the record as a varint. If the low-word of P2 is not +** zero and one or more of the entries are NULL, then jump to the value of +** the low-word of P2. This feature can be used to skip a uniqueness test +** on indices. ** ** P3 may be a string that is P1 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth @@ -2182,8 +2126,6 @@ case OP_Column: { ** ** If P3 is NULL then all index fields have the affinity NONE. */ -case OP_MakeKey: -case OP_MakeIdxKey: case OP_MakeRecord: { /* Assuming the record contains N fields, the record format looks ** like this: @@ -2200,24 +2142,32 @@ case OP_MakeRecord: { ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ - int nField = pOp->p1; unsigned char *zNewRecord; unsigned char *zCsr; - char *zAffinity; Mem *pRec; Mem *pRowid = 0; - int nData = 0; /* Number of bytes of data space */ - int nHdr = 0; /* Number of bytes of header space */ - int nByte = 0; /* Space required for this record */ - 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 ); + int nData = 0; /* Number of bytes of data space */ + int nHdr = 0; /* Number of bytes of header space */ + int nByte = 0; /* Space required for this record */ + u32 serial_type; /* Type field */ + int containsNull = 0; /* True if any of the data fields are NULL */ + char zTemp[NBFS]; /* Space to hold small records */ + Mem *pData0; + + int leaveOnStack; /* If true, leave the entries on the stack */ + int nField; /* Number of fields in the record */ + int jumpIfNull; /* Jump here if non-zero and any entries are NULL. */ + int addRowid; /* True to append a rowid column at the end */ + char *zAffinity; /* The affinity string for the record */ + + leaveOnStack = ((pOp->p1<0)?1:0); + nField = pOp->p1 * (leaveOnStack?-1:1); + jumpIfNull = (pOp->p2 & 0x00FFFFFF); + addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0; zAffinity = pOp->p3; - addRowid = pOp->opcode==OP_MakeIdxKey; + + pData0 = &pTos[1-nField]; + assert( pData0>=p->aStack ); containsNull = 0; /* Loop through the elements that will make up the record to figure @@ -2293,8 +2243,8 @@ case OP_MakeRecord: { goto abort_due_to_error; } - /* Pop nField entries from the stack and push the new entry on */ - if( addRowid || pOp->p2==0 ){ + /* Pop entries off the stack if required. Push the new record on. */ + if( !leaveOnStack ){ popStack(&pTos, nField+addRowid); } pTos++; @@ -2311,11 +2261,9 @@ case OP_MakeRecord: { pTos->xDel = 0; } - /* 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. - */ - if( pOp->p2 && containsNull && addRowid ){ - pc = pOp->p2 - 1; + /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */ + if( jumpIfNull && containsNull ){ + pc = jumpIfNull - 1; } break; } diff --git a/src/where.c b/src/where.c index 40ba9fb8c..2afb82550 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.106 2004/06/16 12:03:10 danielk1977 Exp $ +** $Id: where.c,v 1.107 2004/06/17 07:53:04 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -827,7 +827,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_Goto, 0, brk); /* Generate an index key from the top nColumn elements of the stack */ - sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); @@ -1029,7 +1029,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, nCol, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, brk); - sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0); sqlite3IndexAffinityStr(v, pIdx); if( pLevel->bRev ){ int op = leFlag ? OP_MoveLe : OP_MoveLt; @@ -1083,7 +1083,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, nCol, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, brk); - sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, nCol, 0); sqlite3IndexAffinityStr(v, pIdx); if( pLevel->bRev ){ pLevel->iMem = pParse->nMem++; |