summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/pdo_pgsql/package.xml2
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c43
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c45
-rw-r--r--ext/pdo_pgsql/php_pdo_pgsql_int.h2
4 files changed, 48 insertions, 44 deletions
diff --git a/ext/pdo_pgsql/package.xml b/ext/pdo_pgsql/package.xml
index b7f2613e84..9a3864d24b 100644
--- a/ext/pdo_pgsql/package.xml
+++ b/ext/pdo_pgsql/package.xml
@@ -30,7 +30,7 @@
<license>PHP</license>
<release>
<state>beta</state>
- <version>1.0RC2</version>
+ <version>1.0</version>
<date>2005-11-01</date>
<notes>
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 43ed6e3258..96d2202536 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -153,8 +153,9 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
}
#if HAVE_PQPREPARE
- if (!driver_options || pdo_attr_lval(driver_options,
- PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0 TSRMLS_CC) == 0) {
+ if ((!driver_options || pdo_attr_lval(driver_options,
+ PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0 TSRMLS_CC) == 0)
+ && PQprotocolVersion(H->server) > 2) {
stmt->supports_placeholders = PDO_PLACEHOLDER_NAMED;
stmt->named_rewrite_template = "$%d";
ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len TSRMLS_CC);
@@ -169,41 +170,15 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
}
spprintf(&S->stmt_name, 0, "pdo_pgsql_stmt_%08x", (unsigned int)stmt);
- res = PQprepare(H->server, S->stmt_name, sql, 0, NULL);
+ /* that's all for now; we'll defer the actual prepare until the first execute call */
+
if (nsql) {
- efree(nsql);
- }
- if (!res) {
- pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
- return 0;
+ S->query = nsql;
+ } else {
+ S->query = estrdup(sql);
}
- /* check if the connection is using protocol version 2.0.
- * if that is the reason that the prepare failed, we want to fall
- * through and let PDO emulate it for us */
- status = PQresultStatus(res);
- switch (status) {
- case PGRES_COMMAND_OK:
- case PGRES_TUPLES_OK:
- /* it worked */
- PQclear(res);
- return 1;
-
- case PGRES_BAD_RESPONSE:
- /* server is probably too old; fall through and let
- * PDO emulate it */
- efree(S->stmt_name);
- S->stmt_name = NULL;
- PQclear(res);
- break;
-
- default:
- /* protocol 3.0 and above; hard error */
- pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
- PQclear(res);
- return 0;
- }
- /* fall through */
+ return 1;
}
#endif
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 9810735b3f..fed9741513 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -36,6 +36,7 @@
#define INT8OID 20
#define INT2OID 21
#define INT4OID 23
+#define TEXTOID 25
#define OIDOID 26
@@ -105,12 +106,10 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
pdo_pgsql_db_handle *H = S->H;
ExecStatusType status;
- if (stmt->executed) {
- /* ensure that we free any previous unfetched results */
- if(S->result) {
- PQclear(S->result);
- S->result = NULL;
- }
+ /* ensure that we free any previous unfetched results */
+ if(S->result) {
+ PQclear(S->result);
+ S->result = NULL;
}
S->current_row = 0;
@@ -119,13 +118,32 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
if (S->stmt_name) {
/* using a prepared statement */
+ if (!stmt->executed) {
+ /* we deferred the prepare until now, because we didn't
+ * know anything about the parameter types; now we do */
+ S->result = PQprepare(H->server, S->stmt_name, S->query,
+ stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
+ S->param_types);
+ status = PQresultStatus(S->result);
+ switch (status) {
+ case PGRES_COMMAND_OK:
+ case PGRES_TUPLES_OK:
+ /* it worked */
+ PQclear(S->result);
+ break;
+ default:
+ pdo_pgsql_error_stmt(stmt, status,
+ pdo_pgsql_sqlstate(S->result));
+ return 0;
+ }
+ }
S->result = PQexecPrepared(H->server, S->stmt_name,
stmt->bound_params ?
zend_hash_num_elements(stmt->bound_params) :
0,
(const char**)S->param_values,
S->param_lengths,
- NULL,
+ S->param_formats,
0);
} else
#endif
@@ -196,7 +214,9 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
S->param_formats = ecalloc(
zend_hash_num_elements(stmt->bound_params),
sizeof(int));
-
+ S->param_types = ecalloc(
+ zend_hash_num_elements(stmt->bound_params),
+ sizeof(Oid));
}
if (param->paramno >= 0) {
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
@@ -222,12 +242,19 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
} else if (Z_TYPE_P(param->parameter) == IS_BOOL) {
S->param_values[param->paramno] = Z_BVAL_P(param->parameter) ? "t" : "f";
S->param_lengths[param->paramno] = 1;
- S->param_formats[param->paramno] = 1;
+ S->param_formats[param->paramno] = 0;
} else {
convert_to_string(param->parameter);
S->param_values[param->paramno] = Z_STRVAL_P(param->parameter);
S->param_lengths[param->paramno] = Z_STRLEN_P(param->parameter);
+ S->param_formats[param->paramno] = 0;
+ }
+
+ if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
+ S->param_types[param->paramno] = 0;
S->param_formats[param->paramno] = 1;
+ } else {
+ S->param_types[param->paramno] = 0;
}
}
break;
diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h
index 855c934488..1b48f63ee1 100644
--- a/ext/pdo_pgsql/php_pdo_pgsql_int.h
+++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h
@@ -57,9 +57,11 @@ typedef struct {
char *cursor_name;
#if HAVE_PQPREPARE
char *stmt_name;
+ char *query;
char **param_values;
int *param_lengths;
int *param_formats;
+ Oid *param_types;
#endif
} pdo_pgsql_stmt;