Add opcodes OP_ResultRow and OP_RegMakeRec which are register-based
equivalents to OP_Callback and OP_MakeRecord. Use the new opcodes. (CVS 4656) FossilOrigin-Name: 4c7f35da7751c61a9b61b1d95adddcc37fff3266
This commit is contained in:
parent
2f6751f91e
commit
a2a49dc9df
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Remove\sa\ssurplus\sOP_Close\sfrom\sdelete.c.\s\sFixes\sa\sproblem\swith\s(4654).\s(CVS\s4655)
|
||||
D 2008-01-02T13:05:51
|
||||
C Add\sopcodes\sOP_ResultRow\sand\sOP_RegMakeRec\swhich\sare\sregister-based\nequivalents\sto\sOP_Callback\sand\sOP_MakeRecord.\s\sUse\sthe\snew\sopcodes.\s(CVS\s4656)
|
||||
D 2008-01-02T14:28:13
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -79,7 +79,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
||||
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
||||
F src/alter.c 23d18ec53ef27fcb5e5ae9ca050217231ae15a0d
|
||||
F src/analyze.c cb25936f0148ee65c825a49f8064292a98050a50
|
||||
F src/analyze.c 40806c79cf2cd4fd0f6396d3d283fa05711439d1
|
||||
F src/attach.c 95658e74e3e0d1cbdb8658817516d4d1467fc13d
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||
@ -92,7 +92,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||
F src/delete.c 9a98d854ac2613d14616f5023577a6bec53b2d0e
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c c3fb939d6801071ce19243521ca444eca40b057a
|
||||
F src/expr.c 9f46128496d750edc0a2b32585a109defd9ce74c
|
||||
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
||||
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||
@ -131,7 +131,7 @@ F src/pragma.c 4a7f377a509eb14e35b09d4bf7b808ef647aad0b
|
||||
F src/prepare.c 7aeba7851773fbe3950a26b35d3389bef0eb1c62
|
||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||
F src/select.c 55b1a99e1d28a6ec3db2870a9f3f932fb3e7cb2a
|
||||
F src/select.c c0a225dc3133f914760908c7a73fce83b2834fbb
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 77895a54c2082157e169c857a2e244525ec25af7
|
||||
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
||||
@ -168,7 +168,7 @@ F src/update.c 24ab2157d360bc20ac4447f50d3a70cd993a7d98
|
||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
||||
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
||||
F src/vacuum.c 25ffbd766f25bca099ead1c1e11f5528c86102b8
|
||||
F src/vdbe.c 56a6e80d3357622305cffe6ea509e5d643e7dadb
|
||||
F src/vdbe.c 85e44649ad750d4c249751693ca93b4f57737b0f
|
||||
F src/vdbe.h a042e6d3b567ac81f182ca5b4639807621355822
|
||||
F src/vdbeInt.h 2985f1369273e635898cf5952237efcb3fdb21f3
|
||||
F src/vdbeapi.c 4acfaab3e10c99eb66c5332979d7b14a1c3505ae
|
||||
@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P f1966a8a47fca85f7862c0797a527ab01ac8b0c1
|
||||
R 087c5875afd19f460dd964b443ff0b13
|
||||
P 03cc91b3b0ff9be192532f8a404b3c7b827e1449
|
||||
R 7a6df4f12366724f53264755c79c306d
|
||||
U drh
|
||||
Z 539bcbd7c9fe31e2d5dc24d68f84bb81
|
||||
Z 99aefce3e13cf9b619d1d8015ce6d124
|
||||
|
@ -1 +1 @@
|
||||
03cc91b3b0ff9be192532f8a404b3c7b827e1449
|
||||
4c7f35da7751c61a9b61b1d95adddcc37fff3266
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code associated with the ANALYZE command.
|
||||
**
|
||||
** @(#) $Id: analyze.c,v 1.25 2008/01/02 00:34:37 drh Exp $
|
||||
** @(#) $Id: analyze.c,v 1.26 2008/01/02 14:28:13 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_ANALYZE
|
||||
#include "sqliteInt.h"
|
||||
@ -149,7 +149,7 @@ static void analyzeOneTable(
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem+i);
|
||||
}
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, iMem+nCol+i+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, iMem+nCol+i+1);
|
||||
}
|
||||
|
||||
/* Do the analysis.
|
||||
|
@ -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.322 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: expr.c,v 1.323 2008/01/02 14:28:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -1798,14 +1798,14 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
*/
|
||||
static const Token one = { (u8*)"1", 0, 1 };
|
||||
Select *pSel;
|
||||
int iMem;
|
||||
int sop;
|
||||
int iMem;
|
||||
|
||||
pExpr->iColumn = iMem = pParse->nMem++;
|
||||
pSel = pExpr->pSelect;
|
||||
iMem = pParse->nMem++;
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
sop = SRT_Mem;
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, iMem);
|
||||
VdbeComment((v, "Init subquery result"));
|
||||
}else{
|
||||
sop = SRT_Exists;
|
||||
@ -1817,6 +1817,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){
|
||||
return;
|
||||
}
|
||||
pExpr->iColumn = iMem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
76
src/select.c
76
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.374 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: select.c,v 1.375 2008/01/02 14:28:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -436,7 +436,7 @@ static void codeOffset(
|
||||
** A jump to addrRepeat is made and the N+1 values are popped from the
|
||||
** stack if the top N elements are not distinct.
|
||||
*/
|
||||
static void codeDistinct(
|
||||
static void codeDistinct_OLD(
|
||||
Vdbe *v, /* Generate code into this VM */
|
||||
int iTab, /* A sorting index used to test for distinctness */
|
||||
int addrRepeat, /* Jump to here if not distinct */
|
||||
@ -450,6 +450,29 @@ static void codeDistinct(
|
||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Add code that will check to make sure the top N elements of the
|
||||
** stack are distinct. iTab is a sorting index that holds previously
|
||||
** seen combinations of the N values. A new entry is made in iTab
|
||||
** if the current N values are new.
|
||||
**
|
||||
** A jump to addrRepeat is made and the N+1 values are popped from the
|
||||
** stack if the top N elements are not distinct.
|
||||
*/
|
||||
static void codeDistinct(
|
||||
Vdbe *v, /* Generate code into this VM */
|
||||
int iTab, /* A sorting index used to test for distinctness */
|
||||
int addrRepeat, /* Jump to here if not distinct */
|
||||
int iMem /* First element */
|
||||
){
|
||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
|
||||
VdbeComment((v, "skip indistinct records"));
|
||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate an error message when a SELECT is used within a subexpression
|
||||
** (example: "a IN (SELECT * FROM table)") but it has more than 1 result
|
||||
@ -490,8 +513,9 @@ static int selectInnerLoop(
|
||||
char *aff /* affinity string if eDest is SRT_Union */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
int i;
|
||||
int i, n;
|
||||
int hasDistinct; /* True if the DISTINCT keyword is present */
|
||||
int iMem; /* Start of memory holding result set */
|
||||
|
||||
if( v==0 ) return 0;
|
||||
assert( pEList!=0 );
|
||||
@ -506,14 +530,24 @@ static int selectInnerLoop(
|
||||
|
||||
/* Pull the requested columns.
|
||||
*/
|
||||
if( nColumn>0 ){
|
||||
n = nColumn;
|
||||
}else{
|
||||
n = pEList->nExpr;
|
||||
}
|
||||
iMem = pParse->nMem;
|
||||
pParse->nMem += n+1;
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, n, iMem);
|
||||
if( nColumn>0 ){
|
||||
for(i=0; i<nColumn; i++){
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
|
||||
sqlite3VdbeOp3Int(v, OP_Column, srcTab, i, iMem+i+1);
|
||||
}
|
||||
}else{
|
||||
nColumn = pEList->nExpr;
|
||||
sqlite3ExprCodeExprList(pParse, pEList);
|
||||
for(i=0; i<n; i++){
|
||||
sqlite3ExprIntoReg(pParse, pEList->a[i].pExpr, iMem+i+1);
|
||||
}
|
||||
}
|
||||
nColumn = n;
|
||||
|
||||
/* If the DISTINCT keyword was present on the SELECT statement
|
||||
** and this row has been seen before, then do not make this row
|
||||
@ -522,7 +556,7 @@ static int selectInnerLoop(
|
||||
if( hasDistinct ){
|
||||
assert( pEList!=0 );
|
||||
assert( pEList->nExpr==nColumn );
|
||||
codeDistinct(v, distinct, iContinue, nColumn);
|
||||
codeDistinct(v, distinct, iContinue, iMem);
|
||||
if( pOrderBy==0 ){
|
||||
codeOffset(v, p, iContinue, nColumn);
|
||||
}
|
||||
@ -538,7 +572,7 @@ static int selectInnerLoop(
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_COMPOUND_SELECT
|
||||
case SRT_Union: {
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
||||
if( aff ){
|
||||
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
||||
}
|
||||
@ -552,7 +586,7 @@ static int selectInnerLoop(
|
||||
*/
|
||||
case SRT_Except: {
|
||||
int addr;
|
||||
addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
||||
sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
|
||||
sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
|
||||
@ -564,7 +598,7 @@ static int selectInnerLoop(
|
||||
*/
|
||||
case SRT_Table:
|
||||
case SRT_EphemTab: {
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
||||
if( pOrderBy ){
|
||||
pushOntoSorter(pParse, pOrderBy, p);
|
||||
}else{
|
||||
@ -581,22 +615,20 @@ static int selectInnerLoop(
|
||||
** item into the set table with bogus data.
|
||||
*/
|
||||
case SRT_Set: {
|
||||
int addr1 = sqlite3VdbeCurrentAddr(v);
|
||||
int addr2;
|
||||
|
||||
assert( nColumn==1 );
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
addr2 = sqlite3VdbeAddOp(v, OP_IfMemNull, iMem+1, 0);
|
||||
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr,(iParm>>16)&0xff);
|
||||
if( pOrderBy ){
|
||||
/* At first glance you would think we could optimize out the
|
||||
** ORDER BY in this case since the order of entries in the set
|
||||
** does not matter. But there might be a LIMIT clause, in which
|
||||
** case the order does matter */
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+1, 0);
|
||||
pushOntoSorter(pParse, pOrderBy, p);
|
||||
}else{
|
||||
sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &p->affinity, 1);
|
||||
sqlite3VdbeOp3(v, OP_RegMakeRec, iMem, 0, &p->affinity, 1);
|
||||
sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, addr2);
|
||||
@ -607,7 +639,6 @@ static int selectInnerLoop(
|
||||
*/
|
||||
case SRT_Exists: {
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
/* The LIMIT clause will terminate the loop for us */
|
||||
break;
|
||||
}
|
||||
@ -618,6 +649,7 @@ static int selectInnerLoop(
|
||||
*/
|
||||
case SRT_Mem: {
|
||||
assert( nColumn==1 );
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, iMem+1, 0);
|
||||
if( pOrderBy ){
|
||||
pushOntoSorter(pParse, pOrderBy, p);
|
||||
}else{
|
||||
@ -635,12 +667,13 @@ static int selectInnerLoop(
|
||||
case SRT_Subroutine:
|
||||
case SRT_Callback: {
|
||||
if( pOrderBy ){
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RegMakeRec, iMem, 0);
|
||||
pushOntoSorter(pParse, pOrderBy, p);
|
||||
}else if( eDest==SRT_Subroutine ){
|
||||
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ResultRow, iMem+1, nColumn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -653,7 +686,6 @@ static int selectInnerLoop(
|
||||
*/
|
||||
default: {
|
||||
assert( eDest==SRT_Discard );
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -2876,10 +2908,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
return;
|
||||
}
|
||||
for(i=0; i<pAggInfo->nColumn; i++){
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, pAggInfo->aCol[i].iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, pAggInfo->aCol[i].iMem);
|
||||
}
|
||||
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, pFunc->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemNull, 0, pFunc->iMem);
|
||||
if( pFunc->iDistinct>=0 ){
|
||||
Expr *pE = pFunc->pExpr;
|
||||
if( pE->pList==0 || pE->pList->nExpr!=1 ){
|
||||
@ -2934,7 +2966,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
if( pF->iDistinct>=0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(v);
|
||||
assert( nArg==1 );
|
||||
codeDistinct(v, pF->iDistinct, addrNext, 1);
|
||||
codeDistinct_OLD(v, pF->iDistinct, addrNext, 1);
|
||||
}
|
||||
if( pF->pFunc->needCollSeq ){
|
||||
CollSeq *pColl = 0;
|
||||
|
34
src/vdbe.c
34
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.662 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: vdbe.c,v 1.663 2008/01/02 14:28:13 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -2384,6 +2384,7 @@ case OP_MakeRecord: {
|
||||
u32 serial_type; /* Type field */
|
||||
int containsNull = 0; /* True if any of the data fields are NULL */
|
||||
Mem *pData0; /* Bottom of the stack */
|
||||
Mem *pLast; /* Top of the stack */
|
||||
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. */
|
||||
@ -2411,11 +2412,13 @@ case OP_MakeRecord: {
|
||||
pCount = &p->aMem[nField];
|
||||
assert( pCount->flags & MEM_Int );
|
||||
assert( pCount->u.i>=0 && pCount->u.i+nField<p->nMem );
|
||||
assert( leaveOnStack==1 );
|
||||
leaveOnStack = 1;
|
||||
nField = pCount->u.i;
|
||||
pData0 = &pCount[1];
|
||||
pLast = &pData0[nField-1];
|
||||
}else{
|
||||
pData0 = &pTos[1-nField];
|
||||
pLast = pTos;
|
||||
assert( pData0>=p->aStack );
|
||||
}
|
||||
containsNull = 0;
|
||||
@ -2424,7 +2427,7 @@ case OP_MakeRecord: {
|
||||
/* Loop through the elements that will make up the record to figure
|
||||
** out how much space is required for the new record.
|
||||
*/
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
for(pRec=pData0; pRec<=pLast; pRec++){
|
||||
int len;
|
||||
if( zAffinity ){
|
||||
applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
|
||||
@ -2484,14 +2487,14 @@ case OP_MakeRecord: {
|
||||
|
||||
/* Write the record */
|
||||
i = sqlite3PutVarint(zNewRecord, nHdr);
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
for(pRec=pData0; pRec<=pLast; pRec++){
|
||||
serial_type = sqlite3VdbeSerialType(pRec, file_format);
|
||||
i += sqlite3PutVarint(&zNewRecord[i], serial_type); /* serial type */
|
||||
}
|
||||
if( addRowid ){
|
||||
i += sqlite3PutVarint(&zNewRecord[i], sqlite3VdbeSerialType(pRowid, 0));
|
||||
}
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){ /* serial data */
|
||||
for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */
|
||||
i += sqlite3VdbeSerialPut(&zNewRecord[i], nByte-i, pRec, file_format);
|
||||
}
|
||||
if( addRowid ){
|
||||
@ -4719,13 +4722,26 @@ case OP_IfMemZero: { /* no-push */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemNull P1 * *
|
||||
/* Opcode: IfMemNull P1 P2 *
|
||||
**
|
||||
** Store a NULL in memory cell P1
|
||||
** If the value of memory cell P1 is NULL, jump to P2.
|
||||
*/
|
||||
case OP_IfMemNull: { /* no-push */
|
||||
int i = pOp->p1;
|
||||
assert( i>=0 && i<p->nMem );
|
||||
if( p->aMem[i].flags & MEM_Null ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemNull * P2 *
|
||||
**
|
||||
** Store a NULL in memory cell P2
|
||||
*/
|
||||
case OP_MemNull: {
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
||||
sqlite3VdbeMemSetNull(&p->aMem[pOp->p1]);
|
||||
assert( pOp->p2>=0 && pOp->p2<p->nMem );
|
||||
sqlite3VdbeMemSetNull(&p->aMem[pOp->p2]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user