/ Check-in [43463970]
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:Merge with trunk commit [3e646e3f4c].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal
Files: files | file ages | folders
SHA1: 43463970f5885fb116588695146f2a56cb22804a
User & Date: dan 2010-04-17 15:45:35
Context
2010-04-17
17:34
Do not sync any files in wal mode if "PRAGMA synchronous=off" is set. If files are synced, pass either SQLITE_SYNC_FULL or SQLITE_SYNC_NORMAL to the xSync() callback as configured by "PRAGMA fullfsync". check-in: 0ae91b00 user: dan tags: wal
15:45
Merge with trunk commit [3e646e3f4c]. check-in: 43463970 user: dan tags: wal
15:42
In synchronous=normal mode, do not sync the log after every transaction. In synchronous=full mode, sync the log and add any extra frames required to avoid blast-radius related problems after each transaction. check-in: 9bc9b684 user: dan tags: wal
12:53
Change sqlite3_step() so that it automatically calls sqlite3_reset() instead of returning SQLITE_MISUSE when invoked on a prepared statement that previously returned any value other than SQLITE_ROW. check-in: 3e646e3f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
....
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
**        a separate restriction deriving from ticket #350.
**
**  (13)  The subquery and outer query do not both use LIMIT
**
**  (14)  The subquery does not use OFFSET
**
**  (15)  The outer query is not part of a compound select or the
**        subquery does not have both an ORDER BY and a LIMIT clause.
**        (See ticket #2339)
**
**  (16)  The outer query is not an aggregate or the subquery does
**        not contain ORDER BY.  (Ticket #2942)  This used to not matter
**        until we introduced the group_concat() function.  
**
**  (17)  The sub-query is not a compound select, or it is a UNION ALL 
**        compound clause made up entirely of non-aggregate queries, and 
................................................................................
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  ** became arbitrary expressions, we were forced to add restrictions (13)
  ** and (14). */
  if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
  if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
    return 0;                                            /* Restriction (15) */
  }
  if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
  if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit) 
         && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
     return 0;       
  }







|
|







 







|







2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
....
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
**        a separate restriction deriving from ticket #350.
**
**  (13)  The subquery and outer query do not both use LIMIT
**
**  (14)  The subquery does not use OFFSET
**
**  (15)  The outer query is not part of a compound select or the
**        subquery does not have a LIMIT clause.
**        (See ticket #2339 and ticket [02a8e81d44]).
**
**  (16)  The outer query is not an aggregate or the subquery does
**        not contain ORDER BY.  (Ticket #2942)  This used to not matter
**        until we introduced the group_concat() function.  
**
**  (17)  The sub-query is not a compound select, or it is a UNION ALL 
**        compound clause made up entirely of non-aggregate queries, and 
................................................................................
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  ** became arbitrary expressions, we were forced to add restrictions (13)
  ** and (14). */
  if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
  if( p->pRightmost && pSub->pLimit ){
    return 0;                                            /* Restriction (15) */
  }
  if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
  if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit) 
         && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
     return 0;       
  }

Changes to src/sqlite.h.in.

2881
2882
2883
2884
2885
2886
2887








2888
2889
2890
2891
2892
2893
2894
** [SQLITE_MISUSE] means that the this routine was called inappropriately.
** Perhaps it was called on a [prepared statement] that has
** already been [sqlite3_finalize | finalized] or on one that had
** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
** be the case that the same database connection is being used by two or
** more threads at the same moment in time.
**








** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
** API always returns a generic error code, [SQLITE_ERROR], following any
** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
** specific [error codes] that better describes the error.
** We admit that this is a goofy design.  The problem has been fixed
** with the "v2" interface.  If you prepare all of your SQL statements







>
>
>
>
>
>
>
>







2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
** [SQLITE_MISUSE] means that the this routine was called inappropriately.
** Perhaps it was called on a [prepared statement] that has
** already been [sqlite3_finalize | finalized] or on one that had
** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
** be the case that the same database connection is being used by two or
** more threads at the same moment in time.
**
** For all versions of SQLite up to and including 3.6.23.1, it was required
** after sqlite3_step() returned anything other than [SQLITE_ROW] that
** [sqlite3_reset()] be called before any subsequent invocation of
** sqlite3_step().  Failure to invoke [sqlite3_reset()] in this way would
** result in an [SQLITE_MISUSE] return from sqlite3_step().  But after
** version 3.6.23.1, sqlite3_step() began calling [sqlite3_reset()] 
** automatically in this circumstance rather than returning [SQLITE_MISUSE].  
**
** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
** API always returns a generic error code, [SQLITE_ERROR], following any
** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
** specific [error codes] that better describes the error.
** We admit that this is a goofy design.  The problem has been fixed
** with the "v2" interface.  If you prepare all of your SQL statements

