summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c77
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c5
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql_int.h16
3 files changed, 78 insertions, 20 deletions
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index b80935c199..67db6fd64e 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -30,16 +30,51 @@
#include "php_pdo_pgsql.h"
#include "php_pdo_pgsql_int.h"
-int _pdo_pgsql_error(char *what, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
+int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC) /* {{{ */
{
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s:%d) %s", file, line, errmsg);
- return 1;
+ pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ enum pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
+ pdo_pgsql_error_info *einfo = &H->einfo;
+ char *errmsg = PQerrorMessage(H->server);
+
+ einfo->errcode = errcode;
+ einfo->file = file;
+ einfo->line = line;
+
+ if (einfo->errmsg) {
+ efree(einfo->errmsg);
+ einfo->errmsg = NULL;
+ }
+
+ switch (errcode) {
+ case PGRES_EMPTY_QUERY:
+ *pdo_err = PDO_ERR_SYNTAX;
+ break;
+
+ default:
+ *pdo_err = PDO_ERR_CANT_MAP;
+ break;
+ }
+
+ if (errmsg) {
+ einfo->errmsg = estrdup(errmsg);
+ }
+
+ return errcode;
}
/* }}} */
-int pgsql_handle_error(pdo_dbh_t *dbh, pdo_pgsql_db_handle *H, int errcode) /* {{{ */
+static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) /* {{{ */
{
- return 0;
+ pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ pdo_pgsql_error_info *einfo = &H->einfo;
+
+ if (einfo->errcode) {
+ add_next_index_long(info, einfo->errcode);
+ add_next_index_string(info, einfo->errmsg, 1);
+ }
+
+ return 1;
}
/* }}} */
@@ -67,11 +102,24 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
return 1;
}
-static int pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
+static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ PGresult *res;
+
+ if (!(res = PQexec(H->server, sql))) {
+ /* fatal error */
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR);
+ return 0;
+ } else {
+ ExecStatusType qs = PQresultStatus(res);
+ if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) {
+ pdo_pgsql_error(dbh, qs);
+ return 0;
+ }
+ }
- return 0;
+ return 1;
}
static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
@@ -79,7 +127,7 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
*quoted = emalloc(2*unquotedlen + 3);
(*quoted)[0] = '"';
- *quotedlen = PQescapeString(*quoted + 1, unquoted, unquotedlen);
+ *quotedlen = PQescapeString(*quoted + 1, unquoted, unquotedlen);
(*quoted)[*quotedlen + 1] = '"';
(*quoted)[*quotedlen + 2] = '\0';
*quotedlen += 2;
@@ -91,7 +139,13 @@ static struct pdo_dbh_methods pgsql_methods = {
pgsql_handle_closer,
pgsql_handle_preparer,
pgsql_handle_doer,
- pgsql_handle_quoter
+ pgsql_handle_quoter,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pdo_pgsql_fetch_error_func
};
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
@@ -102,7 +156,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
struct pdo_data_src_parser vars[] = {
{ "host", "", 0 },
{ "port", "", 0 },
- { "dbname", "", 0 },
+ { "dbname", "", 0 },
};
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 3);
@@ -126,8 +180,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
);
if (PQstatus(H->server) != CONNECTION_OK) {
- H->last_err = PQerrorMessage(H->server);
- pdo_pgsql_error("pdo_pgsql_handle_factory", H->last_err);
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR);
goto cleanup;
}
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index ad3780749a..4e2e2b702c 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -68,8 +68,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
status = PQresultStatus(S->result);
if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
- H->last_err = PQerrorMessage(H->server);
- pdo_pgsql_error("pgsql_stmt_execute", H->last_err);
+ pdo_pgsql_error_stmt(stmt, status);
return 0;
}
@@ -126,7 +125,7 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
/* We have already increased count by 1 in pgsql_stmt_fetch() */
*ptr = PQgetvalue(S->result, S->current_row - 1, colno);
- *len = strlen(*ptr);
+ *len = PQgetlength(S->result, S->current_row - 1, colno);
return 1;
}
diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h
index 91a4d3451c..7d0be93586 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql_int.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h
@@ -25,12 +25,19 @@
#include <libpq-fe.h>
+typedef struct {
+ const char *file;
+ int line;
+ unsigned int errcode;
+ char *errmsg;
+} pdo_pgsql_error_info;
+
/* stuff we use in a pgsql database handle */
typedef struct {
PGconn *server;
- char *last_err;
unsigned attached:1;
unsigned _reserved:31;
+ pdo_pgsql_error_info einfo;
} pdo_pgsql_db_handle;
typedef struct {
@@ -41,7 +48,6 @@ typedef struct {
pdo_pgsql_db_handle *H;
PGresult *result;
int current_row;
- char *last_err;
pdo_pgsql_column *cols;
} pdo_pgsql_stmt;
@@ -54,9 +60,9 @@ typedef struct {
extern pdo_driver_t pdo_pgsql_driver;
-extern int _pdo_pgsql_error(char *what, char *errmsg, const char *file, int line TSRMLS_DC);
-#define pdo_pgsql_error(w,s) _pdo_pgsql_error(w, s, __FILE__, __LINE__ TSRMLS_CC)
-extern int pgsql_handle_error(pdo_dbh_t *dbh, pdo_pgsql_db_handle *H, int errcode);
+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 struct pdo_stmt_methods pgsql_stmt_methods;