/ Check-in [053ce76d]
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:Add the SQLITE_OMIT_AUTORESET compile-time option which if enabled causes the sqlite3_step() routine to return SQLITE_MISUSE if it is called after it has previously returned anything other than SQLITE_ROW, SQLITE_BUSY, or SQLITE_LOCKED.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 053ce76deb356d31358454507ba94947142e20ca
User & Date: drh 2011-01-17 17:42:37
Context
2011-01-17
18:30
Fix a typo in the documentation for sqlite3_stmt_readonly(). check-in: 56417a33 user: drh tags: trunk
17:42
Add the SQLITE_OMIT_AUTORESET compile-time option which if enabled causes the sqlite3_step() routine to return SQLITE_MISUSE if it is called after it has previously returned anything other than SQLITE_ROW, SQLITE_BUSY, or SQLITE_LOCKED. check-in: 053ce76d user: drh tags: trunk
02:24
Add back an ALWAYS() to regain full test coverage. check-in: b93f6f3e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

install-sh became executable.

Changes to src/ctime.c.

169
170
171
172
173
174
175



176
177
178
179
180
181
182
  "OMIT_AUTOINCREMENT",
#endif
#ifdef SQLITE_OMIT_AUTOINIT
  "OMIT_AUTOINIT",
#endif
#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
  "OMIT_AUTOMATIC_INDEX",



#endif
#ifdef SQLITE_OMIT_AUTOVACUUM
  "OMIT_AUTOVACUUM",
#endif
#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  "OMIT_BETWEEN_OPTIMIZATION",
#endif







>
>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  "OMIT_AUTOINCREMENT",
#endif
#ifdef SQLITE_OMIT_AUTOINIT
  "OMIT_AUTOINIT",
#endif
#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
  "OMIT_AUTOMATIC_INDEX",
#endif
#ifdef SQLITE_OMIT_AUTORESET
  "OMIT_AUTORESET",
#endif
#ifdef SQLITE_OMIT_AUTOVACUUM
  "OMIT_AUTOVACUUM",
#endif
#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  "OMIT_BETWEEN_OPTIMIZATION",
#endif

Changes to src/sqlite.h.in.

3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087




3088
3089
3090
3091
3092
3093
3094
** [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







|
|
|
|
|
|
|
>
>
>
>







3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
** [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, a call to
** [sqlite3_reset()] was required after sqlite3_step() returned anything
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step().  Failure to reset the prepared statement using 
** [sqlite3_reset()] 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].  This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
** is broken by definition.  The [SQLITE_OMIT_AUTORESET] compile-time option
** can be used to restore the legacy behavior.
**
** <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

Changes to src/test_config.c.

128
129
130
131
132
133
134






135
136
137
138
139
140
141
#endif

#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
  Tcl_SetVar2(interp, "sqlite_options", "autoindex", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "autoindex", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_AUTOVACUUM
  Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY);
#endif /* SQLITE_OMIT_AUTOVACUUM */
#if !defined(SQLITE_DEFAULT_AUTOVACUUM)







>
>
>
>
>
>







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#endif

#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
  Tcl_SetVar2(interp, "sqlite_options", "autoindex", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "autoindex", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_AUTORESET
  Tcl_SetVar2(interp, "sqlite_options", "autoreset", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "autoreset", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_AUTOVACUUM
  Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY);
#endif /* SQLITE_OMIT_AUTOVACUUM */
#if !defined(SQLITE_DEFAULT_AUTOVACUUM)

Changes to src/vdbeapi.c.

341
342
343
344
345
346
347
348
349
350











351


352






353
354
355
356
357
358
359
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;







|
|
|
>
>
>
>
>
>
>
>
>
>
>

>
>
|
>
>
>
>
>
>







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
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 or after SQLITE_DONE.  But beginning
    ** with version 3.7.0, we changed this so that sqlite3_reset() would
    ** be called automatically instead of throwing the SQLITE_MISUSE error.
    ** This "automatic-reset" change is not technically an incompatibility, 
    ** since any application that receives an SQLITE_MISUSE is broken by
    ** definition.
    **
    ** Nevertheless, some published applications that were originally written
    ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE 
    ** returns, and the so were broken by the automatic-reset change.  As a
    ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
    ** legacy behavior of returning SQLITE_MISUSE for cases where the 
    ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
    ** or SQLITE_BUSY error.
    */
#ifdef SQLITE_OMIT_AUTORESET
    if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
      sqlite3_reset((sqlite3_stmt*)p);
    }else{
      return SQLITE_MISUSE_BKPT;
    }
#else
    sqlite3_reset((sqlite3_stmt*)p);
#endif
  }

  /* 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.

70
71
72
73
74
75
76

77
78
79





80
81
82
83
84
85
86
} {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







>
|
|
|
>
>
>
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
} {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.
ifcapable autoreset {
  do_test capi2-1.8 {
    sqlite3_step $VM
  } {SQLITE_ROW}
} else {
  do_test capi2-1.8 {
    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 {
  sqlite3_reset $VM

Changes to test/fkey2.test.

1410
1411
1412
1413
1414
1415
1416

1417
1418
1419





1420
1421
1422
1423
1424
1425
1426
    INSERT INTO one VALUES(1, 2, 3);
  }
} {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);







>
|
|
|
>
>
>
>
>







1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
    INSERT INTO one VALUES(1, 2, 3);
  }
} {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}
ifcapable autoreset {
  do_test fkey2-17.1.3 {
    sqlite3_step $STMT
  } {SQLITE_CONSTRAINT}
} else {
  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);