From 4f778ca31d3a1c71f9eeab0f9e29f3e462fc8f19 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 13 May 2005 18:09:03 +0000 Subject: [PATCH] patch by Christopher Kings-Lynne, slightly modified --- ext/pdo_pgsql/config.m4 | 2 ++ ext/pdo_pgsql/pgsql_driver.c | 23 +++++++++++++++-------- ext/pdo_pgsql/pgsql_statement.c | 28 +++++++++++++++++++++------- ext/pdo_pgsql/php_pdo_pgsql_int.h | 8 +++++--- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4 index 569f748204..d21bb7cbde 100644 --- a/ext/pdo_pgsql/config.m4 +++ b/ext/pdo_pgsql/config.m4 @@ -90,6 +90,8 @@ if test "$PHP_PDO_PGSQL" != "no"; then AC_CHECK_LIB(pq, PQparameterStatus,AC_DEFINE(HAVE_PQPARAMETERSTATUS,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQprotocolVersion,AC_DEFINE(HAVE_PQPROTOCOLVERSION,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, PQtransactionStatus,AC_DEFINE(HAVE_PGTRANSACTIONSTATUS,1,[PostgreSQL 7.4 or later])) + AC_CHECK_LIB(pq, PQunescapeBytea,AC_DEFINE(HAVE_PQUNESCAPEBYTEA,1,[PostgreSQL 7.4 or later])) + AC_CHECK_LIB(pq, PQresultErrorField,AC_DEFINE(HAVE_PQRESULTERRORFIELD,1,[PostgreSQL 7.4 or later])) AC_CHECK_LIB(pq, pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether libpq is compiled with --enable-multibyte])) LIBS=$old_LIBS LDFLAGS=$old_LDFLAGS diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 72b6781f2d..b63b20f125 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -52,7 +52,7 @@ static char * _pdo_pgsql_trim_message(const char *message, int persistent) return tmp; } -int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC) /* {{{ */ +int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *file, int line TSRMLS_DC) /* {{{ */ { pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code; @@ -68,10 +68,11 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char * einfo->errmsg = NULL; } - switch (errcode) { - default: - strcpy(*pdo_err, "HY000"); - break; + if (sqlstate == NULL) { + strcpy(*pdo_err, "HY000"); + } + else { + strcpy(*pdo_err, sqlstate); } if (errmsg) { @@ -154,12 +155,18 @@ static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRM if (!(res = PQexec(H->server, sql))) { /* fatal error */ - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); return 0; } else { ExecStatusType qs = PQresultStatus(res); if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) { - pdo_pgsql_error(dbh, qs); +#if HAVE_PQRESULTERRORFIELD + char * sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE); + pdo_pgsql_error(dbh, qs, (const char *)sqlstate); + PQfreemem(sqlstate); +#else + pdo_pgsql_error(dbh, qs, NULL); +#endif PQclear(res); return 0; } @@ -384,7 +391,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ } if (PQstatus(H->server) != CONNECTION_OK) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE); goto cleanup; } diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index f1393aa1dc..1abb76d2f0 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -97,7 +97,13 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) status = PQresultStatus(S->result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { - pdo_pgsql_error_stmt(stmt, status); +#if HAVE_PQRESULTERRORFIELD + char * sqlstate = PQresultErrorField(S->result, PG_DIAG_SQLSTATE); + pdo_pgsql_error_stmt(stmt, status, (const char *)sqlstate); +#else + pdo_pgsql_error_stmt(stmt, status, NULL); +#endif + return 0; } @@ -145,7 +151,12 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, status = PQresultStatus(S->result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { - pdo_pgsql_error_stmt(stmt, status); +#if HAVE_PQRESULTERRORFIELD + char * sqlstate = PQresultErrorField(S->result, PG_DIAG_SQLSTATE); + pdo_pgsql_error_stmt(stmt, status, (const char *)sqlstate); +#else + pdo_pgsql_error_stmt(stmt, status, NULL); +#endif return 0; } @@ -209,7 +220,7 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) } /* PQunescapeBytea() from PostgreSQL 7.3 to provide bytea unescape feature to 7.2 users. - Renamed to php_pgsql_unescape_bytea() */ + Renamed to php_pdo_pgsql_unescape_bytea() */ /* * PQunescapeBytea - converts the null terminated string representation * of a bytea, strtext, into binary, filling a buffer. It returns a @@ -231,7 +242,7 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) * 5 \' * 6 \\ */ -static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) +static unsigned char *php_pdo_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) { size_t buflen; unsigned char *buffer, @@ -346,11 +357,14 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned break; case PDO_PARAM_LOB: - tmp_ptr = php_pgsql_unescape_bytea(*ptr, &tmp_len); - *ptr = estrndup(tmp_ptr, tmp_len); + *ptr = php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len); *len = tmp_len; *caller_frees = 1; - free(tmp_ptr); + break; + case PDO_PARAM_NULL: + case PDO_PARAM_STR: + case PDO_PARAM_STMT: + case PDO_PARAM_INPUT_OUTPUT: break; } } diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index ee3e290f83..a2f98b783a 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -25,6 +25,8 @@ #include +#define PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE "08006" + typedef struct { const char *file; int line; @@ -65,9 +67,9 @@ typedef struct { extern pdo_driver_t pdo_pgsql_driver; -extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC); -#define pdo_pgsql_error(d,e) _pdo_pgsql_error(d, NULL, e, __FILE__, __LINE__ TSRMLS_CC) -#define pdo_pgsql_error_stmt(s,e) _pdo_pgsql_error(s->dbh, s, e, __FILE__, __LINE__ TSRMLS_CC) +extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *file, int line TSRMLS_DC); +#define pdo_pgsql_error(d,e,z) _pdo_pgsql_error(d, NULL, e, z, __FILE__, __LINE__ TSRMLS_CC) +#define pdo_pgsql_error_stmt(s,e,z) _pdo_pgsql_error(s->dbh, s, e, z, __FILE__, __LINE__ TSRMLS_CC) extern struct pdo_stmt_methods pgsql_stmt_methods; -- 2.50.1