Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -1033,11 +1033,11 @@ UPDATE_MAX_BLOBSIZE(pOut); break; } /* Opcode: Move P1 P2 P3 * * -** Synopsis: r[P2]=r[P1] N=P3 +** Synopsis: r[P2@P3]=r[P1@P3] ** ** Move the values in register P1..P1+P3 over into ** registers P2..P2+P3. Registers P1..P1+P3 are ** left holding a NULL. It is an error for register ranges ** P1..P1+P3 and P2..P2+P3 to overlap. @@ -1076,11 +1076,11 @@ } break; } /* Opcode: Copy P1 P2 P3 * * -** Synopsis: r[P2]=r[P1] N=P3 +** Synopsis: r[P2@P3]=r[P1@P3] ** ** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. ** ** This instruction makes a deep copy of the value. A duplicate ** is made of any string or blob constant. See also OP_SCopy. @@ -1398,11 +1398,11 @@ } break; } /* Opcode: Function P1 P2 P3 P4 P5 -** Synopsis: r[P3]=func(r[P2]..) N=P5 +** Synopsis: r[P3]=func(r[P2@P5]) ** ** Invoke a user function (P4 is a pointer to a Function structure that ** defines the function) with P5 arguments taken from register P2 and ** successors. The result of the function is stored in register P3. ** Register P3 must not be one of the function inputs. @@ -2511,11 +2511,11 @@ REGISTER_TRACE(pOp->p3, pDest); break; } /* Opcode: Affinity P1 P2 * P4 * -** Synopsis: affinity(r[P1]) N=P2 +** Synopsis: affinity(r[P1@P2]) ** ** Apply affinities to a range of P2 registers starting with P1. ** ** P4 is a string that is P2 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth @@ -2538,11 +2538,11 @@ } break; } /* Opcode: MakeRecord P1 P2 P3 P4 * -** Synopsis: r[P3]=rec(r[P1]..) N=P2 +** Synopsis: r[P3]=mkrec(r[P1@P2]) ** ** Convert P2 registers beginning with P1 into the [record format] ** use as a data record in a database table or as a key ** in an index. The OP_Column opcode can decode the record later. ** @@ -3377,11 +3377,11 @@ rc = sqlite3VdbeSorterInit(db, pCx); break; } /* Opcode: OpenPseudo P1 P2 P3 * P5 -** Synopsis: content in r[P2].. N=P3 +** Synopsis: content in r[P2@P3] ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row in the content of memory ** register P2 when P5==0. In other words, cursor P1 becomes an alias for the ** MEM_Blob content contained in register P2. When P5==1, then the @@ -3420,11 +3420,11 @@ p->apCsr[pOp->p1] = 0; break; } /* Opcode: SeekGe P1 P2 P3 P4 * -** Synopsis: key=r[P3].. N=P4 +** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), ** use the value in register P3 as the key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. @@ -3434,11 +3434,11 @@ ** greater than or equal to the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe */ /* Opcode: SeekGt P1 P2 P3 P4 * -** Synopsis: key=r[P3].. N=P4 +** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), ** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. @@ -3448,11 +3448,11 @@ ** the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe */ /* Opcode: SeekLt P1 P2 P3 P4 * -** Synopsis: key=r[P3].. N=P4 +** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), ** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. @@ -3462,11 +3462,11 @@ ** the key and P2 is not zero, then jump to P2. ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe */ /* Opcode: SeekLe P1 P2 P3 P4 * -** Synopsis: key=r[P3].. N=P4 +** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), ** use the value in register P3 as a key. If cursor P1 refers ** to an SQL index, then P3 is the first in an array of P4 registers ** that are used as an unpacked index key. @@ -3656,11 +3656,11 @@ break; } /* Opcode: Found P1 P2 P3 P4 * -** Synopsis: key=r[P3].. N=P4 +** Synopsis: key=r[P3@P4] ** ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked ** record. ** @@ -3667,11 +3667,11 @@ ** Cursor P1 is on an index btree. If the record identified by P3 and P4 ** is a prefix of any entry in P1 then a jump is made to P2 and ** P1 is left pointing at the matching entry. */ /* Opcode: NotFound P1 P2 P3 P4 * -** Synopsis: key=r[P3] N=P4 +** Synopsis: key=r[P3@P4] ** ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked ** record. ** @@ -4637,11 +4637,11 @@ } break; } /* Opcode: IdxDelete P1 P2 P3 * * -** Synopsis: key=r[P2].. +** Synopsis: key=r[P2@P3] ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ @@ -4710,11 +4710,11 @@ } break; } /* Opcode: IdxGE P1 P2 P3 P4 P5 -** Synopsis: key=r[P3] N=P4 +** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index ** key that omits the ROWID. Compare this key value against the index ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** @@ -4725,11 +4725,11 @@ ** prior to the comparison. This make the opcode work like IdxGT except ** that if the key from register P3 is a prefix of the key in the cursor, ** the result is false whereas it would be true with IdxGT. */ /* Opcode: IdxLT P1 P2 P3 P4 P5 -** Synopsis: key=r[P3] N=P4 +** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index ** key that omits the ROWID. Compare this key value against the index ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. ** @@ -5468,11 +5468,11 @@ } break; } /* Opcode: AggStep * P2 P3 P4 P5 -** Synopsis: accum=r[P3] step(r[P2]..) N=P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) ** ** Execute the step function for an aggregate. The ** function has P5 arguments. P4 is a pointer to the FuncDef ** structure that specifies the function. Use register ** P3 as the accumulator. @@ -6086,11 +6086,11 @@ } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VUpdate P1 P2 P3 P4 * -** Synopsis: data=r[P3] N=P2 +** Synopsis: data=r[P3@P2] ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xUpdate method. P2 values ** are contiguous memory cells starting at P3 to pass to the xUpdate ** invocation. The value in register (P3+P2-1) corresponds to the Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -853,44 +853,65 @@ return &p->aOp[addr]; } } #if defined(SQLITE_DEBUG) +/* +** Return an integer value for one of the parameters to the opcode pOp +** determined by character c. +*/ +static int translateP(char c, const Op *pOp){ + if( c=='1' ) return pOp->p1; + if( c=='2' ) return pOp->p2; + if( c=='3' ) return pOp->p3; + if( c=='4' ) return pOp->p4.i; + return pOp->p5; +} + /* ** Compute a string for the "comment" field of a VDBE opcode listing */ -static int displayComment(Op *pOp, const char *zP4, char *zTemp, int nTemp){ +static int displayComment( + const Op *pOp, /* The opcode to be commented */ + const char *zP4, /* Previously obtained value for P4 */ + char *zTemp, /* Write result here */ + int nTemp /* Space available in zTemp[] */ +){ const char *zOpName; const char *zSynopsis; int nOpName; int ii, jj; zOpName = sqlite3OpcodeName(pOp->opcode); nOpName = sqlite3Strlen30(zOpName); if( zOpName[nOpName+1] ){ int seenCom = 0; + char c; zSynopsis = zOpName += nOpName + 1; - for(ii=jj=0; jjp1; break; - case '2': v = pOp->p2; break; - case '3': v = pOp->p3; break; - case '5': v = pOp->p5; break; - case '4': zShow = zP4; break; - case 'X': zShow = pOp->zComment; seenCom = 1; break; - } - if( zShow ){ - sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zShow); + for(ii=jj=0; jjzComment); + seenCom = 1; }else{ - sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v); + int v1 = translateP(c, pOp); + int v2; + sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1); + if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ + ii += 3; + jj += sqlite3Strlen30(zTemp+jj); + v2 = translateP(zSynopsis[ii], pOp); + if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); + }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ + ii += 4; + } } jj += sqlite3Strlen30(zTemp+jj); }else{ - zTemp[jj++] = zSynopsis[ii]; + zTemp[jj++] = c; } } if( !seenCom && jjzComment ){ sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment); jj += sqlite3Strlen30(zTemp+jj);