ID:               39564
 User updated by:  php dot bugreport dot tarpit at spamgourmet dot com
 Reported By:      php dot bugreport dot tarpit at spamgourmet dot com
-Status:           Bogus
+Status:           Open
 Bug Type:         PDO related
 Operating System: Windows 98SE and XP/SP1
 PHP Version:      5.2.0
 New Comment:

There are things you should NOT do after eight hours debugging
COBOL+CICS+DB2+MQ..... Obviously compacting a C-program for a
bug-report is one of these! Sorry, no other excuse for this stupid
mistake. So here is the original code (with the addition of
sqlite3_reset()):

#include <stdio.h>
#include <process.h>
#include <string.h>
#include <sqlite3.h>

int main(int argc, char **argv)
{
  sqlite3      *db;
  sqlite3_stmt *stm;
  int          rc;
  char         *sqli;
  char         *sqlp;
  char         *zErr;
  const char   *tail;

  fprintf(stdout, "'%s' using SQLite %s (compiled) - %s (DLL)\n\n",
argv[0], SQLITE_VERSION, sqlite3_libversion() );

  rc = sqlite3_open("bugtest.db", &db);
     if (rc)
        { fprintf(stdout, "Can't open database: %s\n",
sqlite3_errmsg(db)); exit(255); }

  sqli = "Insert Into TEST (Key, Text) Values (1, 'Test1')";
  sqlp = "Insert Into TEST (Key, Text) Values (?, ?)";

  rc = sqlite3_exec(db, sqli, NULL, NULL, &zErr);
     if (rc)
        { fprintf(stdout, "sqlite3_exec(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  rc = sqlite3_prepare(db, sqlp, strlen(sqlp), &stm, &tail);
     if (rc)
        { fprintf(stdout, "sqlite3_prepare(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  rc = sqlite3_bind_int(stm, 1, 1);
     if (rc)
        { fprintf(stdout, "sqlite3_bind_int(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  rc = sqlite3_bind_text(stm, 2, "Test1", 5, SQLITE_STATIC);
     if (rc)
        { fprintf(stdout, "sqlite3_bind_text(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  rc = sqlite3_step(stm);
     if (rc)
        { fprintf(stdout, "sqlite3_step(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  rc = sqlite3_reset(stm);
     if (rc)
        { fprintf(stdout, "sqlite3_reset(): %i - %s\n", rc,
sqlite3_errmsg(db)); }

  sqlite3_finalize(stm);
  sqlite3_close(db);
  return 0;
}
It produced the following output:

'D:\BCC55\BUGTEST.EXE' using SQLite 3.3.7 (compiled) - 3.3.7 (DLL)

sqlite3_exec(): 19 - PRIMARY KEY must be unique
sqlite3_step(): 1 - SQL logic error or missing database
sqlite3_reset(): 19 - PRIMARY KEY must be unique

As you commented correctly, the error code is fetched with
sqlite3_errmsg(). After a failed sqlite3_step() the error code returned
by sqlite3_errmsg() is wrong; only after a sqlite3_reset() the correct
error code can be fetched with sqlite3_errmsg().
Tonight I found this link explaining this behaviour:
http://www.sqlite.org/cvstrac/tktview?tn=1965.
Calling sqlite3_reset() after a failed sqlite3_step() should then fix
this problem.


Previous Comments:
------------------------------------------------------------------------

[2006-11-23 23:33:38] [EMAIL PROTECTED]

First of all, you're using zErr returned by sqlite3_exec(), of course
it's right.
Second, sqlite3_step() doesn't return error code (as sqlite3_exec()
does), it returns SQLITE_ERROR instead and the error code is fetched
using sqlite3_errcode(db).

------------------------------------------------------------------------

[2006-11-23 23:11:26] php dot bugreport dot tarpit at spamgourmet dot
com

I tried the following code using SQLite 3.3.7:
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <sqlite3.h>
int main()
{ sqlite3      *db;
  sqlite3_stmt *stm;
  int          rc;
  char         *sqli, *sqlp, *zErr;
  const char   *tail;
  rc = sqlite3_open("bugtest.db", &db);
     if(rc)  { fprintf(stdout, "Can't open database: %s\n",
sqlite3_errmsg(db)); exit(255); }
  sqli = "Insert Into TEST (Key, Text) Values (1, 'Test1')";
  sqlp = "Insert Into TEST (Key, Text) Values (?, ?)";
  rc = sqlite3_exec(db, sqli, NULL, NULL, &zErr);
     if(rc)  { fprintf(stdout, "exec(): %i - %s\n", rc, zErr); }
  rc = sqlite3_prepare(db, sqlp, strlen(sqlp), &stm, &tail);
     if(rc)  { fprintf(stdout, "prepare(): %i - %s\n", rc, zErr); }
  rc = sqlite3_bind_int(stm, 1, 1);
     if(rc)  { fprintf(stdout, "bind_int(): %i - %s\n", rc, zErr); }
  rc = sqlite3_bind_text(stm, 2, "Test1", 5, SQLITE_STATIC);
     if(rc)  { fprintf(stdout, "bind_text(): %i - %s\n", rc, zErr); }
  rc = sqlite3_step(stm);
     if(rc)  { fprintf(stdout, "step(): %i - %s\n", rc, zErr); }
  sqlite3_finalize(stm); sqlite3_close(db); return 0; }

With result:
exec(): 19 - PRIMARY KEY must be unique
step(): 1 - PRIMARY KEY must be unique

Yes, sqlite3_step() does return the wrong errorcode - that is a bug in
SQLite. But it still returns the correct message, which appears to get
lost somewhere.....

------------------------------------------------------------------------

[2006-11-21 22:10:34] [EMAIL PROTECTED]

These two methods use different SQLite functions to execute queries,
which report different errors. And that is the reason I can hardly
imagine why it's PDO fault.

------------------------------------------------------------------------

[2006-11-21 22:04:52] php dot bugreport dot tarpit at spamgourmet dot
com

Original category was "SQLite related" - because that is the only part
of PDO I use. Since the error is obviously not in SQLite (which reports
the correct errors), but in PDO (which reports different errors
depending on the use of PDO::exec() or PDOStatement::execute()
functions), category "PDO related" would be better.

------------------------------------------------------------------------

[2006-11-21 09:29:12] [EMAIL PROTECTED]

SQLite inconsistencies should be reported to SQLite developers.

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/39564

-- 
Edit this bug report at http://bugs.php.net/?id=39564&edit=1

Reply via email to