Changes to src/vdbeapi.c.

317
318
319
320
321
322
323
324
325
326



327
328
329
330
331
332
333
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    sqlite3_log(SQLITE_MISUSE, 
          "attempt to step a halted statement: [%s]", p->zSql);
    return SQLITE_MISUSE_BKPT;



  }

  /* Check that malloc() has not failed. If it has, return early. */
  db = p->db;
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM;
    return SQLITE_NOMEM;







|
|
|
>
>
>







317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
*/
static int sqlite3Step(Vdbe *p){
  sqlite3 *db;
  int rc;

  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    /* We used to require that sqlite3_reset() be called before retrying
    ** sqlite3_step() after any error.  But after 3.6.23, we changed this
    ** so that sqlite3_reset() would be called automatically instead of
    ** throwing the error.
    */
    sqlite3_reset((sqlite3_stmt*)p);
  }

  /* Check that malloc() has not failed. If it has, return early. */
  db = p->db;
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM;
    return SQLITE_NOMEM;

Changes to test/capi2.test.

67
68
69
70
71
72
73



74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
} {name rowid text INTEGER}
do_test capi2-1.6 {
  sqlite3_step $VM 
} {SQLITE_DONE}
do_test capi2-1.7 {
  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}



do_test capi2-1.8-misuse {
  sqlite3_step $VM
} {SQLITE_MISUSE}

# Update: In v2, once SQLITE_MISUSE is returned the statement handle cannot
# be interrogated for more information. However in v3, since the column
# count, names and types are determined at compile time, these are still
# accessible after an SQLITE_MISUSE error.
do_test capi2-1.9 {

  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}
do_test capi2-1.10 {
  sqlite3_data_count $VM
} {0}

do_test capi2-1.11 {







>
>
>
|

|






>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
} {name rowid text INTEGER}
do_test capi2-1.6 {
  sqlite3_step $VM 
} {SQLITE_DONE}
do_test capi2-1.7 {
  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}

# This used to be SQLITE_MISUSE.  But now we automatically reset prepared
# statements.
do_test capi2-1.8 {
  sqlite3_step $VM
} {SQLITE_ROW}

# Update: In v2, once SQLITE_MISUSE is returned the statement handle cannot
# be interrogated for more information. However in v3, since the column
# count, names and types are determined at compile time, these are still
# accessible after an SQLITE_MISUSE error.
do_test capi2-1.9 {
  sqlite3_reset $VM
  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}
do_test capi2-1.10 {
  sqlite3_data_count $VM
} {0}

do_test capi2-1.11 {

Changes to test/fkey2.test.

1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
} {1}
do_test fkey2-17.1.2 {
  set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
  sqlite3_step $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.3 {
  sqlite3_step $STMT
} {SQLITE_MISUSE}
do_test fkey2-17.1.4 {
  sqlite3_finalize $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.5 {
  execsql {
    INSERT INTO one VALUES(2, 3, 4);
    INSERT INTO one VALUES(3, 4, 5);







|







1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
} {1}
do_test fkey2-17.1.2 {
  set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
  sqlite3_step $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.3 {
  sqlite3_step $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.4 {
  sqlite3_finalize $STMT
} {SQLITE_CONSTRAINT}
do_test fkey2-17.1.5 {
  execsql {
    INSERT INTO one VALUES(2, 3, 4);
    INSERT INTO one VALUES(3, 4, 5);

Added test/tkt-02a8e81d44.test.































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 2010 April 15
#
# 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 implements regression tests for SQLite library.
#
# This file implements tests to verify that ticket [02a8e81d44] has been
# fixed.  
#

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

do_test tkt-02a838-1.1 {
  execsql {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1);
    INSERT INTO t1 VALUES(2);
    INSERT INTO t1 VALUES(4);
    INSERT INTO t1 VALUES(5);
    SELECT * FROM (SELECT a FROM t1 LIMIT 1) UNION ALL SELECT 3;
  }
} {1 3}

finish_test