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

Overview
Comment:Remove the error message output parameter from sqlite4_exec().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6833c6df33e7596fcb525654d8f4f4da8e9b1564
User & Date: dan 2013-06-07 14:22:17.361
Context
2013-06-07
14:36
Change the order of the parameters passed to sqlite4_collation_needed() and needed16() to be consistent with other callback APIs. check-in: 22b6bdf65a user: dan tags: trunk
14:22
Remove the error message output parameter from sqlite4_exec(). check-in: 6833c6df33 user: dan tags: trunk
02:00
Replace placeholder sqlite4_num_to_int32. Change API to be analogous sqlite4_num_to_int64. Add tests. check-in: 762134b4a8 user: peterreid tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/legacy.c.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
** argument to xCall().  If xCall=NULL then no callback
** is invoked, even for queries.
*/
int sqlite4_exec(
  sqlite4 *db,                /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  int (*xCall)(void*,int,sqlite4_value**,const char**),  /* Callback function */
  void *pArg,                 /* First argument to xCall() */
  char **pzErrMsg             /* Write error messages here */
){
  int rc = SQLITE4_OK;        /* Return code */
  int nRetry = 0;             /* Number of retry attempts */
  int bAbort = 0;             /* Set to true if callback returns non-zero */

  if( !sqlite4SafetyCheckOk(db) ) return SQLITE4_MISUSE_BKPT;
  if( zSql==0 ) zSql = "";







|
<







27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
** argument to xCall().  If xCall=NULL then no callback
** is invoked, even for queries.
*/
int sqlite4_exec(
  sqlite4 *db,                /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  int (*xCall)(void*,int,sqlite4_value**,const char**),  /* Callback function */
  void *pArg                  /* First argument to xCall() */

){
  int rc = SQLITE4_OK;        /* Return code */
  int nRetry = 0;             /* Number of retry attempts */
  int bAbort = 0;             /* Set to true if callback returns non-zero */

  if( !sqlite4SafetyCheckOk(db) ) return SQLITE4_MISUSE_BKPT;
  if( zSql==0 ) zSql = "";
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

    sqlite4DbFree(db, azCol);
  }

  if( bAbort ) rc = SQLITE4_ABORT;
  rc = sqlite4ApiExit(db, rc);

  if( pzErrMsg ){
    if( rc!=SQLITE4_OK ){
      *pzErrMsg = sqlite4DbStrDup(0, sqlite4_errmsg(db));
      if( 0==*pzErrMsg ){
        rc = SQLITE4_NOMEM;
        sqlite4Error(db, SQLITE4_NOMEM, 0);
      }
    }else{
      *pzErrMsg = 0;
    }
  }

  sqlite4_mutex_leave(db->mutex);
  return rc;
}







<
<
<
<
<
<
<
<
<
<
<
<



113
114
115
116
117
118
119












120
121
122

    sqlite4DbFree(db, azCol);
  }

  if( bAbort ) rc = SQLITE4_ABORT;
  rc = sqlite4ApiExit(db, rc);













  sqlite4_mutex_leave(db->mutex);
  return rc;
}
Changes to src/prepare.c.
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
        db->aDb[iDb].zName, zMasterName);
#ifndef SQLITE4_OMIT_AUTHORIZATION
    {
      Authorizer *pAuth;
      pAuth = db->pAuth;
      db->pAuth = 0;
#endif
      rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData, 0);
#ifndef SQLITE4_OMIT_AUTHORIZATION
      db->pAuth = pAuth;
    }
#endif
    if( rc==SQLITE4_OK ) rc = initData.rc;
    sqlite4DbFree(db, zSql);
#ifndef SQLITE4_OMIT_ANALYZE







|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
        db->aDb[iDb].zName, zMasterName);
#ifndef SQLITE4_OMIT_AUTHORIZATION
    {
      Authorizer *pAuth;
      pAuth = db->pAuth;
      db->pAuth = 0;
#endif
      rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData);
#ifndef SQLITE4_OMIT_AUTHORIZATION
      db->pAuth = pAuth;
    }
#endif
    if( rc==SQLITE4_OK ) rc = initData.rc;
    sqlite4DbFree(db, zSql);
