/ Check-in [25dd3422]
Login

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

Overview
Comment:Make sure the IN operator works with zeroblobs. Ticket #3965. Other simplifications associated with structural testing. (CVS 6890)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:25dd342283046aaf66a679348ef1c7364c616402
User & Date: drh 2009-07-14 02:33:02
Context
2009-07-14
14:15
Simplifications and tweaks to vdbeaux.c resulting from structural testing. (CVS 6891) check-in: fa49666f user: drh tags: trunk
02:33
Make sure the IN operator works with zeroblobs. Ticket #3965. Other simplifications associated with structural testing. (CVS 6890) check-in: 25dd3422 user: drh tags: trunk
2009-07-13
15:52
Remove the SQLITE_CommitBusy flag. This was an attempt to block recursion on the sqlite3_commit_hook() interface. But such recursion is explicitly disallowed, so the flag is pointless. (CVS 6889) check-in: 1c2bfc43 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3345
3346
3347
3348
3349
3350
3351

3352
3353
3354
3355
3356
3357
3358
....
3947
3948
3949
3950
3951
3952
3953

3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
**
** 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.870 2009/07/07 15:47:12 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( ALWAYS(pC->pCursor!=0) ){

    assert( pC->isTable==0 );
    assert( pIn3->flags & MEM_Blob );

    pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
                                      aTempRec, sizeof(aTempRec));
    if( pIdxKey==0 ){
      goto no_mem;
    }
    if( pOp->opcode==OP_Found ){
      pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
................................................................................
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{

    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->rowidIsValid ){
      v = pC->lastRowid;
    }else{
      assert( pC->pCursor!=0 );
      sqlite3BtreeKeySize(pC->pCursor, &v);
    }
  }
  pOut->u.i = v;
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}







|







 







>







 







>





<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
....
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960

3961
3962
3963
3964
3965
3966
3967
**
** 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.871 2009/07/14 02:33:02 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( ALWAYS(pC->pCursor!=0) ){

    assert( pC->isTable==0 );
    assert( pIn3->flags & MEM_Blob );
    ExpandBlob(pIn3);
    pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
                                      aTempRec, sizeof(aTempRec));
    if( pIdxKey==0 ){
      goto no_mem;
    }
    if( pOp->opcode==OP_Found ){
      pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
................................................................................
    rc = pModule->xRowid(pC->pVtabCursor, &v);
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = pVtab->zErrMsg;
    pVtab->zErrMsg = 0;
    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->rowidIsValid ){
      v = pC->lastRowid;
    }else{

      sqlite3BtreeKeySize(pC->pCursor, &v);
    }
  }
  pOut->u.i = v;
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

Changes to src/vdbeaux.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
....
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
....
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2449
2450
2451
2452
2453
2454
2455
2456




2457
2458
2459
2460
2461
2462
2463
2464
2465
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.471 2009/07/13 15:52:38 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"



/*
................................................................................
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
** Otherwise SQLITE_OK.
*/
int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
  sqlite3 *const db = p->db;
  int rc = SQLITE_OK;

  /* If p->iStatement is greater than zero, then this Vdbe opened a 
  ** statement transaction that should be closed here. The only exception
  ** is that an IO error may have occured, causing an emergency rollback.
  ** In this case (db->nStatement==0), and there is nothing to do.
  */
  if( db->nStatement && p->iStatement ){
    int i;
    const int iSavepoint = p->iStatement-1;

    assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
    assert( db->nStatement>0 );
    assert( p->iStatement==(db->nStatement+db->nSavepoint) );

................................................................................
        p->zErrMsg = 0;
      }
    }
  
    /* If this was an INSERT, UPDATE or DELETE and no statement transaction
    ** has been rolled back, update the database connection change-counter. 
    */
    if( p->changeCntOn && p->pc>=0 ){
      if( eStatementOp!=SAVEPOINT_ROLLBACK ){
        sqlite3VdbeSetChanges(db, p->nChange);
      }else{
        sqlite3VdbeSetChanges(db, 0);
      }
      p->nChange = 0;
    }
