Back to index

php5  5.3.10
pgsql_statement.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Authors: Edin Kadribasic <edink@emini.dk>                            |
00016   |          Ilia Alshanestsky <ilia@prohost.org>                        |
00017   |          Wez Furlong <wez@php.net>                                   |
00018   +----------------------------------------------------------------------+
00019 */
00020 
00021 /* $Id: pgsql_statement.c 321634 2012-01-01 13:15:04Z felipe $ */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include "php.h"
00028 #include "php_ini.h"
00029 #include "ext/standard/info.h"
00030 #include "pdo/php_pdo.h"
00031 #include "pdo/php_pdo_driver.h"
00032 #include "php_pdo_pgsql.h"
00033 #include "php_pdo_pgsql_int.h"
00034 #if HAVE_NETINET_IN_H
00035 #include <netinet/in.h>
00036 #endif
00037 
00038 /* from postgresql/src/include/catalog/pg_type.h */
00039 #define BOOLOID     16
00040 #define BYTEAOID    17
00041 #define INT8OID     20
00042 #define INT2OID     21
00043 #define INT4OID     23
00044 #define TEXTOID     25
00045 #define OIDOID      26
00046 
00047 static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
00048 {
00049        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00050 
00051        if (S->result) {
00052               /* free the resource */
00053               PQclear(S->result);
00054               S->result = NULL;
00055        }
00056 
00057 #if HAVE_PQPREPARE
00058        if (S->stmt_name) {
00059               pdo_pgsql_db_handle *H = S->H;
00060               char *q = NULL;
00061               PGresult *res;
00062 
00063               if (S->is_prepared) {
00064                      spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
00065                      res = PQexec(H->server, q);
00066                      efree(q);
00067                      if (res) {
00068                             PQclear(res);
00069                      }
00070               }
00071               efree(S->stmt_name);
00072               S->stmt_name = NULL;
00073        }
00074        if (S->param_lengths) {
00075               efree(S->param_lengths);
00076               S->param_lengths = NULL;
00077        }
00078        if (S->param_values) {
00079               efree(S->param_values);
00080               S->param_values = NULL;
00081        }
00082        if (S->param_formats) {
00083               efree(S->param_formats);
00084               S->param_formats = NULL;
00085        }
00086        if (S->param_types) {
00087               efree(S->param_types);
00088               S->param_types = NULL;
00089        }
00090        if (S->query) {
00091               efree(S->query);
00092               S->query = NULL;
00093        }
00094 #endif
00095 
00096        if (S->cursor_name) {
00097               pdo_pgsql_db_handle *H = S->H;
00098               char *q = NULL;
00099               PGresult *res;
00100 
00101               spprintf(&q, 0, "CLOSE %s", S->cursor_name);
00102               res = PQexec(H->server, q);
00103               efree(q);
00104               if (res) PQclear(res);
00105               efree(S->cursor_name);
00106               S->cursor_name = NULL;
00107        }
00108        
00109        if(S->cols) {
00110               efree(S->cols);
00111               S->cols = NULL;
00112        }
00113        efree(S);
00114        stmt->driver_data = NULL;
00115        return 1;
00116 }
00117 
00118 static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
00119 {
00120        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00121        pdo_pgsql_db_handle *H = S->H;
00122        ExecStatusType status;
00123 
00124        /* ensure that we free any previous unfetched results */
00125        if(S->result) {
00126               PQclear(S->result);
00127               S->result = NULL;
00128        }
00129        
00130        S->current_row = 0;
00131 
00132        if (S->cursor_name) {
00133               char *q = NULL;
00134 
00135               if (S->is_prepared) {
00136                      spprintf(&q, 0, "CLOSE %s", S->cursor_name);
00137                      S->result = PQexec(H->server, q);
00138                      efree(q);
00139               }
00140 
00141               spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, stmt->active_query_string);
00142               S->result = PQexec(H->server, q);
00143               efree(q);
00144 
00145               /* check if declare failed */
00146               status = PQresultStatus(S->result);
00147               if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
00148                      pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
00149                      return 0;
00150               }
00151 
00152               /* the cursor was declared correctly */
00153               S->is_prepared = 1;
00154 
00155               /* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */
00156               spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
00157               S->result = PQexec(H->server, q);
00158               efree(q);
00159        } else
00160 #if HAVE_PQPREPARE
00161        if (S->stmt_name) {
00162               /* using a prepared statement */
00163 
00164               if (!S->is_prepared) {
00165 stmt_retry:
00166                      /* we deferred the prepare until now, because we didn't
00167                       * know anything about the parameter types; now we do */
00168                      S->result = PQprepare(H->server, S->stmt_name, S->query, 
00169                                           stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
00170                                           S->param_types);
00171                      status = PQresultStatus(S->result);
00172                      switch (status) {
00173                             case PGRES_COMMAND_OK:
00174                             case PGRES_TUPLES_OK:
00175                                    /* it worked */
00176                                    S->is_prepared = 1;
00177                                    PQclear(S->result);
00178                                    break;
00179                             default: {
00180                                    char *sqlstate = pdo_pgsql_sqlstate(S->result);
00181                                    /* 42P05 means that the prepared statement already existed. this can happen if you use 
00182                                     * a connection pooling software line pgpool which doesn't close the db-connection once 
00183                                     * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no 
00184                                     * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we 
00185                                     * deallocate it and retry ONCE (thies 2005.12.15)
00186                                     */
00187                                    if (sqlstate && !strcmp(sqlstate, "42P05")) {
00188                                           char buf[100]; /* stmt_name == "pdo_crsr_%08x" */
00189                                           PGresult *res;
00190                                           snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
00191                                           res = PQexec(H->server, buf);
00192                                           if (res) {
00193                                                  PQclear(res);
00194                                           }
00195                                           goto stmt_retry;
00196                                    } else {
00197                                           pdo_pgsql_error_stmt(stmt, status, sqlstate);
00198                                           return 0;
00199                                    }
00200                             }
00201                      }
00202               }
00203               S->result = PQexecPrepared(H->server, S->stmt_name,
00204                             stmt->bound_params ?
00205                                    zend_hash_num_elements(stmt->bound_params) :
00206                                    0,
00207                             (const char**)S->param_values,
00208                             S->param_lengths,
00209                             S->param_formats,
00210                             0);
00211        } else
00212 #endif
00213        {
00214               S->result = PQexec(H->server, stmt->active_query_string);
00215        }
00216        status = PQresultStatus(S->result);
00217 
00218        if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
00219               pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
00220               return 0;
00221        }
00222 
00223        if (!stmt->executed && !stmt->column_count) {
00224               stmt->column_count = (int) PQnfields(S->result);
00225               S->cols = ecalloc(stmt->column_count, sizeof(pdo_pgsql_column));
00226        }
00227 
00228        if (status == PGRES_COMMAND_OK) {
00229               stmt->row_count = (long)atoi(PQcmdTuples(S->result));
00230               H->pgoid = PQoidValue(S->result);
00231        } else {
00232               stmt->row_count = (long)PQntuples(S->result);
00233        }
00234 
00235        return 1;
00236 }
00237 
00238 static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
00239               enum pdo_param_event event_type TSRMLS_DC)
00240 {
00241 #if HAVE_PQPREPARE
00242        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00243 
00244        if (S->stmt_name && param->is_param) {
00245               switch (event_type) {
00246                      case PDO_PARAM_EVT_FREE:
00247                             if (param->driver_data) {
00248                                    efree(param->driver_data);
00249                             }
00250                             break;
00251 
00252                      case PDO_PARAM_EVT_NORMALIZE:
00253                             /* decode name from $1, $2 into 0, 1 etc. */
00254                             if (param->name) {
00255                                    if (param->name[0] == '$') {
00256                                           param->paramno = atoi(param->name + 1);
00257                                    } else {
00258                                           /* resolve parameter name to rewritten name */
00259                                           char *nameptr;
00260                                           if (stmt->bound_param_map && SUCCESS == zend_hash_find(stmt->bound_param_map,
00261                                                         param->name, param->namelen + 1, (void**)&nameptr)) {
00262                                                  param->paramno = atoi(nameptr + 1) - 1;
00263                                           } else {
00264                                                  pdo_raise_impl_error(stmt->dbh, stmt, "HY093", param->name TSRMLS_CC);
00265                                                  return 0;
00266                                           }
00267                                    }
00268                             }
00269                             break;
00270 
00271                      case PDO_PARAM_EVT_ALLOC:
00272                      case PDO_PARAM_EVT_EXEC_POST:
00273                      case PDO_PARAM_EVT_FETCH_PRE:
00274                      case PDO_PARAM_EVT_FETCH_POST:
00275                             /* work is handled by EVT_NORMALIZE */
00276                             return 1;
00277 
00278                      case PDO_PARAM_EVT_EXEC_PRE:
00279                             if (!stmt->bound_param_map) {
00280                                    return 0;
00281                             }
00282                             if (!S->param_values) {
00283                                    S->param_values = ecalloc(
00284                                                  zend_hash_num_elements(stmt->bound_param_map),
00285                                                  sizeof(char*));
00286                                    S->param_lengths = ecalloc(
00287                                                  zend_hash_num_elements(stmt->bound_param_map),
00288                                                  sizeof(int));
00289                                    S->param_formats = ecalloc(
00290                                                  zend_hash_num_elements(stmt->bound_param_map),
00291                                                  sizeof(int));
00292                                    S->param_types = ecalloc(
00293                                                  zend_hash_num_elements(stmt->bound_param_map),
00294                                                  sizeof(Oid));
00295                             }
00296                             if (param->paramno >= 0) {
00297                                    if (param->paramno > zend_hash_num_elements(stmt->bound_param_map)) {
00298                                           pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
00299                                           return 0;
00300                                    }
00301 
00302                                    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
00303                                                  Z_TYPE_P(param->parameter) == IS_RESOURCE) {
00304                                           php_stream *stm;
00305                                           php_stream_from_zval_no_verify(stm, &param->parameter);
00306                                           if (stm) {
00307                                                  if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
00308                                                         struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
00309                                                         pdo_pgsql_bound_param *P = param->driver_data;
00310 
00311                                                         if (P == NULL) {
00312                                                                P = ecalloc(1, sizeof(*P));
00313                                                                param->driver_data = P;
00314                                                         }
00315                                                         P->oid = htonl(self->oid);
00316                                                         S->param_values[param->paramno] = (char*)&P->oid;
00317                                                         S->param_lengths[param->paramno] = sizeof(P->oid);
00318                                                         S->param_formats[param->paramno] = 1;
00319                                                         S->param_types[param->paramno] = OIDOID;
00320                                                         return 1;
00321                                                  } else {
00322                                                         int len;
00323                                                         
00324                                                         SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
00325                                                         Z_TYPE_P(param->parameter) = IS_STRING;
00326                                                         
00327                                                         if ((len = php_stream_copy_to_mem(stm, &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0)) > 0) {
00328                                                                Z_STRLEN_P(param->parameter) = len;
00329                                                         } else {
00330                                                                ZVAL_EMPTY_STRING(param->parameter);
00331                                                         }
00332                                                  }
00333                                           } else {
00334                                                  /* expected a stream resource */
00335                                                  pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
00336                                                  return 0;
00337                                           }
00338                                    }
00339 
00340                                    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
00341                                                  Z_TYPE_P(param->parameter) == IS_NULL) {
00342                                           S->param_values[param->paramno] = NULL;
00343                                           S->param_lengths[param->paramno] = 0;
00344                                    } else if (Z_TYPE_P(param->parameter) == IS_BOOL) {
00345                                           S->param_values[param->paramno] = Z_BVAL_P(param->parameter) ? "t" : "f";
00346                                           S->param_lengths[param->paramno] = 1;
00347                                           S->param_formats[param->paramno] = 0;
00348                                    } else {
00349                                           SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
00350                                           convert_to_string(param->parameter);
00351                                           S->param_values[param->paramno] = Z_STRVAL_P(param->parameter);
00352                                           S->param_lengths[param->paramno] = Z_STRLEN_P(param->parameter);
00353                                           S->param_formats[param->paramno] = 0;
00354                                    }
00355 
00356                                    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
00357                                           S->param_types[param->paramno] = 0;
00358                                           S->param_formats[param->paramno] = 1;
00359                                    } else {
00360                                           S->param_types[param->paramno] = 0;
00361                                    }
00362                             }
00363                             break;
00364               }
00365        }
00366 #endif 
00367        return 1;
00368 }
00369 
00370 static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
00371        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
00372 {
00373        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00374 
00375        if (S->cursor_name) {
00376               char *ori_str = NULL;
00377               char *q = NULL;
00378               ExecStatusType status;
00379 
00380               switch (ori) {
00381                      case PDO_FETCH_ORI_NEXT:    spprintf(&ori_str, 0, "NEXT"); break;
00382                      case PDO_FETCH_ORI_PRIOR:   spprintf(&ori_str, 0, "BACKWARD"); break;
00383                      case PDO_FETCH_ORI_FIRST:   spprintf(&ori_str, 0, "FIRST"); break;
00384                      case PDO_FETCH_ORI_LAST:    spprintf(&ori_str, 0, "LAST"); break;
00385                      case PDO_FETCH_ORI_ABS:            spprintf(&ori_str, 0, "ABSOLUTE %ld", offset); break;
00386                      case PDO_FETCH_ORI_REL:            spprintf(&ori_str, 0, "RELATIVE %ld", offset); break;
00387                      default:
00388                             return 0;
00389               }
00390               
00391               spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
00392               efree(ori_str);
00393               S->result = PQexec(S->H->server, q);
00394               efree(q);
00395               status = PQresultStatus(S->result);
00396 
00397               if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
00398                      pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
00399                      return 0;
00400               }
00401 
00402               if (PQntuples(S->result)) {
00403                      S->current_row = 1;
00404                      return 1;
00405               } else {
00406                      return 0;
00407               }
00408        } else {
00409               if (S->current_row < stmt->row_count) {
00410                      S->current_row++;
00411                      return 1;
00412               } else {
00413                      return 0;
00414               }
00415        }
00416 }
00417 
00418 static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
00419 {
00420        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00421        struct pdo_column_data *cols = stmt->columns;
00422        struct pdo_bound_param_data *param;
00423        
00424        if (!S->result) {
00425               return 0;
00426        }
00427 
00428        cols[colno].name = estrdup(PQfname(S->result, colno));
00429        cols[colno].namelen = strlen(cols[colno].name);
00430        cols[colno].maxlen = PQfsize(S->result, colno);
00431        cols[colno].precision = PQfmod(S->result, colno);
00432        S->cols[colno].pgsql_type = PQftype(S->result, colno);
00433        
00434        switch(S->cols[colno].pgsql_type) {
00435 
00436               case BOOLOID:
00437                      cols[colno].param_type = PDO_PARAM_BOOL;
00438                      break;
00439        
00440               case OIDOID:
00441                      /* did the user bind the column as a LOB ? */
00442                      if (stmt->bound_columns && (
00443                                    SUCCESS == zend_hash_index_find(stmt->bound_columns,
00444                                           colno, (void**)&param) ||
00445                                    SUCCESS == zend_hash_find(stmt->bound_columns,
00446                                           cols[colno].name, cols[colno].namelen,
00447                                           (void**)&param))) {
00448                             if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
00449                                    cols[colno].param_type = PDO_PARAM_LOB;
00450                                    break;
00451                             }
00452                      }
00453                      cols[colno].param_type = PDO_PARAM_INT;
00454                      break;
00455 
00456               case INT2OID:
00457               case INT4OID:
00458                      cols[colno].param_type = PDO_PARAM_INT;
00459                      break;
00460 
00461               case INT8OID:
00462                      if (sizeof(long)>=8) {
00463                             cols[colno].param_type = PDO_PARAM_INT;
00464                      } else {
00465                             cols[colno].param_type = PDO_PARAM_STR;
00466                      }
00467                      break;
00468 
00469               case BYTEAOID:
00470                      cols[colno].param_type = PDO_PARAM_LOB;
00471                      break;
00472 
00473               default:
00474                      cols[colno].param_type = PDO_PARAM_STR;
00475        }
00476 
00477        return 1;
00478 }
00479 
00480 static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees  TSRMLS_DC)
00481 {
00482        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00483        struct pdo_column_data *cols = stmt->columns;
00484        size_t tmp_len;
00485 
00486        if (!S->result) {
00487               return 0;
00488        }
00489 
00490        /* We have already increased count by 1 in pgsql_stmt_fetch() */
00491        if (PQgetisnull(S->result, S->current_row - 1, colno)) { /* Check if we got NULL */
00492               *ptr = NULL;
00493               *len = 0;
00494        } else {
00495               *ptr = PQgetvalue(S->result, S->current_row - 1, colno);
00496               *len = PQgetlength(S->result, S->current_row - 1, colno);
00497               
00498               switch(cols[colno].param_type) {
00499 
00500                      case PDO_PARAM_INT:
00501                             S->cols[colno].intval = atol(*ptr);
00502                             *ptr = (char *) &(S->cols[colno].intval);
00503                             *len = sizeof(long);
00504                             break;
00505 
00506                      case PDO_PARAM_BOOL:
00507                             S->cols[colno].boolval = **ptr == 't' ? 1: 0;
00508                             *ptr = (char *) &(S->cols[colno].boolval);
00509                             *len = sizeof(zend_bool);
00510                             break;
00511                             
00512                      case PDO_PARAM_LOB:
00513                             if (S->cols[colno].pgsql_type == OIDOID) {
00514                                    /* ooo, a real large object */
00515                                    char *end_ptr;
00516                                    Oid oid = (Oid)strtoul(*ptr, &end_ptr, 10);
00517                                    int loid = lo_open(S->H->server, oid, INV_READ);
00518                                    if (loid >= 0) {
00519                                           *ptr = (char*)pdo_pgsql_create_lob_stream(stmt->dbh, loid, oid TSRMLS_CC);
00520                                           *len = 0;
00521                                           return *ptr ? 1 : 0;
00522                                    }
00523                                    *ptr = NULL;
00524                                    *len = 0;
00525                                    return 0;
00526                             } else {
00527                                    char *tmp_ptr = PQunescapeBytea(*ptr, &tmp_len);
00528                                    if (!tmp_ptr) {
00529                                           /* PQunescapeBytea returned an error */
00530                                           *len = 0;
00531                                           return 0;
00532                                    }
00533                                    if (!tmp_len) {
00534                                           /* Empty string, return as empty stream */
00535                                           *ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0);
00536                                           PQfreemem(tmp_ptr);
00537                                           *len = 0;
00538                                    } else {
00539                                           *ptr = estrndup(tmp_ptr, tmp_len);
00540                                           PQfreemem(tmp_ptr);
00541                                           *len = tmp_len;
00542                                           *caller_frees = 1;
00543                                    }
00544                             }
00545                             break;
00546                      case PDO_PARAM_NULL:
00547                      case PDO_PARAM_STR:
00548                      case PDO_PARAM_STMT:
00549                      case PDO_PARAM_INPUT_OUTPUT:
00550                      case PDO_PARAM_ZVAL:
00551                      default:
00552                             break;
00553               }
00554        }
00555 
00556        return 1;
00557 }
00558 
00559 static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
00560 {
00561        pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
00562        PGresult *res;
00563        char *q=NULL;
00564        ExecStatusType status;
00565        
00566        if (!S->result) {
00567               return FAILURE;
00568        }
00569        
00570        if (colno >= stmt->column_count) {
00571               return FAILURE;
00572        }
00573        
00574        array_init(return_value);
00575        add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
00576 
00577        /* Fetch metadata from Postgres system catalogue */
00578        spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%d", S->cols[colno].pgsql_type);
00579        res = PQexec(S->H->server, q);
00580        efree(q);
00581        
00582        status = PQresultStatus(res);
00583        
00584        if (status != PGRES_TUPLES_OK) {
00585               /* Failed to get system catalogue, but return success
00586                * with the data we have collected so far
00587                */
00588               goto done;
00589        }
00590 
00591        /* We want exactly one row returned */
00592        if (1 != PQntuples(res)) {
00593               goto done;
00594        }
00595 
00596        add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0), 1);
00597 done:
00598        PQclear(res);        
00599        return 1;
00600 }
00601 
00602 static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
00603 {
00604        return 1;
00605 }
00606 
00607 struct pdo_stmt_methods pgsql_stmt_methods = {
00608        pgsql_stmt_dtor,
00609        pgsql_stmt_execute,
00610        pgsql_stmt_fetch,
00611        pgsql_stmt_describe,
00612        pgsql_stmt_get_col,
00613        pgsql_stmt_param_hook,
00614        NULL, /* set_attr */
00615        NULL, /* get_attr */
00616        pgsql_stmt_get_column_meta,
00617        NULL,  /* next_rowset */
00618        pdo_pgsql_stmt_cursor_closer
00619 };
00620 
00621 /*
00622  * Local variables:
00623  * tab-width: 4
00624  * c-basic-offset: 4
00625  * End:
00626  * vim600: noet sw=4 ts=4 fdm=marker
00627  * vim<600: noet sw=4 ts=4
00628  */