#ifndef SQLITE4_OMIT_ANALYZE
Changes to src/shell.c.
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
  struct callback_data *p, 
  const char *zQuery
){
  int rc;
  char *zErr = 0;
  rc = sqlite4_exec(p->db, zQuery, dump_callback, p, &zErr);
  if( rc==SQLITE4_CORRUPT ){

    char *zQ2;
    int len = strlen30(zQuery);
    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
    if( zErr ){
      fprintf(p->out, "/****** %s ******/\n", zErr);
      sqlite4_free(0, zErr);
      zErr = 0;
    }
    zQ2 = malloc( len+100 );
    if( zQ2==0 ) return rc;
    sqlite4_snprintf(zQ2,sizeof(zQ2), "%s ORDER BY rowid DESC", zQuery);
    rc = sqlite4_exec(p->db, zQ2, dump_callback, p, &zErr);
    if( rc ){
      fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
    }else{
      rc = SQLITE4_CORRUPT;
    }
    sqlite4_free(0, zErr);
    free(zQ2);
  }
  return rc;
}

/*
** Text of a help message







<
|

>





<
<




|

|



<







1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252


1253
1254
1255
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265
1266
1267
1268
1269
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
  struct callback_data *p, 
  const char *zQuery
){
  int rc;

  rc = sqlite4_exec(p->db, zQuery, dump_callback, p);
  if( rc==SQLITE4_CORRUPT ){
    const char *zErr = sqlite4_errmsg(p->db);
    char *zQ2;
    int len = strlen30(zQuery);
    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
    if( zErr ){
      fprintf(p->out, "/****** %s ******/\n", zErr);


    }
    zQ2 = malloc( len+100 );
    if( zQ2==0 ) return rc;
    sqlite4_snprintf(zQ2,sizeof(zQ2), "%s ORDER BY rowid DESC", zQuery);
    rc = sqlite4_exec(p->db, zQ2, dump_callback, p);
    if( rc ){
      fprintf(p->out, "/****** ERROR: %s ******/\n", sqlite4_errmsg(p->db));
    }else{
      rc = SQLITE4_CORRUPT;
    }

    free(zQ2);
  }
  return rc;
}

/*
** Text of a help message
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
    open_db(p);
    /* When playing back a "dump", the content might appear in an order
    ** which causes immediate foreign key constraints to be violated.
    ** So disable foreign-key constraint enforcement to prevent problems. */
    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
    fprintf(p->out, "BEGIN TRANSACTION;\n");
    p->writableSchema = 0;
    sqlite4_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
    p->nErr = 0;
    if( nArg==1 ){
      run_schema_dump_query(p, 
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
      );
      run_schema_dump_query(p, 







|







1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
    open_db(p);
    /* When playing back a "dump", the content might appear in an order
    ** which causes immediate foreign key constraints to be violated.
    ** So disable foreign-key constraint enforcement to prevent problems. */
    fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
    fprintf(p->out, "BEGIN TRANSACTION;\n");
    p->writableSchema = 0;
    sqlite4_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0);
    p->nErr = 0;
    if( nArg==1 ){
      run_schema_dump_query(p, 
        "SELECT name, type, sql FROM sqlite_master "
        "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
      );
      run_schema_dump_query(p, 
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
        zShellStatic = 0;
      }
    }
    if( p->writableSchema ){
      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
      p->writableSchema = 0;
    }
    sqlite4_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
    sqlite4_exec(p->db, "RELEASE dump;", 0, 0, 0);
    fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
    p->echoOn = booleanValue(azArg[1]);
  }else








|
|







1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
        zShellStatic = 0;
      }
    }
    if( p->writableSchema ){
      fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
      p->writableSchema = 0;
    }
    sqlite4_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0);
    sqlite4_exec(p->db, "RELEASE dump;", 0, 0);
    fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
    p->echoOn = booleanValue(azArg[1]);
  }else

1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ){
      fprintf(stderr, "Error: out of memory\n");
      fclose(in);
      sqlite4_finalize(pStmt);
      return 1;
    }
    sqlite4_exec(p->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in, 1))!=0 ){
      char *z, c;
      int inQuote = 0;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; (c = *z)!=0; z++){







|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ){
      fprintf(stderr, "Error: out of memory\n");
      fclose(in);
      sqlite4_finalize(pStmt);
      return 1;
    }
    sqlite4_exec(p->db, "BEGIN", 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in, 1))!=0 ){
      char *z, c;
      int inQuote = 0;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; (c = *z)!=0; z++){
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
        rc = 1;
        break; /* from while */
      }
    } /* end while */
    free(azCol);
    fclose(in);
    sqlite4_finalize(pStmt);
    sqlite4_exec(p->db, zCommit, 0, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));







