/ Check-in [f856676c]
Login

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

Overview
Comment:Small changes to the OP_OpenEphemeral opcode to improve testability.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f856676c8438dbf52d299e78f6dd6148d929755dc05cdcabafd17d9a86439435
User & Date: drh 2018-12-31 17:58:05
Context
2018-12-31
20:39
Additional steps to help ensure that scalar subqueries are only evaluated once even if they are used in multiple places within the query. This fixes a performance regression reported on the mailing list and caused by check-in [531eca6104e41e43] which was a fix for ticket [787fa716be3a7f650c]. Think of this check-in as an improved fix for that ticket. check-in: e1303193 user: drh tags: trunk
18:30
Merge enhancements and bug fixes from trunk. check-in: 9fb646f2 user: drh tags: reuse-subqueries
17:58
Small changes to the OP_OpenEphemeral opcode to improve testability. check-in: f856676c user: drh tags: trunk
16:36
Fix the OP_OpenEphemeral opcode in the bytecode engine so that if it is called a second or subsequent time, it merely clears the existing table rather than creating a new one. Proposed fix for ticket [d0866b26f83e9c55e30de0821f5d]. check-in: 4678cb10 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

  3663   3663     assert( pOp->p1>=0 );
  3664   3664     assert( pOp->p2>=0 );
  3665   3665     pCx = p->apCsr[pOp->p1];
  3666   3666     if( pCx ){
  3667   3667       /* If the ephermeral table is already open, erase all existing content
  3668   3668       ** so that the table is empty again, rather than creating a new table. */
  3669   3669       rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
  3670         -    if( rc ) goto abort_due_to_error;
  3671         -    break;
  3672         -  }
  3673         -  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
  3674         -  if( pCx==0 ) goto no_mem;
  3675         -  pCx->nullRow = 1;
  3676         -  pCx->isEphemeral = 1;
  3677         -  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
  3678         -                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
  3679         -  if( rc==SQLITE_OK ){
  3680         -    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
  3681         -  }
  3682         -  if( rc==SQLITE_OK ){
  3683         -    /* If a transient index is required, create it by calling
  3684         -    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
  3685         -    ** opening it. If a transient table is required, just use the
  3686         -    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
  3687         -    */
  3688         -    if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
  3689         -      assert( pOp->p4type==P4_KEYINFO );
  3690         -      rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
  3691         -                                   BTREE_BLOBKEY | pOp->p5); 
  3692         -      if( rc==SQLITE_OK ){
  3693         -        assert( pCx->pgnoRoot==MASTER_ROOT+1 );
  3694         -        assert( pKeyInfo->db==db );
  3695         -        assert( pKeyInfo->enc==ENC(db) );
  3696         -        rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
  3697         -                                pKeyInfo, pCx->uc.pCursor);
  3698         -      }
  3699         -      pCx->isTable = 0;
  3700         -    }else{
  3701         -      pCx->pgnoRoot = MASTER_ROOT;
  3702         -      rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
  3703         -                              0, pCx->uc.pCursor);
  3704         -      pCx->isTable = 1;
  3705         -    }
  3706         -  }
  3707         -  if( rc ) goto abort_due_to_error;
  3708         -  pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
         3670  +  }else{
         3671  +    pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
         3672  +    if( pCx==0 ) goto no_mem;
         3673  +    pCx->nullRow = 1;
         3674  +    pCx->isEphemeral = 1;
         3675  +    rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
         3676  +                          BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
         3677  +                          vfsFlags);
         3678  +    if( rc==SQLITE_OK ){
         3679  +      rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
         3680  +    }
         3681  +    if( rc==SQLITE_OK ){
         3682  +      /* If a transient index is required, create it by calling
         3683  +      ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
         3684  +      ** opening it. If a transient table is required, just use the
         3685  +      ** automatically created table with root-page 1 (an BLOB_INTKEY table).
         3686  +      */
         3687  +      if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
         3688  +        assert( pOp->p4type==P4_KEYINFO );
         3689  +        rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
         3690  +                                     BTREE_BLOBKEY | pOp->p5); 
         3691  +        if( rc==SQLITE_OK ){
         3692  +          assert( pCx->pgnoRoot==MASTER_ROOT+1 );
         3693  +          assert( pKeyInfo->db==db );
         3694  +          assert( pKeyInfo->enc==ENC(db) );
         3695  +          rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
         3696  +                                  pKeyInfo, pCx->uc.pCursor);
         3697  +        }
         3698  +        pCx->isTable = 0;
         3699  +      }else{
         3700  +        pCx->pgnoRoot = MASTER_ROOT;
         3701  +        rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
         3702  +                                0, pCx->uc.pCursor);
         3703  +        pCx->isTable = 1;
         3704  +      }
         3705  +    }
         3706  +    pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
         3707  +  }
         3708  +  if( rc ) goto abort_due_to_error;
  3709   3709     break;
  3710   3710   }
  3711   3711   
  3712   3712   /* Opcode: SorterOpen P1 P2 P3 P4 *
  3713   3713   **
  3714   3714   ** This opcode works like OP_OpenEphemeral except that it opens
  3715   3715   ** a transient index that is specifically designed to sort large