diff options
-rw-r--r-- | ext/pdo_pgsql/package.xml | 2 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 43 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 45 | ||||
-rw-r--r-- | ext/pdo_pgsql/php_pdo_pgsql_int.h | 2 |
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; |