|







1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
        rc = 1;
        break; /* from while */
      }
    } /* end while */
    free(azCol);
    fclose(in);
    sqlite4_finalize(pStmt);
    sqlite4_exec(p->db, zCommit, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
Changes to src/sqlite.h.in.
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
**
** The sqlite4_exec() interface is a convenience wrapper around
** [sqlite4_prepare()], [sqlite4_step()], and [sqlite4_finalize()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code. 
**
** ^The sqlite4_exec() interface runs zero or more UTF-8 encoded,
** semicolon-separate SQL statements passed into its 2nd argument,
** in the context of the [database connection] passed in as its 1st
** argument.  ^If the callback function of the 3rd argument to
** sqlite4_exec() is not NULL, then it is invoked for each result row
** coming out of the evaluated SQL statements.  ^The 4th argument to
** sqlite4_exec() is relayed through to the 1st argument of each
** callback invocation.  ^If the callback pointer to sqlite4_exec()
** is NULL, then no callback is ever invoked and result rows are
** ignored.
**
** ^If an error occurs while evaluating the SQL statements passed into
** sqlite4_exec(), then execution of the current statement stops and
** any subsequent statements are not executed.  ^If the 5th parameter 
** to sqlite4_exec() is not NULL then any error message is written into 
** memory obtained from [sqlite4_malloc()] and passed back through the 5th 
** parameter. To avoid memory leaks, the application should invoke 
** [sqlite4_free()] on error message strings returned through the 5th 
** parameter of of sqlite4_exec() after the error message string is no 
** longer needed. ^If the 5th parameter to sqlite4_exec() is not NULL and 
** no errors occur, then sqlite4_exec() sets the pointer in its 5th 
** parameter to NULL before returning.
**
** ^If an sqlite4_exec() callback returns non-zero, the sqlite4_exec()
** routine returns SQLITE4_ABORT without invoking the callback again and
** without running any subsequent SQL statements.
**
** ^The 2nd argument to the sqlite4_exec() callback function is the
** number of columns in the result.  ^The 3rd argument to the sqlite4_exec()







|










|
|
<
<
<
<
<
<
<
|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502







503
504
505
506
507
508
509
510
**
** The sqlite4_exec() interface is a convenience wrapper around
** [sqlite4_prepare()], [sqlite4_step()], and [sqlite4_finalize()],
** that allows an application to run multiple statements of SQL
** without having to use a lot of C code. 
**
** ^The sqlite4_exec() interface runs zero or more UTF-8 encoded,
** semicolon-separated SQL statements passed into its 2nd argument,
** in the context of the [database connection] passed in as its 1st
** argument.  ^If the callback function of the 3rd argument to
** sqlite4_exec() is not NULL, then it is invoked for each result row
** coming out of the evaluated SQL statements.  ^The 4th argument to
** sqlite4_exec() is relayed through to the 1st argument of each
** callback invocation.  ^If the callback pointer to sqlite4_exec()
** is NULL, then no callback is ever invoked and result rows are
** ignored.
**
** ^If an error occurs while evaluating the SQL statements passed into
** sqlite4_exec(), then execution of the current statement stops, an
** error code is returned to the user and no subsequent statements are 







** executed.
**
** ^If an sqlite4_exec() callback returns non-zero, the sqlite4_exec()
** routine returns SQLITE4_ABORT without invoking the callback again and
** without running any subsequent SQL statements.
**
** ^The 2nd argument to the sqlite4_exec() callback function is the
** number of columns in the result.  ^The 3rd argument to the sqlite4_exec()
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
**      the 2nd parameter of sqlite4_exec() while sqlite4_exec() is running.
** </ul>
*/
int sqlite4_exec(
  sqlite4 *,                      /* An open database */
  const char *zSql,               /* SQL to be evaluated */
  int (*)(void*,int,sqlite4_value**,const char**),    /* Callback function */
  void *,                         /* Context for callback */
  char **pzErrmsg                 /* Error msg written here */
);

/*
** CAPIREF: Result Codes
** KEYWORDS: SQLITE4_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**







|
<







530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
**      the 2nd parameter of sqlite4_exec() while sqlite4_exec() is running.
** </ul>
*/
int sqlite4_exec(
  sqlite4 *,                      /* An open database */
  const char *zSql,               /* SQL to be evaluated */
  int (*)(void*,int,sqlite4_value**,const char**),    /* Callback function */
  void *                          /* Context for callback */

);

/*
** CAPIREF: Result Codes
** KEYWORDS: SQLITE4_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**
Changes to src/tclsqlite.c.
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  int rc = result;
  const char *zEnd;

  pDb->nTransaction--;
  zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];

  pDb->disableAuth++;
  if( sqlite4_exec(pDb->db, zEnd, 0, 0, 0) ){
      /* This is a tricky scenario to handle. The most likely cause of an
      ** error is that the exec() above was an attempt to commit the 
      ** top-level transaction that returned SQLITE4_BUSY. Or, less likely,
      ** that an IO-error has occured. In either case, throw a Tcl exception
      ** and try to rollback the transaction.
      **
      ** But it could also be that the user executed one or more BEGIN, 
      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
      ** this method's logic. Not clear how this would be best handled.
      */
    if( rc!=TCL_ERROR ){
      Tcl_AppendResult(interp, sqlite4_errmsg(pDb->db), 0);
      rc = TCL_ERROR;
    }
    sqlite4_exec(pDb->db, "ROLLBACK", 0, 0, 0);
  }
  pDb->disableAuth--;

  return rc;
}

