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