wez Fri Jul 8 11:27:35 2005 EDT
Modified files:
/php-src/ext/pdo_pgsql config.m4 pgsql_driver.c pgsql_statement.c
php_pdo_pgsql_int.h
Log:
Add early support for native prepared statements in pgsql.
Note that some tests now fail; if we can't resolve this in time for the beta,
the prepare code should be disabled (I'll add a flag for this later today).
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/config.m4?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/pdo_pgsql/config.m4
diff -u php-src/ext/pdo_pgsql/config.m4:1.11
php-src/ext/pdo_pgsql/config.m4:1.12
--- php-src/ext/pdo_pgsql/config.m4:1.11 Thu Jul 7 09:35:39 2005
+++ php-src/ext/pdo_pgsql/config.m4 Fri Jul 8 11:27:34 2005
@@ -1,5 +1,5 @@
dnl
-dnl $Id: config.m4,v 1.11 2005/07/07 13:35:39 iliaa Exp $
+dnl $Id: config.m4,v 1.12 2005/07/08 15:27:34 wez Exp $
dnl
if test "$PHP_PDO" != "no"; then
@@ -93,6 +93,9 @@
AC_CHECK_LIB(pq, PQExecParams,AC_DEFINE(HAVE_PQEXECPARAMS,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]))
+
+ AC_CHECK_LIB(pq, PQprepare,AC_DEFINE(HAVE_PQPREPARE,1,[prepared statements]))
+
LIBS=$old_LIBS
LDFLAGS=$old_LDFLAGS
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_driver.c?r1=1.49&r2=1.50&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_driver.c
diff -u php-src/ext/pdo_pgsql/pgsql_driver.c:1.49
php-src/ext/pdo_pgsql/pgsql_driver.c:1.50
--- php-src/ext/pdo_pgsql/pgsql_driver.c:1.49 Thu Jul 7 09:35:39 2005
+++ php-src/ext/pdo_pgsql/pgsql_driver.c Fri Jul 8 11:27:34 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_driver.c,v 1.49 2005/07/07 13:35:39 iliaa Exp $ */
+/* $Id: pgsql_driver.c,v 1.50 2005/07/08 15:27:34 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -132,19 +132,77 @@
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
int scrollable;
+#if HAVE_PQPREPARE
+ PGresult *res;
+ int ret;
+ char *nsql = NULL;
+ int nsql_len = 0;
+ ExecStatusType status;
+#endif
S->H = H;
stmt->driver_data = S;
stmt->methods = &pgsql_stmt_methods;
- stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
scrollable = pdo_attr_lval(driver_options, PDO_ATTR_CURSOR,
PDO_CURSOR_FWDONLY TSRMLS_CC) == PDO_CURSOR_SCROLL;
if (scrollable) {
+ /* TODO: check how scrollable cursors related to prepared
statements */
spprintf(&S->cursor_name, 0, "pdo_pgsql_cursor_%08x", (unsigned
int) stmt);
}
+#if HAVE_PQPREPARE
+ 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);
+
+ if (ret == 1) {
+ /* query was re-written */
+ sql = nsql;
+ } else if (ret == -1) {
+ /* couldn't grok it */
+ strcpy(dbh->error_code, stmt->error_code);
+ return 0;
+ }
+
+ spprintf(&S->stmt_name, 0, "pdo_pgsql_stmt_%08x", (unsigned int)stmt);
+ res = PQprepare(H->server, S->stmt_name, sql, 0, NULL);
+ if (nsql) {
+ efree(nsql);
+ }
+ if (!res) {
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
+ return 0;
+ }
+
+ /* 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 */
+ 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;
+ break;
+
+ default:
+ /* protocol 3.0 and above; hard error */
+ pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
+ PQclear(res);
+ return 0;
+ }
+ /* fall through */
+#endif
+
+ stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
return 1;
}
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_statement.c?r1=1.24&r2=1.25&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_statement.c
diff -u php-src/ext/pdo_pgsql/pgsql_statement.c:1.24
php-src/ext/pdo_pgsql/pgsql_statement.c:1.25
--- php-src/ext/pdo_pgsql/pgsql_statement.c:1.24 Sat Jul 2 23:04:13 2005
+++ php-src/ext/pdo_pgsql/pgsql_statement.c Fri Jul 8 11:27:34 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_statement.c,v 1.24 2005/07/03 03:04:13 wez Exp $ */
+/* $Id: pgsql_statement.c,v 1.25 2005/07/08 15:27:34 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -49,6 +49,29 @@
S->result = NULL;
}
+#if HAVE_PQPREPARE
+ if (S->stmt_name) {
+ pdo_pgsql_db_handle *H = S->H;
+ char *q = NULL;
+ PGresult *res;
+
+ spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
+ res = PQexec(H->server, q);
+ efree(q);
+ if (res) PQclear(res);
+ efree(S->stmt_name);
+ S->stmt_name = NULL;
+ }
+ if (S->param_lengths) {
+ efree(S->param_lengths);
+ S->param_lengths = NULL;
+ }
+ if (S->param_values) {
+ efree(S->param_values);
+ S->param_values = NULL;
+ }
+#endif
+
if (S->cursor_name) {
pdo_pgsql_db_handle *H = S->H;
char *q = NULL;
@@ -67,6 +90,7 @@
S->cols = NULL;
}
efree(S);
+ stmt->driver_data = NULL;
return 1;
}
@@ -86,6 +110,20 @@
S->current_row = 0;
+#if HAVE_PQPREPARE
+ if (S->stmt_name) {
+ /* using a prepared statement */
+
+ 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,
+ 0);
+ } else
+#endif
if (S->cursor_name) {
char *q = NULL;
spprintf(&q, 0, "DECLARE %s CURSOR FOR %s", S->cursor_name,
stmt->active_query_string);
@@ -119,6 +157,44 @@
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data
*param,
enum pdo_param_event event_type TSRMLS_DC)
{
+ pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
+
+ if (S->stmt_name && param->is_param) {
+ switch (event_type) {
+ case PDO_PARAM_EVT_ALLOC:
+ /* decode name from $1, $2 into 0, 1 etc. */
+ if (param->name) {
+ param->paramno = atoi(param->name + 1);
+ }
+ break;
+
+ case PDO_PARAM_EVT_EXEC_PRE:
+ if (!S->param_values) {
+ S->param_values = ecalloc(
+
zend_hash_num_elements(stmt->bound_params),
+ sizeof(char*));
+ S->param_lengths = ecalloc(
+
zend_hash_num_elements(stmt->bound_params),
+ sizeof(int));
+ S->param_formats = ecalloc(
+
zend_hash_num_elements(stmt->bound_params),
+ sizeof(int));
+
+ }
+ if (PDO_PARAM_TYPE(param->param_type) ==
PDO_PARAM_NULL ||
+ Z_TYPE_P(param->parameter) ==
IS_NULL) {
+ S->param_values[param->paramno] = NULL;
+ S->param_lengths[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] = 1;
+ }
+
+ break;
+ }
+ }
return 1;
}
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h
diff -u php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.11
php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.12
--- php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.11 Fri Jul 1 18:30:55 2005
+++ php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h Fri Jul 8 11:27:34 2005
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2004 The PHP Group |
+ | Copyright (c) 1997-2005 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_pgsql_int.h,v 1.11 2005/07/01 22:30:55 edink Exp $ */
+/* $Id: php_pdo_pgsql_int.h,v 1.12 2005/07/08 15:27:34 wez Exp $ */
#ifndef PHP_PDO_PGSQL_INT_H
#define PHP_PDO_PGSQL_INT_H
@@ -55,6 +55,12 @@
int current_row;
pdo_pgsql_column *cols;
char *cursor_name;
+#if HAVE_PQPREPARE
+ char *stmt_name;
+ char **param_values;
+ int *param_lengths;
+ int *param_formats;
+#endif
} pdo_pgsql_stmt;
typedef struct {
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php