/*







|














|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  int rc = result;
  const char *zEnd;

  pDb->nTransaction--;
  zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];

  pDb->disableAuth++;
  if( sqlite4_exec(pDb->db, zEnd, 0, 0) ){
      /* This is a tricky scenario to handle. The most likely cause of an
      ** error is that the exec() above was an attempt to commit the 
      ** top-level transaction that returned SQLITE4_BUSY. Or, less likely,
      ** that an IO-error has occured. In either case, throw a Tcl exception
      ** and try to rollback the transaction.
      **
      ** But it could also be that the user executed one or more BEGIN, 
      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
      ** this method's logic. Not clear how this would be best handled.
      */
    if( rc!=TCL_ERROR ){
      Tcl_AppendResult(interp, sqlite4_errmsg(pDb->db), 0);
      rc = TCL_ERROR;
    }
    sqlite4_exec(pDb->db, "ROLLBACK", 0, 0);
  }
  pDb->disableAuth--;

  return rc;
}

/*
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
    }
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ) {
      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
      fclose(in);
      return TCL_ERROR;
    }
    (void)sqlite4_exec(pDb->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){
      char *z;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; *z; z++){
        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){







|







1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
    }
    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
    if( azCol==0 ) {
      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
      fclose(in);
      return TCL_ERROR;
    }
    (void)sqlite4_exec(pDb->db, "BEGIN", 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in))!=0 ){
      char *z;
      lineno++;
      azCol[0] = zLine;
      for(i=0, z=zLine; *z; z++){
        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
        zCommit = "ROLLBACK";
        break;
      }
    }
    free(azCol);
    fclose(in);
    sqlite4_finalize(pStmt);
    (void)sqlite4_exec(pDb->db, zCommit, 0, 0, 0);

    if( zCommit[0] == 'C' ){
      /* success, set result as number of lines processed */
      pResult = Tcl_GetObjResult(interp);
      Tcl_SetIntObj(pResult, lineno);
      rc = TCL_OK;
    }else{







|







1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
        zCommit = "ROLLBACK";
        break;
      }
    }
    free(azCol);
    fclose(in);
    sqlite4_finalize(pStmt);
    (void)sqlite4_exec(pDb->db, zCommit, 0, 0);

    if( zCommit[0] == 'C' ){
      /* success, set result as number of lines processed */
      pResult = Tcl_GetObjResult(interp);
      Tcl_SetIntObj(pResult, lineno);
      rc = TCL_OK;
    }else{
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
      }
    }
    pScript = objv[objc-1];

    /* Run the SQLite BEGIN command to open a transaction or savepoint. */
    pDb->disableAuth++;
    rc = sqlite4_exec(pDb->db, zBegin, 0, 0, 0);
    pDb->disableAuth--;
    if( rc!=SQLITE4_OK ){
      Tcl_AppendResult(interp, sqlite4_errmsg(pDb->db), 0);
      return TCL_ERROR;
    }
    pDb->nTransaction++;








