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