/ Check-in [6a9fb47d]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Take out the OP_JumpOnce opcode. Revert compound SELECT to use OP_IfNot, which is the correct behavior. Mark trigger registers as initially invalid.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | uninit-vdbe-mem
Files: files | file ages | folders
SHA1: 6a9fb47d5060fe641915f5f99cc9265409a4583b
User & Date: drh 2011-12-09 17:27:51
Context
2011-12-09
17:38
Remove an unnecessary initialization of Vdbe.aOnceFlag. check-in: 421714da user: drh tags: uninit-vdbe-mem
17:27
Take out the OP_JumpOnce opcode. Revert compound SELECT to use OP_IfNot, which is the correct behavior. Mark trigger registers as initially invalid. check-in: 6a9fb47d user: drh tags: uninit-vdbe-mem
16:59
Previous check-in broke auto-increment. This check-in appears to fix it. check-in: 28ffd39c user: drh tags: uninit-vdbe-mem
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

  1943   1943     addr = sqlite3VdbeCurrentAddr(v);
  1944   1944     iContinue = sqlite3VdbeMakeLabel(v);
  1945   1945   
  1946   1946     /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  1947   1947     */
  1948   1948     if( regPrev ){
  1949   1949       int j1, j2;
  1950         -    j1 = sqlite3VdbeAddOp1(v, OP_JumpOnce, pParse->nOnce++);
         1950  +    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
  1951   1951       j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
  1952   1952                                 (char*)pKeyInfo, p4type);
  1953   1953       sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
  1954   1954       sqlite3VdbeJumpHere(v, j1);
  1955   1955       sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
         1956  +    sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  1956   1957     }
  1957   1958     if( pParse->db->mallocFailed ) return 0;
  1958   1959   
  1959   1960     /* Suppress the the first OFFSET entries if there is an OFFSET clause
  1960   1961     */
  1961   1962     codeOffset(v, p, iContinue);
  1962   1963   

Changes to src/vdbe.c.

  2048   2048       pc = pOp->p2-1;
  2049   2049     }else{
  2050   2050       p->aOnceFlag[pOp->p1] = 1;
  2051   2051     }
  2052   2052     break;
  2053   2053   }
  2054   2054   
  2055         -/* Opcode: JumpOnce P1 P2 * * *
  2056         -**
  2057         -** Check if OP_Once flag P1 is clear. If so, set the flag and
  2058         -** jump to instruction P2. Otherwise fall through.
  2059         -**
  2060         -** See also: Once
  2061         -*/
  2062         -case OP_JumpOnce: {         /* jump */
  2063         -  assert( pOp->p1<p->nOnceFlag );
  2064         -  if( !p->aOnceFlag[pOp->p1] ){
  2065         -    pc = pOp->p2-1;
  2066         -    p->aOnceFlag[pOp->p1] = 1;
  2067         -  }
  2068         -  break;
  2069         -}
  2070         -
  2071   2055   /* Opcode: If P1 P2 P3 * *
  2072   2056   **
  2073   2057   ** Jump to P2 if the value in register P1 is true.  The value
  2074   2058   ** is considered true if it is numeric and non-zero.  If the value
  2075   2059   ** in P1 is NULL then take the jump if P3 is non-zero.
  2076   2060   */
  2077   2061   /* Opcode: IfNot P1 P2 P3 * *
................................................................................
  5097   5081     Mem *pEnd;              /* Last memory cell in new array */
  5098   5082     VdbeFrame *pFrame;      /* New vdbe frame to execute in */
  5099   5083     SubProgram *pProgram;   /* Sub-program to execute */
  5100   5084     void *t;                /* Token identifying trigger */
  5101   5085   
  5102   5086     pProgram = pOp->p4.pProgram;
  5103   5087     pRt = &aMem[pOp->p3];
  5104         -  /*assert( memIsValid(pRt) );*/
  5105   5088     assert( pProgram->nOp>0 );
  5106   5089     
  5107   5090     /* If the p5 flag is clear, then recursive invocation of triggers is 
  5108   5091     ** disabled for backwards compatibility (p5 is set if this sub-program
  5109   5092     ** is really a trigger, not a foreign key action, and the flag set
  5110   5093     ** and cleared by the "PRAGMA recursive_triggers" command is clear).
  5111   5094     ** 
................................................................................
  5162   5145       pFrame->nOp = p->nOp;
  5163   5146       pFrame->token = pProgram->token;
  5164   5147       pFrame->aOnceFlag = p->aOnceFlag;
  5165   5148       pFrame->nOnceFlag = p->nOnceFlag;
  5166   5149   
  5167   5150       pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
  5168   5151       for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
  5169         -      pMem->flags = MEM_Null;
         5152  +      pMem->flags = MEM_Invalid;
  5170   5153         pMem->db = db;
  5171   5154       }
  5172   5155     }else{
  5173   5156       pFrame = pRt->u.pFrame;
  5174   5157       assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
  5175   5158       assert( pProgram->nCsr==pFrame->nChildCsr );
  5176   5159       assert( pc==pFrame->pc );
................................................................................
  5274   5257     VdbeFrame *pFrame;
  5275   5258     if( p->pFrame ){
  5276   5259       for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
  5277   5260       pIn1 = &pFrame->aMem[pOp->p1];
  5278   5261     }else{
  5279   5262       pIn1 = &aMem[pOp->p1];
  5280   5263     }
  5281         -  /*assert( memIsValid(pIn1) );  FIXME */
         5264  +  assert( memIsValid(pIn1) );
  5282   5265     sqlite3VdbeMemIntegerify(pIn1);
  5283   5266     pIn2 = &aMem[pOp->p2];
  5284   5267     sqlite3VdbeMemIntegerify(pIn2);
  5285   5268     if( pIn1->u.i<pIn2->u.i){
  5286   5269       pIn1->u.i = pIn2->u.i;
  5287   5270     }
  5288   5271     break;