|







2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
      }
    }
    pScript = objv[objc-1];

    /* Run the SQLite BEGIN command to open a transaction or savepoint. */
    pDb->disableAuth++;
    rc = sqlite4_exec(pDb->db, zBegin, 0, 0);
    pDb->disableAuth--;
    if( rc!=SQLITE4_OK ){
      Tcl_AppendResult(interp, sqlite4_errmsg(pDb->db), 0);
      return TCL_ERROR;
    }
    pDb->nTransaction++;

Changes to src/vdbe.c.
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
    if( zSql==0 ){
      rc = SQLITE4_NOMEM;
    }else{
      assert( db->init.busy==0 );
      db->init.busy = 1;
      initData.rc = SQLITE4_OK;
      assert( !db->mallocFailed );
      rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData, 0);
      if( rc==SQLITE4_OK ) rc = initData.rc;
      sqlite4DbFree(db, zSql);
      db->init.busy = 0;
    }
  }
  if( rc==SQLITE4_NOMEM ){
    goto no_mem;







|







3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
    if( zSql==0 ){
      rc = SQLITE4_NOMEM;
    }else{
      assert( db->init.busy==0 );
      db->init.busy = 1;
      initData.rc = SQLITE4_OK;
      assert( !db->mallocFailed );
      rc = sqlite4_exec(db, zSql, sqlite4InitCallback, &initData);
      if( rc==SQLITE4_OK ) rc = initData.rc;
      sqlite4DbFree(db, zSql);
      db->init.busy = 0;
    }
  }
  if( rc==SQLITE4_NOMEM ){
    goto no_mem;
Changes to test/test_main.c.
338
339
340
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
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB FORMAT STRING", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  Tcl_DStringInit(&str);
  zSql = sqlite4_mprintf(0, argv[2], argv[3]);
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str, &zErr);
  sqlite4_free(0, zSql);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, rc==SQLITE4_OK ? Tcl_DStringValue(&str) : zErr);
  Tcl_DStringFree(&str);
  if( zErr ) sqlite4_free(0, zErr);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_exec_hex  DB  HEX
**
** Invoke the sqlite4_exec() on a string that is obtained by translating
** HEX into ASCII.  Most characters are translated as is.  %HH becomes
** a hex character.
*/
static int test_exec_hex(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  Tcl_DString str;
  int rc, i, j;
  char *zErr = 0;
  char *zHex;
  char zSql[500];
  char zBuf[30];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB HEX", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zHex = argv[2];
  for(i=j=0; i<sizeof(zSql) && zHex[j]; i++, j++){
    if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){
      zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);
      j += 2;
    }else{
      zSql[i] = zHex[j];
    }
  }
  zSql[i] = 0;
  Tcl_DStringInit(&str);
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str, &zErr);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, rc==SQLITE4_OK ? Tcl_DStringValue(&str) : zErr);
  Tcl_DStringFree(&str);
  if( zErr ) sqlite4_free(0, zErr);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  db_enter DB
**         db_leave DB







|



|

<




















<




















|


|

<







338
339
340
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
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB FORMAT STRING", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  Tcl_DStringInit(&str);
  zSql = sqlite4_mprintf(0, argv[2], argv[3]);
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str);
  sqlite4_free(0, zSql);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, !rc ? Tcl_DStringValue(&str) : sqlite4_errmsg(db));
  Tcl_DStringFree(&str);

  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_exec_hex  DB  HEX
**
** Invoke the sqlite4_exec() on a string that is obtained by translating
** HEX into ASCII.  Most characters are translated as is.  %HH becomes
** a hex character.
*/
static int test_exec_hex(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  Tcl_DString str;
  int rc, i, j;

  char *zHex;
  char zSql[500];
  char zBuf[30];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB HEX", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zHex = argv[2];
  for(i=j=0; i<sizeof(zSql) && zHex[j]; i++, j++){
    if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){
      zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);
      j += 2;
    }else{
      zSql[i] = zHex[j];
    }
  }
  zSql[i] = 0;
  Tcl_DStringInit(&str);
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, !rc ? Tcl_DStringValue(&str) : sqlite4_errmsg(db));
  Tcl_DStringFree(&str);

  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  db_enter DB
