Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Registerify binary operators. Add register tracing to debugging output. (CVS 4686) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
66396d2f0289e36b5fc0af5078c08d1b |
User & Date: | drh 2008-01-05 16:29:28.000 |
Context
2008-01-05
| ||
17:39 | First pass at optimizing max()/min() as described in #2853. Some refinements to come. (CVS 4687) (check-in: c449e04f18 user: danielk1977 tags: trunk) | |
16:29 | Registerify binary operators. Add register tracing to debugging output. (CVS 4686) (check-in: 66396d2f02 user: drh tags: trunk) | |
06:51 | Expression code generator takes advantage of recent opcode changes. (CVS 4685) (check-in: 6c78d2a49a user: drh tags: trunk) | |
Changes
Changes to mkopcodeh.awk.
︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | # bit 1: pushes a result onto stack # bit 2: output to p1. release p1 before opcode runs # for(i=0; i<=max; i++) bv[i] = 0; for(name in op){ x = op[name] a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0 if( jump[name] ) a0 = 1; if( nopush[name]==0 ) a1 = 2; if( out2_prerelease[name] ) a2 = 4; if( in1[name] ) a3 = 8; if( in2[name] ) a4 = 16; if( in3[name] ) a5 = 32; if( out2[name] ) a6 = 64; if( out3[name] ) a7 = 128; | > | | | | | | | | | > | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | # bit 1: pushes a result onto stack # bit 2: output to p1. release p1 before opcode runs # for(i=0; i<=max; i++) bv[i] = 0; for(name in op){ x = op[name] a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0 a8 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0 if( jump[name] ) a0 = 1; if( nopush[name]==0 ) a1 = 2; if( out2_prerelease[name] ) a2 = 4; if( in1[name] ) a3 = 8; if( in2[name] ) a4 = 16; if( in3[name] ) a5 = 32; if( out2[name] ) a6 = 64; if( out3[name] ) a7 = 128; bv[x] = a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15; } print "\n" print "/* Properties such as \"out2\" or \"jump\" that are specified in" print "** comments following the "case" for each opcode in the vdbe.c" print "** are encoded into bitvectors as follows:" print "*/" print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */" print "#define OPFLG_PUSH 0x0002 /* ~no-push: Does not push */" print "#define OPFLG_OUT2_PRERELEASE 0x0004 /* out2-prerelease: */" print "#define OPFLG_IN1 0x0008 /* in1: P1 is an input */" print "#define OPFLG_IN2 0x0010 /* in2: P2 is an input */" print "#define OPFLG_IN3 0x0020 /* in3: P3 is an input */" print "#define OPFLG_OUT2 0x0040 /* out2: P2 is an output */" print "#define OPFLG_OUT3 0x0080 /* out3: P3 is an output */" print "#define OPFLG_INITIALIZER {\\" for(i=0; i<=max; i++){ if( i%8==0 ) printf("/* %3d */",i) printf " 0x%04x,", bv[i] if( i%8==7 ) printf("\\\n"); } print "}" } |
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** ** @(#) $Id: analyze.c,v 1.34 2008/01/05 16:29:28 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table on cursor ** iStatCur. |
︙ | ︙ | |||
155 156 157 158 159 160 161 | endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); topOfLoop = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); for(i=0; i<nCol; i++){ sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i); sqlite3VdbeAddOp1(v, OP_SCopy, iMem+nCol+i+1); | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); topOfLoop = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); for(i=0; i<nCol; i++){ sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i); sqlite3VdbeAddOp1(v, OP_SCopy, iMem+nCol+i+1); sqlite3VdbeAddOp1(v, OP_Ne, 0x100); /* FIX ME: use collating sequence */ } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; i<nCol; i++){ addr = sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); } |
︙ | ︙ | |||
191 192 193 194 195 196 197 | */ sqlite3VdbeAddOp1(v, OP_SCopy, iMem); addr = sqlite3VdbeAddOp0(v, OP_IfNot); sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0); sqlite3VdbeAddOp1(v, OP_SCopy, iMem); | < | | | | | | < < < < < | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | */ sqlite3VdbeAddOp1(v, OP_SCopy, iMem); addr = sqlite3VdbeAddOp0(v, OP_IfNot); sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0); sqlite3VdbeAddOp1(v, OP_SCopy, iMem); for(i=0; i<nCol; i++){ sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, " ", 0); sqlite3VdbeAddOp0(v, OP_Concat); sqlite3VdbeAddOp2(v, OP_Add, iMem, iMem+i+1); sqlite3VdbeAddOp2(v, OP_AddImm, 0, -1); sqlite3VdbeAddOp2(v, OP_Divide, iMem+i+1, 0); sqlite3VdbeAddOp0(v, OP_ToInt); sqlite3VdbeAddOp0(v, OP_Concat); } sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0); sqlite3CodeInsert(pParse, iStatCur, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, addr); } } |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.334 2008/01/05 16:29:28 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 | case TK_REM: case TK_BITAND: case TK_BITOR: case TK_SLASH: case TK_LSHIFT: case TK_RSHIFT: case TK_CONCAT: { assert( TK_AND==OP_And ); assert( TK_OR==OP_Or ); assert( TK_PLUS==OP_Add ); assert( TK_MINUS==OP_Subtract ); assert( TK_REM==OP_Remainder ); assert( TK_BITAND==OP_BitAnd ); assert( TK_BITOR==OP_BitOr ); assert( TK_SLASH==OP_Divide ); assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); | > | | | | > > > | 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 | case TK_REM: case TK_BITAND: case TK_BITOR: case TK_SLASH: case TK_LSHIFT: case TK_RSHIFT: case TK_CONCAT: { int r1, r2; assert( TK_AND==OP_And ); assert( TK_OR==OP_Or ); assert( TK_PLUS==OP_Add ); assert( TK_MINUS==OP_Subtract ); assert( TK_REM==OP_Remainder ); assert( TK_BITAND==OP_BitAnd ); assert( TK_BITOR==OP_BitOr ); assert( TK_SLASH==OP_Divide ); assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); r1 = sqlite3ExprCode(pParse, pExpr->pLeft, 0); r2 = sqlite3ExprCode(pParse, pExpr->pRight, 0); sqlite3VdbeAddOp3(v, op, r2, r1, target); if( r1==0 ) stackChng--; if( r2==0 ) stackChng--; if( target==0 ) stackChng++; inReg = target; break; } case TK_UMINUS: { Expr *pLeft = pExpr->pLeft; assert( pLeft ); if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){ Token *p = &pLeft->token; |
︙ | ︙ | |||
2345 2346 2347 2348 2349 2350 2351 | VdbeComment((v, "raise(IGNORE)")); } stackChng = 0; break; } #endif } | | > | > > > | 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | VdbeComment((v, "raise(IGNORE)")); } stackChng = 0; break; } #endif } if( inReg!=target ){ if( origTarget!=-1 ){ sqlite3VdbeAddOp2(v, (inReg>0 ? OP_SCopy : OP_Move), inReg, target); }else{ target = inReg; } stackChng = 0; } if( pParse->ckOffset ){ pParse->ckOffset += stackChng; assert( pParse->ckOffset ); } return target; |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.161 2008/01/05 16:29:28 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) |
︙ | ︙ | |||
883 884 885 886 887 888 889 | if( cnt==0 ) continue; sqlite3VdbeAddOp2(v, OP_IntegrityCk, 1, i); addr = sqlite3VdbeAddOp2(v, OP_IsNull, -1, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); | | | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | if( cnt==0 ) continue; sqlite3VdbeAddOp2(v, OP_IntegrityCk, 1, i); addr = sqlite3VdbeAddOp2(v, OP_IsNull, -1, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); sqlite3VdbeAddOp2(v, OP_Pull, 1, 0); sqlite3VdbeAddOp0(v, OP_Concat); sqlite3VdbeAddOp2(v, OP_Callback, 1, 0); sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. */ for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); |
︙ | ︙ | |||
910 911 912 913 914 915 916 | int jmp2; static const VdbeOpList idxErr[] = { { OP_AddImm, 1, -1, 0}, { OP_String8, 0, 0, 0}, /* 1 */ { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, 0}, /* 3 */ { OP_String8, 0, 0, 0}, /* 4 */ | | > > | 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 | int jmp2; static const VdbeOpList idxErr[] = { { OP_AddImm, 1, -1, 0}, { OP_String8, 0, 0, 0}, /* 1 */ { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, 0}, /* 3 */ { OP_String8, 0, 0, 0}, /* 4 */ { OP_Concat, 0, 0, 0}, { OP_Concat, 0, 0, 0}, { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; sqlite3GenerateIndexKey(v, pIdx, 1); jmp2 = sqlite3VdbeAddOp2(v, OP_Found, j+2, 0); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.684 2008/01/05 16:29:28 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
174 175 176 177 178 179 180 | /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** this file. */ | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** this file. */ static unsigned short opcodeProperty[] = OPFLG_INITIALIZER; /* ** Return true if an opcode has any of the OPFLG_xxx properties ** specified by mask. */ int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ assert( opcode>0 && opcode<sizeof(opcodeProperty) ); |
︙ | ︙ | |||
392 393 394 395 396 397 398 399 400 401 402 403 404 405 | sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); k += strlen(&zBuf[k]); zBuf[k++] = 0; } } #endif #ifdef VDBE_PROFILE /* ** The following routine only works on pentium-class processors. ** It uses the RDTSC opcode to read the cycle count value out of the ** processor and returns that value. This can be used for high-res ** profiling. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); k += strlen(&zBuf[k]); zBuf[k++] = 0; } } #endif #ifdef SQLITE_DEBUG /* ** Print the value of a register for tracing purposes: */ static void memTracePrint(FILE *out, Mem *p){ if( p->flags & MEM_Null ){ fprintf(out, " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ fprintf(out, " si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ fprintf(out, " i:%lld", p->u.i); }else if( p->flags & MEM_Real ){ fprintf(out, " r:%g", p->r); }else{ char zBuf[200]; sqlite3VdbeMemPrettyPrint(p, zBuf); fprintf(out, " "); fprintf(out, "%s", zBuf); } } static void registerTrace(FILE *out, int iReg, Mem *p){ fprintf(out, "REG[%d] = ", iReg); memTracePrint(out, p); fprintf(out, "\n"); } #endif #ifdef SQLITE_DEBUG # define REGISTER_TRACE(R,M) if(p->trace&&R>0)registerTrace(p->trace,R,M) #else # define REGISTER_TRACE(R,M) #endif #ifdef VDBE_PROFILE /* ** The following routine only works on pentium-class processors. ** It uses the RDTSC opcode to read the cycle count value out of the ** processor and returns that value. This can be used for high-res ** profiling. |
︙ | ︙ | |||
463 464 465 466 467 468 469 | ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ Mem *pTos; /* Top entry in the operand stack */ | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ Mem *pTos; /* Top entry in the operand stack */ Mem *pIn1, *pIn2, *pIn3; /* Input operands */ Mem *pOut; /* Output operand */ int nPop = 0; /* Number of times to pop the stack */ u8 opProperty; #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif |
︙ | ︙ | |||
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | assert( pOp->p1>=0 ); if( pOp->p1==0 ){ pIn1 = pTos; nPop = 1; }else{ assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; } if( (opProperty & OPFLG_IN2)!=0 ){ assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pIn2 = &pTos[-nPop]; nPop++; }else{ assert( pOp->p2<=p->nMem ); pIn2 = &p->aMem[pOp->p2]; } if( (opProperty & OPFLG_OUT3)!=0 ){ assert( pOp->p3>=0 ); if( pOp->p3==0 ){ | > > > > > | > > < | | > > > > | > > < | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 | assert( pOp->p1>=0 ); if( pOp->p1==0 ){ pIn1 = pTos; nPop = 1; }else{ assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; REGISTER_TRACE(pOp->p1, pIn1); } if( (opProperty & OPFLG_IN2)!=0 ){ assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pIn2 = &pTos[-nPop]; nPop++; }else{ assert( pOp->p2<=p->nMem ); pIn2 = &p->aMem[pOp->p2]; REGISTER_TRACE(pOp->p2, pIn2); } if( (opProperty & OPFLG_OUT3)!=0 ){ assert( pOp->p3>=0 ); if( pOp->p3==0 ){ nPop--; if( nPop<0 ){ assert( nPop==(-1) ); pTos++; nPop = 0; } pOut = &pTos[-nPop]; }else{ assert( pOp->p3<=p->nMem ); pOut = &p->aMem[pOp->p3]; } } }else if( (opProperty & OPFLG_IN3)!=0 ){ assert( pOp->p3>=0 ); if( pOp->p3==0 ){ pIn3 = &pTos[-nPop]; nPop++; }else{ assert( pOp->p3<=p->nMem ); pIn3 = &p->aMem[pOp->p3]; REGISTER_TRACE(pOp->p3, pIn3); } }else if( (opProperty & OPFLG_OUT2)!=0 ){ assert( pOp->p2>=0 ); if( pOp->p2==0 ){ nPop--; if( nPop<0 ){ assert( nPop==(-1) ); pTos++; nPop = 0; } pOut = &pTos[-nPop]; }else{ assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; } } } |
︙ | ︙ | |||
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | case OP_SCopy: { if( pOp->p1<=0 ){ pIn1 = &pTos[pOp->p1]; assert( pIn1>=p->aStack ); }else{ assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; } assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pOut = ++pTos; pOut->flags = MEM_Null; }else{ assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; } if( pOp->opcode==OP_Move ){ rc = sqlite3VdbeMemMove(pOut, pIn1); if( pOp->p1==0 ) pTos--; }else{ sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); if( pOp->opcode==OP_Copy ){ Deephemeralize(pOut); } } break; } /* Opcode: Pull P1 * * ** ** The P1-th element is removed from its current location on ** the stack and pushed back on top of the stack. The | > > | 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 | case OP_SCopy: { if( pOp->p1<=0 ){ pIn1 = &pTos[pOp->p1]; assert( pIn1>=p->aStack ); }else{ assert( pOp->p1<=p->nMem ); pIn1 = &p->aMem[pOp->p1]; REGISTER_TRACE(pOp->p1, pIn1); } assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pOut = ++pTos; pOut->flags = MEM_Null; }else{ assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; } if( pOp->opcode==OP_Move ){ rc = sqlite3VdbeMemMove(pOut, pIn1); if( pOp->p1==0 ) pTos--; }else{ sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); if( pOp->opcode==OP_Copy ){ Deephemeralize(pOut); } } REGISTER_TRACE(pOp->p2, pOut); break; } /* Opcode: Pull P1 * * ** ** The P1-th element is removed from its current location on ** the stack and pushed back on top of the stack. The |
︙ | ︙ | |||
1213 1214 1215 1216 1217 1218 1219 | p->popStack = 0; p->pc = pc + 1; p->pTos = pTos; rc = SQLITE_ROW; goto vdbe_return; } | | | < < | < < < > | < < < < < < < < < | > | | | | | < < | > > | < < < < < < > | < < < < < < < < < | | < < < < < < | | > > | | < | < < < < | | | | | < | 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 | p->popStack = 0; p->pc = pc + 1; p->pTos = pTos; rc = SQLITE_ROW; goto vdbe_return; } /* Opcode: Concat P1 P2 P3 * * ** ** Add the text in register P1 onto the end of the text in ** register P2 and store the result in register P3. ** If either the P1 or P2 text are NULL then store NULL in P3. */ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ char *zNew; i64 nByte; if( (pIn1->flags | pIn2->flags) & MEM_Null ){ Release(pOut); pOut->flags = MEM_Null; break; } ExpandBlob(pIn1); Stringify(pIn1, encoding); ExpandBlob(pIn2); Stringify(pIn2, encoding); nByte = pIn1->n + pIn2->n; if( nByte>SQLITE_MAX_LENGTH ){ goto too_big; } zNew = sqlite3DbMallocRaw(db, nByte+2); if( zNew==0 ){ goto no_mem; } memcpy(zNew, pIn2->z, pIn2->n); memcpy(&zNew[pIn2->n], pIn1->z, pIn1->n); zNew[nByte] = 0; zNew[nByte+1] = 0; Release(pOut); pOut->n = nByte; pOut->flags = MEM_Str|MEM_Dyn|MEM_Term; pOut->xDel = 0; pOut->enc = encoding; pOut->z = zNew; break; } /* Opcode: Add * * * ** ** Pop the top two elements from the stack, add them together, ** and push the result back onto the stack. If either element |
︙ | ︙ | |||
1335 1336 1337 1338 1339 1340 1341 | ** first (what was on top of the stack) from the second (the ** next on stack) ** and push the remainder after division onto the stack. If either element ** is a string then it is converted to a double using the atof() ** function before the division. Division by zero returns NULL. ** If either operand is NULL, the result is NULL. */ | | | | | | < < | | < < | | | | | 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 | ** first (what was on top of the stack) from the second (the ** next on stack) ** and push the remainder after division onto the stack. If either element ** is a string then it is converted to a double using the atof() ** function before the division. Division by zero returns NULL. ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ int flags; flags = pIn1->flags | pIn2->flags; if( (flags & MEM_Null)!=0 ){ Release(pOut); pOut->flags = MEM_Null; }else if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ i64 a, b; a = pIn1->u.i; b = pIn2->u.i; switch( pOp->opcode ){ case OP_Add: b += a; break; case OP_Subtract: b -= a; break; case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0 ) goto divide_by_zero; /* Dividing the largest possible negative 64-bit integer (1<<63) by |
︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 | default: { if( a==0 ) goto divide_by_zero; if( a==-1 ) a = 1; b %= a; break; } } | | < < | | | | | 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 | default: { if( a==0 ) goto divide_by_zero; if( a==-1 ) a = 1; b %= a; break; } } Release(pOut); pOut->u.i = b; pOut->flags = MEM_Int; }else{ double a, b; a = sqlite3VdbeRealValue(pIn1); b = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: b += a; break; case OP_Subtract: b -= a; break; case OP_Multiply: b *= a; break; case OP_Divide: { if( a==0.0 ) goto divide_by_zero; b /= a; |
︙ | ︙ | |||
1407 1408 1409 1410 1411 1412 1413 | b = ib % ia; break; } } if( sqlite3_isnan(b) ){ goto divide_by_zero; } | | < < | | | | < < | | 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 | b = ib % ia; break; } } if( sqlite3_isnan(b) ){ goto divide_by_zero; } Release(pOut); pOut->r = b; pOut->flags = MEM_Real; if( (flags & MEM_Real)==0 ){ sqlite3VdbeIntegerAffinity(pOut); } } break; divide_by_zero: Release(pOut); pOut->flags = MEM_Null; break; } /* Opcode: CollSeq * * P4 ** ** P4 is a pointer to a CollSeq struct. If the next call to a user function ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will |
︙ | ︙ | |||
1565 1566 1567 1568 1569 1570 1571 | /* Opcode: ShiftRight * * * ** ** Pop the top two elements from the stack. Convert both elements ** to integers. Push back onto the stack the second element shifted ** right by N bits where N is the top element on the stack. ** If either operand is NULL, the result is NULL. */ | | | | | < < | < | | | | | < < | | | 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 | /* Opcode: ShiftRight * * * ** ** Pop the top two elements from the stack. Convert both elements ** to integers. Push back onto the stack the second element shifted ** right by N bits where N is the top element on the stack. ** If either operand is NULL, the result is NULL. */ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ i64 a, b; if( (pIn1->flags | pIn2->flags) & MEM_Null ){ Release(pOut); pOut->flags = MEM_Null; break; } a = sqlite3VdbeIntValue(pIn2); b = sqlite3VdbeIntValue(pIn1); switch( pOp->opcode ){ case OP_BitAnd: a &= b; break; case OP_BitOr: a |= b; break; case OP_ShiftLeft: a <<= b; break; case OP_ShiftRight: a >>= b; break; default: /* CANT HAPPEN */ break; } Release(pOut); pOut->u.i = a; pOut->flags = MEM_Int; break; } /* Opcode: AddImm P1 P2 * * * ** ** Add P2 the value in register P1. ** The result is always an integer. |
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 | ** If P3 is not zero, then act on the value in register P3 instead ** of using the stack. */ case OP_MustBeInt: { /* no-push, jump */ Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]); assert( pOp->p3 || pTos>=p->aStack ); assert( pOp->p3>=0 && pOp->p3<=p->nMem ); applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding); if( (pMem->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else if( pMem==pTos ){ if( pOp->p1 ) popStack(&pTos, 1); | > | 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 | ** If P3 is not zero, then act on the value in register P3 instead ** of using the stack. */ case OP_MustBeInt: { /* no-push, jump */ Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]); assert( pOp->p3 || pTos>=p->aStack ); assert( pOp->p3>=0 && pOp->p3<=p->nMem ); REGISTER_TRACE(pOp->p3, pMem); applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding); if( (pMem->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else if( pMem==pTos ){ if( pOp->p1 ) popStack(&pTos, 1); |
︙ | ︙ | |||
1939 1940 1941 1942 1943 1944 1945 | pTos++; pTos->flags = MEM_Int; pTos->u.i = res; } break; } | | | | | > > > | | < > | > > > | | < | < | | < | | < | | < | | | | | 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 | pTos++; pTos->flags = MEM_Int; pTos->u.i = res; } break; } /* Opcode: And P1 P2 P3 * * ** ** Take the logical AND of the values in registers P1 and P2 and ** write the result into register P3. ** ** If either P1 or P2 is 0 (false) then the result is 0 even if ** the other input is NULL. A NULL and true or two NULLs give ** a NULL output. */ /* Opcode: Or P1 P2 P3 * * ** ** Take the logical OR of the values in register P1 and P2 and ** store the answer in register P3. ** ** If either P1 or P2 is nonzero (true) then the result is 1 (true) ** even if the other input is NULL. A NULL and false or two NULLs ** give a NULL output. */ case OP_And: /* same as TK_AND, in1, in2, out3 */ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ int v1, v2; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ if( pIn1->flags & MEM_Null ){ v1 = 2; }else{ v1 = sqlite3VdbeIntValue(pIn1)!=0; } if( pIn2->flags & MEM_Null ){ v2 = 2; }else{ v2 = sqlite3VdbeIntValue(pIn2)!=0; } if( pOp->opcode==OP_And ){ static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; v1 = and_logic[v1*3+v2]; }else{ static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; v1 = or_logic[v1*3+v2]; } Release(pOut); if( v1==2 ){ pOut->flags = MEM_Null; }else{ pOut->u.i = v1; pOut->flags = MEM_Int; } break; } /* Opcode: Negative * * * ** ** Treat the top of the stack as a numeric quantity. Replace it |
︙ | ︙ | |||
2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 | } /* pDest->z might be pointing to sMem.zShort[]. Fix that so that we ** can abandon sMem */ rc = sqlite3VdbeMemMakeWriteable(pDest); op_column_out: break; } /* Opcode: MakeRecord P1 P2 P4 ** ** Convert the top abs(P1) entries of the stack into a single entry ** suitable for use as a data record in a database table or as a key | > | 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 | } /* pDest->z might be pointing to sMem.zShort[]. Fix that so that we ** can abandon sMem */ rc = sqlite3VdbeMemMakeWriteable(pDest); op_column_out: REGISTER_TRACE(pOp->p3, pDest); break; } /* Opcode: MakeRecord P1 P2 P4 ** ** Convert the top abs(P1) entries of the stack into a single entry ** suitable for use as a data record in a database table or as a key |
︙ | ︙ | |||
3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 | int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; Mem *pKey; if( pOp->p3 ){ assert( pOp->p3<=p->nMem ); pKey = &p->aMem[pOp->p3]; }else{ pKey = pTos; assert( pTos>=p->aStack ); } assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ | > | 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 | int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; Mem *pKey; if( pOp->p3 ){ assert( pOp->p3<=p->nMem ); pKey = &p->aMem[pOp->p3]; REGISTER_TRACE(pOp->p3, pKey); }else{ pKey = pTos; assert( pTos>=p->aStack ); } assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ |
︙ | ︙ | |||
3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 | } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ Mem *pMem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ pMem = &p->aMem[pOp->p3]; sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } if( v<pMem->u.i+1 ){ | > | 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 | } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ Mem *pMem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ pMem = &p->aMem[pOp->p3]; REGISTER_TRACE(pOp->p3, pMem); sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } if( v<pMem->u.i+1 ){ |
︙ | ︙ | |||
3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 | Mem *pData = &p->aMem[pOp->p2]; Mem *pKey = &p->aMem[pOp->p3]; int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){ i64 iKey; /* The integer ROWID or key for the record to be inserted */ assert( pKey->flags & MEM_Int ); assert( pC->isTable ); iKey = intToKey(pKey->u.i); | > > | 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 | Mem *pData = &p->aMem[pOp->p2]; Mem *pKey = &p->aMem[pOp->p3]; int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); REGISTER_TRACE(pOp->p2, pData); REGISTER_TRACE(pOp->p3, pKey); if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){ i64 iKey; /* The integer ROWID or key for the record to be inserted */ assert( pKey->flags & MEM_Int ); assert( pC->isTable ); iKey = intToKey(pKey->u.i); |
︙ | ︙ | |||
3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 | assert( pC->nData<=SQLITE_MAX_LENGTH ); pOut->z = pC->pData; pOut->flags = MEM_Blob|MEM_Ephem; }else{ pOut->flags = MEM_Null; } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ break; } /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. If p2==0 then push the integer. | > | 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 | assert( pC->nData<=SQLITE_MAX_LENGTH ); pOut->z = pC->pData; pOut->flags = MEM_Blob|MEM_Ephem; }else{ pOut->flags = MEM_Null; } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ REGISTER_TRACE(pOp->p3, pOut); break; } /* Opcode: Rowid P1 P2 * * * ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. If p2==0 then push the integer. |
︙ | ︙ | |||
4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 | /* Opcode: FifoWrite P1 * * ** ** Write the integer from memory cell P1 into the Fifo. */ case OP_FifoWrite: { /* no-push */ Mem *pReg = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); sqlite3VdbeMemIntegerify(pReg); if( sqlite3VdbeFifoPush(&p->sFifo, pReg->u.i)==SQLITE_NOMEM ){ goto no_mem; } break; } | > | 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 | /* Opcode: FifoWrite P1 * * ** ** Write the integer from memory cell P1 into the Fifo. */ case OP_FifoWrite: { /* no-push */ Mem *pReg = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); REGISTER_TRACE(pOp->p1, pReg); sqlite3VdbeMemIntegerify(pReg); if( sqlite3VdbeFifoPush(&p->sFifo, pReg->u.i)==SQLITE_NOMEM ){ goto no_mem; } break; } |
︙ | ︙ | |||
4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 | CHECK_FOR_INTERRUPT; if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){ pc = pOp->p2 - 1; }else{ Mem *pOut = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); sqlite3VdbeMemSetInt64(pOut, v); } break; } #ifndef SQLITE_OMIT_TRIGGER /* Opcode: ContextPush * * * ** | > | 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 | CHECK_FOR_INTERRUPT; if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){ pc = pOp->p2 - 1; }else{ Mem *pOut = &p->aMem[pOp->p1]; assert( pOp->p1>0 && pOp->p1<=p->nMem ); sqlite3VdbeMemSetInt64(pOut, v); REGISTER_TRACE(pOp->p1, pOut); } break; } #ifndef SQLITE_OMIT_TRIGGER /* Opcode: ContextPush * * * ** |
︙ | ︙ | |||
5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 | int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery = &p->aMem[pOp->p3]; Mem *pArgc = &pQuery[1]; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; /* Grab the index number and argc parameters off the top of the stack. */ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); nArg = pArgc->u.i; iQuery = pQuery->u.i; | > > | 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 | int nArg; int iQuery; const sqlite3_module *pModule; Mem *pQuery = &p->aMem[pOp->p3]; Mem *pArgc = &pQuery[1]; Cursor *pCur = p->apCsr[pOp->p1]; REGISTER_TRACE(pOp->p3, pQuery); assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; /* Grab the index number and argc parameters off the top of the stack. */ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); nArg = pArgc->u.i; iQuery = pQuery->u.i; |
︙ | ︙ | |||
5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 | ** do this regardless of whether or not an error occured to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); if( pOp->p3>0 ){ assert( pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; }else{ pDest = ++pTos; pDest->flags = 0; } sqlite3VdbeMemMove(pDest, &sContext.s); if( sqlite3SafetyOn(db) ){ | > | 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 | ** do this regardless of whether or not an error occured to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); if( pOp->p3>0 ){ assert( pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; REGISTER_TRACE(pOp->p3, pDest); }else{ pDest = ++pTos; pDest->flags = 0; } sqlite3VdbeMemMove(pDest, &sContext.s); if( sqlite3SafetyOn(db) ){ |
︙ | ︙ | |||
5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 | ** This opcode invokes the corresponding xRename method. The value ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { /* no-push */ sqlite3_vtab *pVtab = pOp->p4.pVtab; Mem *pName = &p->aMem[pOp->p1]; assert( pVtab->pModule->xRename ); Stringify(pName, encoding); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; sqlite3VtabLock(pVtab); rc = pVtab->pModule->xRename(pVtab, pName->z); sqlite3VtabUnlock(db, pVtab); | > | 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 | ** This opcode invokes the corresponding xRename method. The value ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { /* no-push */ sqlite3_vtab *pVtab = pOp->p4.pVtab; Mem *pName = &p->aMem[pOp->p1]; assert( pVtab->pModule->xRename ); REGISTER_TRACE(pOp->p1, pName); Stringify(pName, encoding); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; sqlite3VtabLock(pVtab); rc = pVtab->pModule->xRename(pVtab, pName->z); sqlite3VtabUnlock(db, pVtab); |
︙ | ︙ | |||
5387 5388 5389 5390 5391 5392 5393 | sqlite3VdbeMemSanity(pTos); assert( !sqlite3VdbeMemTooBig(pTos) ); } assert( pc>=-1 && pc<p->nOp ); #ifdef SQLITE_DEBUG /* Code for tracing the vdbe stack. */ | | > > > > > > > > | | | < < < < < < < < < < < | < < < | > | 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 | sqlite3VdbeMemSanity(pTos); assert( !sqlite3VdbeMemTooBig(pTos) ); } assert( pc>=-1 && pc<p->nOp ); #ifdef SQLITE_DEBUG /* Code for tracing the vdbe stack. */ if( p->trace ){ if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc); if( (opProperty&(OPFLG_OUT2_PRERELEASE|OPFLG_OUT2))!=0 && pOp->p2>0 ){ registerTrace(p->trace, pOp->p2, pOut); } if( (opProperty&OPFLG_OUT3)!=0 && pOp->p3>0 ){ registerTrace(p->trace, pOp->p3, pOut); } if( pTos>=p->aStack ){ int i; fprintf(p->trace, "Stack:"); for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){ memTracePrint(p->trace, &pTos[i]); } fprintf(p->trace,"\n"); } } #endif /* SQLITE_DEBUG */ #endif /* NDEBUG */ } /* The end of the for(;;) loop the loops through opcodes */ /* If we reach this point, it means that execution is finished. */ |
︙ | ︙ |