................................................................................
      if( rc ) return rc;
    }
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
    p->deferredMoveto = 0;
    p->cacheStatus = CACHE_STALE;
  }else if( p->pCursor ){
    int hasMoved;
    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
    if( rc ) return rc;
    if( hasMoved ){
      p->cacheStatus = CACHE_STALE;
      p->nullRow = 1;
    }
................................................................................
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
  int i;
  Mem *pMem;

  assert( p!=0 );
  assert( p->flags & UNPACKED_NEED_DESTROY );
  for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
    if( pMem->zMalloc ){




      sqlite3VdbeMemRelease(pMem);
    }
  }
  if( p->flags & UNPACKED_NEED_FREE ){
    sqlite3DbFree(p->pKeyInfo->db, p);
  }
}

/*







|







 







<
<
<
<
<
|







 







|







 







|







 







|
>
>
>
>
|
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1610
1611
1612
1613
1614
1615
1616





1617
1618
1619
1620
1621
1622
1623
1624
....
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
....
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
....
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456

2457
2458
2459
2460
2461
2462
2463
**
*************************************************************************
** This file contains code used for creating, destroying, and populating
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
** $Id: vdbeaux.c,v 1.472 2009/07/14 02:33:02 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"



/*
................................................................................
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
** Otherwise SQLITE_OK.
*/
int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
  sqlite3 *const db = p->db;
  int rc = SQLITE_OK;






  if( p->iStatement ){
    int i;
    const int iSavepoint = p->iStatement-1;

    assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
    assert( db->nStatement>0 );
    assert( p->iStatement==(db->nStatement+db->nSavepoint) );

................................................................................
        p->zErrMsg = 0;
      }
    }
  
    /* If this was an INSERT, UPDATE or DELETE and no statement transaction
    ** has been rolled back, update the database connection change-counter. 
    */
    if( p->changeCntOn ){
      if( eStatementOp!=SAVEPOINT_ROLLBACK ){
        sqlite3VdbeSetChanges(db, p->nChange);
      }else{
        sqlite3VdbeSetChanges(db, 0);
      }
      p->nChange = 0;
    }
................................................................................
      if( rc ) return rc;
    }
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
    p->deferredMoveto = 0;
    p->cacheStatus = CACHE_STALE;
  }else if( ALWAYS(p->pCursor) ){
    int hasMoved;
    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
    if( rc ) return rc;
    if( hasMoved ){
      p->cacheStatus = CACHE_STALE;
      p->nullRow = 1;
    }
................................................................................
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
  int i;
  Mem *pMem;

  assert( p!=0 );
  assert( p->flags & UNPACKED_NEED_DESTROY );
  for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
    /* The unpacked record is always constructed by the
    ** sqlite3VdbeUnpackRecord() function above, which makes all
    ** strings and blobs static.  And none of the elements are
    ** ever transformed, so there is never anything to delete.
    */
    if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem);

  }
  if( p->flags & UNPACKED_NEED_FREE ){
    sqlite3DbFree(p->pKeyInfo->db, p);
  }
}

/*

Changes to test/zeroblob.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
222
223
224
225
226
227
228
229





























230
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.13 2008/06/13 18:24:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !incrblob {
  finish_test
  return
................................................................................
#
do_test zeroblob-8.1 {
  llength [execsql {
    SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b;
  }]
} {8}































finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing of the zero-filled blob functionality
# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
# and the built-in zeroblob() SQL function.
#
# $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !incrblob {
  finish_test
  return
................................................................................
#
do_test zeroblob-8.1 {
  llength [execsql {
    SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b;
  }]
} {8}


# Ticket #3965
# zeroblobs on either size of an IN operator
#
do_test zeroblob-9.1 {
  db eval {SELECT x'0000' IN (x'000000')}
} {0}
do_test zeroblob-9.2 {
  db eval {SELECT x'0000' IN (x'0000')}
} {1}
do_test zeroblob-9.3 {
  db eval {SELECT zeroblob(2) IN (x'000000')}
} {0}
do_test zeroblob-9.4 {
  db eval {SELECT zeroblob(2) IN (x'0000')}
} {1}
do_test zeroblob-9.5 {
  db eval {SELECT x'0000' IN (zeroblob(3))}
} {0}
do_test zeroblob-9.6 {
  db eval {SELECT x'0000' IN (zeroblob(2))}
} {1}
do_test zeroblob-9.7 {
  db eval {SELECT zeroblob(2) IN (zeroblob(3))}
} {0}
do_test zeroblob-9.8 {
  db eval {SELECT zeroblob(2) IN (zeroblob(2))}
} {1}


finish_test