**         db_leave DB
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  Tcl_DString str;
  int rc;
  char *zErr = 0;
  char *zSql;
  int i, j;
  char zBuf[30];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  Tcl_DStringInit(&str);
  zSql = sqlite4_mprintf(0, "%s", argv[2]);
  for(i=j=0; zSql[i];){
    if( zSql[i]=='%' ){
      zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);
      i += 3;
    }else{
      zSql[j++] = zSql[i++];
    }
  }
  zSql[j] = 0;
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str, &zErr);
  sqlite4_free(0, zSql);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, rc==SQLITE4_OK ? Tcl_DStringValue(&str) : zErr);
  Tcl_DStringFree(&str);
  if( zErr ) sqlite4_free(0, zErr);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_exec_nr  DB  SQL
**
** Invoke the sqlite4_exec interface using the open database DB.  Discard
** all results
*/
static int test_exec_nr(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  int rc;
  char *zErr = 0;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  rc = sqlite4_exec(db, argv[2], 0, 0, &zErr);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
**







<




















|



|

<


















<






|







446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
504
505
506
507
508
509
510
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  Tcl_DString str;
  int rc;

  char *zSql;
  int i, j;
  char zBuf[30];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  Tcl_DStringInit(&str);
  zSql = sqlite4_mprintf(0, "%s", argv[2]);
  for(i=j=0; zSql[i];){
    if( zSql[i]=='%' ){
      zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);
      i += 3;
    }else{
      zSql[j++] = zSql[i++];
    }
  }
  zSql[j] = 0;
  rc = sqlite4_exec(db, zSql, exec_printf_cb, &str);
  sqlite4_free(0, zSql);
  sprintf(zBuf, "%d", rc);
  Tcl_AppendElement(interp, zBuf);
  Tcl_AppendElement(interp, !rc ? Tcl_DStringValue(&str) : sqlite4_errmsg(db));
  Tcl_DStringFree(&str);

  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_exec_nr  DB  SQL
**
** Invoke the sqlite4_exec interface using the open database DB.  Discard
** all results
*/
static int test_exec_nr(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite4 *db;
  int rc;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  rc = sqlite4_exec(db, argv[2], 0, 0);
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite4_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
**
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
  int argc,  
  sqlite4_value **argv
){
  struct dstr x;
  sqlite4 *db = (sqlite4 *)sqlite4_context_appdata(context);
  const char *zSql = sqlite4_value_text(argv[0], 0);
  memset(&x, 0, sizeof(x));
  (void)sqlite4_exec(db, zSql, execFuncCallback, &x, 0);
  sqlite4_result_text(context, x.z, x.nUsed, SQLITE4_TRANSIENT, 0);
  sqlite4_free(0, x.z);
}

/*
** Implementation of tkt2213func(), a scalar function that takes exactly
** one argument. It has two interesting features:







|







776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  int argc,  
  sqlite4_value **argv
){
  struct dstr x;
  sqlite4 *db = (sqlite4 *)sqlite4_context_appdata(context);
  const char *zSql = sqlite4_value_text(argv[0], 0);
  memset(&x, 0, sizeof(x));
  (void)sqlite4_exec(db, zSql, execFuncCallback, &x);
  sqlite4_result_text(context, x.z, x.nUsed, SQLITE4_TRANSIENT, 0);
  sqlite4_free(0, x.z);
}

/*
** Implementation of tkt2213func(), a scalar function that takes exactly
** one argument. It has two interesting features:
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
        " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  prepStack();
  (void)sqlite4_exec(db, argv[2], 0, 0, 0);
  for(i=65535; i>=0 && ((u32*)sqlite4_stack_baseline)[-i]==0xdeadbeef; i--){}
  Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
  return TCL_OK;
}

/*
** Usage: sqlite_delete_function DB function-name







|







3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
        " DB SQL", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  prepStack();
  (void)sqlite4_exec(db, argv[2], 0, 0);
  for(i=65535; i>=0 && ((u32*)sqlite4_stack_baseline)[-i]==0xdeadbeef; i--){}
  Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
  return TCL_OK;
}

/*
** Usage: sqlite_delete_function DB function-name