PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - pdo_pgsql - pgsql_statement.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 289
Code covered: 74.4 % Executed lines: 215
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 6                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Authors: Edin Kadribasic <edink@emini.dk>                            |
      16                 :   |          Ilia Alshanestsky <ilia@prohost.org>                        |
      17                 :   |          Wez Furlong <wez@php.net>                                   |
      18                 :   +----------------------------------------------------------------------+
      19                 : */
      20                 : 
      21                 : /* $Id: pgsql_statement.c 290214 2009-11-04 19:32:27Z mbeccati $ */
      22                 : 
      23                 : #ifdef HAVE_CONFIG_H
      24                 : #include "config.h"
      25                 : #endif
      26                 : 
      27                 : #include "php.h"
      28                 : #include "php_ini.h"
      29                 : #include "ext/standard/info.h"
      30                 : #include "pdo/php_pdo.h"
      31                 : #include "pdo/php_pdo_driver.h"
      32                 : #include "php_pdo_pgsql.h"
      33                 : #include "php_pdo_pgsql_int.h"
      34                 : #if HAVE_NETINET_IN_H
      35                 : #include <netinet/in.h>
      36                 : #endif
      37                 : 
      38                 : /* from postgresql/src/include/catalog/pg_type.h */
      39                 : #define BOOLOID     16
      40                 : #define BYTEAOID    17
      41                 : #define INT8OID     20
      42                 : #define INT2OID     21
      43                 : #define INT4OID     23
      44                 : #define TEXTOID     25
      45                 : #define OIDOID      26
      46                 : 
      47                 : static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
      48             127 : {
      49             127 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
      50                 : 
      51             127 :         if (S->result) {
      52                 :                 /* free the resource */
      53             116 :                 PQclear(S->result);
      54             116 :                 S->result = NULL;
      55                 :         }
      56                 : 
      57                 : #if HAVE_PQPREPARE
      58             127 :         if (S->stmt_name) {
      59             113 :                 pdo_pgsql_db_handle *H = S->H;
      60             113 :                 char *q = NULL;
      61                 :                 PGresult *res;
      62                 : 
      63             113 :                 if (S->is_prepared) {
      64              93 :                         spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
      65              93 :                         res = PQexec(H->server, q);
      66              93 :                         efree(q);
      67              93 :                         if (res) {
      68              93 :                                 PQclear(res);
      69                 :                         }
      70                 :                 }
      71             113 :                 efree(S->stmt_name);
      72             113 :                 S->stmt_name = NULL;
      73                 :         }
      74             127 :         if (S->param_lengths) {
      75              33 :                 efree(S->param_lengths);
      76              33 :                 S->param_lengths = NULL;
      77                 :         }
      78             127 :         if (S->param_values) {
      79              33 :                 efree(S->param_values);
      80              33 :                 S->param_values = NULL;
      81                 :         }
      82             127 :         if (S->param_formats) {
      83              33 :                 efree(S->param_formats);
      84              33 :                 S->param_formats = NULL;
      85                 :         }
      86             127 :         if (S->param_types) {
      87              33 :                 efree(S->param_types);
      88              33 :                 S->param_types = NULL;
      89                 :         }
      90             127 :         if (S->query) {
      91             113 :                 efree(S->query);
      92             113 :                 S->query = NULL;
      93                 :         }
      94                 : #endif
      95                 : 
      96             127 :         if (S->cursor_name) {
      97               2 :                 pdo_pgsql_db_handle *H = S->H;
      98               2 :                 char *q = NULL;
      99                 :                 PGresult *res;
     100                 : 
     101               2 :                 spprintf(&q, 0, "CLOSE %s", S->cursor_name);
     102               2 :                 res = PQexec(H->server, q);
     103               2 :                 efree(q);
     104               2 :                 if (res) PQclear(res);
     105               2 :                 efree(S->cursor_name);
     106               2 :                 S->cursor_name = NULL;
     107                 :         }
     108                 :         
     109             127 :         if(S->cols) {
     110             102 :                 efree(S->cols);
     111             102 :                 S->cols = NULL;
     112                 :         }
     113             127 :         efree(S);
     114             127 :         stmt->driver_data = NULL;
     115             127 :         return 1;
     116                 : }
     117                 : 
     118                 : static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
     119             204 : {
     120             204 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     121             204 :         pdo_pgsql_db_handle *H = S->H;
     122                 :         ExecStatusType status;
     123                 : 
     124                 :         /* ensure that we free any previous unfetched results */
     125             204 :         if(S->result) {
     126              87 :                 PQclear(S->result);
     127              87 :                 S->result = NULL;
     128                 :         }
     129                 :         
     130             204 :         S->current_row = 0;
     131                 : 
     132             204 :         if (S->cursor_name) {
     133               3 :                 char *q = NULL;
     134                 : 
     135               3 :                 if (S->is_prepared) {
     136               1 :                         spprintf(&q, 0, "CLOSE %s", S->cursor_name);
     137               1 :                         S->result = PQexec(H->server, q);
     138               1 :                         efree(q);
     139                 :                 }
     140                 : 
     141               3 :                 spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, stmt->active_query_string);
     142               3 :                 S->result = PQexec(H->server, q);
     143               3 :                 efree(q);
     144                 : 
     145                 :                 /* check if declare failed */
     146               3 :                 status = PQresultStatus(S->result);
     147               3 :                 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
     148               0 :                         pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
     149               0 :                         return 0;
     150                 :                 }
     151                 : 
     152                 :                 /* the cursor was declared correctly */
     153               3 :                 S->is_prepared = 1;
     154                 : 
     155                 :                 /* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */
     156               3 :                 spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
     157               3 :                 S->result = PQexec(H->server, q);
     158               3 :                 efree(q);
     159                 :         } else
     160                 : #if HAVE_PQPREPARE
     161             201 :         if (S->stmt_name) {
     162                 :                 /* using a prepared statement */
     163                 : 
     164             186 :                 if (!S->is_prepared) {
     165             103 : stmt_retry:
     166                 :                         /* we deferred the prepare until now, because we didn't
     167                 :                          * know anything about the parameter types; now we do */
     168             103 :                         S->result = PQprepare(H->server, S->stmt_name, S->query, 
     169                 :                                                 stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
     170                 :                                                 S->param_types);
     171             103 :                         status = PQresultStatus(S->result);
     172             103 :                         switch (status) {
     173                 :                                 case PGRES_COMMAND_OK:
     174                 :                                 case PGRES_TUPLES_OK:
     175                 :                                         /* it worked */
     176              94 :                                         S->is_prepared = 1;
     177              94 :                                         PQclear(S->result);
     178              94 :                                         break;
     179                 :                                 default: {
     180               9 :                                         char *sqlstate = pdo_pgsql_sqlstate(S->result);
     181                 :                                         /* 42P05 means that the prepared statement already existed. this can happen if you use 
     182                 :                                          * a connection pooling software line pgpool which doesn't close the db-connection once 
     183                 :                                          * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no 
     184                 :                                          * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we 
     185                 :                                          * deallocate it and retry ONCE (thies 2005.12.15)
     186                 :                                          */
     187               9 :                                         if (!strcmp(sqlstate, "42P05")) {
     188                 :                                                 char buf[100]; /* stmt_name == "pdo_crsr_%08x" */
     189                 :                                                 PGresult *res;
     190               0 :                                                 snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
     191               0 :                                                 res = PQexec(H->server, buf);
     192               0 :                                                 if (res) {
     193               0 :                                                         PQclear(res);
     194                 :                                                 }
     195               0 :                                                 goto stmt_retry;
     196                 :                                         } else {
     197               9 :                                                 pdo_pgsql_error_stmt(stmt, status, sqlstate);
     198               9 :                                                 return 0;
     199                 :                                         }
     200                 :                                 }
     201                 :                         }
     202                 :                 }
     203             177 :                 S->result = PQexecPrepared(H->server, S->stmt_name,
     204                 :                                 stmt->bound_params ?
     205                 :                                         zend_hash_num_elements(stmt->bound_params) :
     206                 :                                         0,
     207                 :                                 (const char**)S->param_values,
     208                 :                                 S->param_lengths,
     209                 :                                 S->param_formats,
     210                 :                                 0);
     211                 :         } else
     212                 : #endif
     213                 :         {
     214              15 :                 S->result = PQexec(H->server, stmt->active_query_string);
     215                 :         }
     216             195 :         status = PQresultStatus(S->result);
     217                 : 
     218             195 :         if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
     219              14 :                 pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
     220              14 :                 return 0;
     221                 :         }
     222                 : 
     223             181 :         if (!stmt->executed && !stmt->column_count) {
     224             103 :                 stmt->column_count = (int) PQnfields(S->result);
     225             103 :                 S->cols = ecalloc(stmt->column_count, sizeof(pdo_pgsql_column));
     226                 :         }
     227                 : 
     228             181 :         if (status == PGRES_COMMAND_OK) {
     229              54 :                 stmt->row_count = (long)atoi(PQcmdTuples(S->result));
     230              54 :                 H->pgoid = PQoidValue(S->result);
     231                 :         } else {
     232             127 :                 stmt->row_count = (long)PQntuples(S->result);
     233                 :         }
     234                 : 
     235             181 :         return 1;
     236                 : }
     237                 : 
     238                 : static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
     239                 :                 enum pdo_param_event event_type TSRMLS_DC)
     240            1140 : {
     241                 : #if HAVE_PQPREPARE
     242            1140 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     243                 : 
     244            1140 :         if (S->stmt_name && param->is_param) {
     245             804 :                 switch (event_type) {
     246                 :                         case PDO_PARAM_EVT_FREE:
     247             141 :                                 if (param->driver_data) {
     248               0 :                                         efree(param->driver_data);
     249                 :                                 }
     250             141 :                                 break;
     251                 : 
     252                 :                         case PDO_PARAM_EVT_NORMALIZE:
     253                 :                                 /* decode name from $1, $2 into 0, 1 etc. */
     254             142 :                                 if (param->name) {
     255              23 :                                         if (param->name[0] == '$') {
     256               0 :                                                 param->paramno = atoi(param->name + 1);
     257                 :                                         } else {
     258                 :                                                 /* resolve parameter name to rewritten name */
     259                 :                                                 char *nameptr;
     260              45 :                                                 if (stmt->bound_param_map && SUCCESS == zend_hash_find(stmt->bound_param_map,
     261                 :                                                                 param->name, param->namelen + 1, (void**)&nameptr)) {
     262              22 :                                                         param->paramno = atoi(nameptr + 1) - 1;
     263                 :                                                 } else {
     264               1 :                                                         pdo_raise_impl_error(stmt->dbh, stmt, "HY093", param->name TSRMLS_CC);
     265               1 :                                                         return 0;
     266                 :                                                 }
     267                 :                                         }
     268                 :                                 }
     269             141 :                                 break;
     270                 : 
     271                 :                         case PDO_PARAM_EVT_ALLOC:
     272                 :                         case PDO_PARAM_EVT_EXEC_POST:
     273                 :                         case PDO_PARAM_EVT_FETCH_PRE:
     274                 :                         case PDO_PARAM_EVT_FETCH_POST:
     275                 :                                 /* work is handled by EVT_NORMALIZE */
     276             367 :                                 return 1;
     277                 : 
     278                 :                         case PDO_PARAM_EVT_EXEC_PRE:
     279             154 :                                 if (!stmt->bound_param_map) {
     280               0 :                                         return 0;
     281                 :                                 }
     282             154 :                                 if (!S->param_values) {
     283              33 :                                         S->param_values = ecalloc(
     284                 :                                                         zend_hash_num_elements(stmt->bound_param_map),
     285                 :                                                         sizeof(char*));
     286              33 :                                         S->param_lengths = ecalloc(
     287                 :                                                         zend_hash_num_elements(stmt->bound_param_map),
     288                 :                                                         sizeof(int));
     289              33 :                                         S->param_formats = ecalloc(
     290                 :                                                         zend_hash_num_elements(stmt->bound_param_map),
     291                 :                                                         sizeof(int));
     292              33 :                                         S->param_types = ecalloc(
     293                 :                                                         zend_hash_num_elements(stmt->bound_param_map),
     294                 :                                                         sizeof(Oid));
     295                 :                                 }
     296             154 :                                 if (param->paramno >= 0) {
     297             145 :                                         if (param->paramno > zend_hash_num_elements(stmt->bound_param_map)) {
     298               0 :                                                 pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
     299               0 :                                                 return 0;
     300                 :                                         }
     301                 : 
     302             145 :                                         if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
     303                 :                                                         Z_TYPE_P(param->parameter) == IS_RESOURCE) {
     304                 :                                                 php_stream *stm;
     305               5 :                                                 php_stream_from_zval_no_verify(stm, &param->parameter);
     306               5 :                                                 if (stm) {
     307               5 :                                                         if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
     308               0 :                                                                 struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
     309               0 :                                                                 pdo_pgsql_bound_param *P = param->driver_data;
     310                 : 
     311               0 :                                                                 if (P == NULL) {
     312               0 :                                                                         P = ecalloc(1, sizeof(*P));
     313               0 :                                                                         param->driver_data = P;
     314                 :                                                                 }
     315               0 :                                                                 P->oid = htonl(self->oid);
     316               0 :                                                                 S->param_values[param->paramno] = (char*)&P->oid;
     317               0 :                                                                 S->param_lengths[param->paramno] = sizeof(P->oid);
     318               0 :                                                                 S->param_formats[param->paramno] = 1;
     319               0 :                                                                 S->param_types[param->paramno] = OIDOID;
     320               0 :                                                                 return 1;
     321                 :                                                         } else {
     322                 :                                                                 int len;
     323                 :                                                                 
     324               5 :                                                                 SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
     325               5 :                                                                 Z_TYPE_P(param->parameter) = IS_STRING;
     326                 :                                                                 
     327               5 :                                                                 if ((len = php_stream_copy_to_mem(stm, &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0)) > 0) {
     328               3 :                                                                         Z_STRLEN_P(param->parameter) = len;
     329                 :                                                                 } else {
     330               2 :                                                                         ZVAL_EMPTY_STRING(param->parameter);
     331                 :                                                                 }
     332                 :                                                         }
     333                 :                                                 } else {
     334                 :                                                         /* expected a stream resource */
     335               0 :                                                         pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
     336               0 :                                                         return 0;
     337                 :                                                 }
     338                 :                                         }
     339                 : 
     340             152 :                                         if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
     341                 :                                                         Z_TYPE_P(param->parameter) == IS_NULL) {
     342               7 :                                                 S->param_values[param->paramno] = NULL;
     343               7 :                                                 S->param_lengths[param->paramno] = 0;
     344             138 :                                         } else if (Z_TYPE_P(param->parameter) == IS_BOOL) {
     345               2 :                                                 S->param_values[param->paramno] = Z_BVAL_P(param->parameter) ? "t" : "f";
     346               2 :                                                 S->param_lengths[param->paramno] = 1;
     347               2 :                                                 S->param_formats[param->paramno] = 0;
     348                 :                                         } else {
     349             136 :                                                 SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
     350             136 :                                                 convert_to_string(param->parameter);
     351             136 :                                                 S->param_values[param->paramno] = Z_STRVAL_P(param->parameter);
     352             136 :                                                 S->param_lengths[param->paramno] = Z_STRLEN_P(param->parameter);
     353             136 :                                                 S->param_formats[param->paramno] = 0;
     354                 :                                         }
     355                 : 
     356             145 :                                         if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
     357               9 :                                                 S->param_types[param->paramno] = 0;
     358               9 :                                                 S->param_formats[param->paramno] = 1;
     359                 :                                         } else {
     360             136 :                                                 S->param_types[param->paramno] = 0;
     361                 :                                         }
     362                 :                                 }
     363                 :                                 break;
     364                 :                 }
     365                 :         }
     366                 : #endif  
     367             772 :         return 1;
     368                 : }
     369                 : 
     370                 : static int pgsql_stmt_fetch(pdo_stmt_t *stmt,
     371                 :         enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
     372             284 : {
     373             284 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     374                 : 
     375             284 :         if (S->cursor_name) {
     376              15 :                 char *ori_str = NULL;
     377              15 :                 char *q = NULL;
     378                 :                 ExecStatusType status;
     379                 : 
     380              15 :                 switch (ori) {
     381              10 :                         case PDO_FETCH_ORI_NEXT:        spprintf(&ori_str, 0, "NEXT"); break;
     382               1 :                         case PDO_FETCH_ORI_PRIOR:       spprintf(&ori_str, 0, "BACKWARD"); break;
     383               1 :                         case PDO_FETCH_ORI_FIRST:       spprintf(&ori_str, 0, "FIRST"); break;
     384               1 :                         case PDO_FETCH_ORI_LAST:        spprintf(&ori_str, 0, "LAST"); break;
     385               1 :                         case PDO_FETCH_ORI_ABS:         spprintf(&ori_str, 0, "ABSOLUTE %ld", offset); break;
     386               1 :                         case PDO_FETCH_ORI_REL:         spprintf(&ori_str, 0, "RELATIVE %ld", offset); break;
     387                 :                         default:
     388               0 :                                 return 0;
     389                 :                 }
     390                 :                 
     391              15 :                 spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name);
     392              15 :                 efree(ori_str);
     393              15 :                 S->result = PQexec(S->H->server, q);
     394              15 :                 efree(q);
     395              15 :                 status = PQresultStatus(S->result);
     396                 : 
     397              15 :                 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
     398               0 :                         pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
     399               0 :                         return 0;
     400                 :                 }
     401                 : 
     402              15 :                 if (PQntuples(S->result)) {
     403              12 :                         S->current_row = 1;
     404              12 :                         return 1;
     405                 :                 } else {
     406               3 :                         return 0;
     407                 :                 }
     408                 :         } else {
     409             269 :                 if (S->current_row < stmt->row_count) {
     410             208 :                         S->current_row++;
     411             208 :                         return 1;
     412                 :                 } else {
     413              61 :                         return 0;
     414                 :                 }
     415                 :         }
     416                 : }
     417                 : 
     418                 : static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
     419             129 : {
     420             129 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     421             129 :         struct pdo_column_data *cols = stmt->columns;
     422                 :         struct pdo_bound_param_data *param;
     423                 :         
     424             129 :         if (!S->result) {
     425               0 :                 return 0;
     426                 :         }
     427                 : 
     428             129 :         cols[colno].name = estrdup(PQfname(S->result, colno));
     429             129 :         cols[colno].namelen = strlen(cols[colno].name);
     430             129 :         cols[colno].maxlen = PQfsize(S->result, colno);
     431             129 :         cols[colno].precision = PQfmod(S->result, colno);
     432             129 :         S->cols[colno].pgsql_type = PQftype(S->result, colno);
     433                 :         
     434             129 :         switch(S->cols[colno].pgsql_type) {
     435                 : 
     436                 :                 case BOOLOID:
     437               0 :                         cols[colno].param_type = PDO_PARAM_BOOL;
     438               0 :                         break;
     439                 :         
     440                 :                 case OIDOID:
     441                 :                         /* did the user bind the column as a LOB ? */
     442               0 :                         if (stmt->bound_columns && (
     443                 :                                         SUCCESS == zend_hash_index_find(stmt->bound_columns,
     444                 :                                                 colno, (void**)&param) ||
     445                 :                                         SUCCESS == zend_hash_find(stmt->bound_columns,
     446                 :                                                 cols[colno].name, cols[colno].namelen,
     447                 :                                                 (void**)&param))) {
     448               0 :                                 if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
     449               0 :                                         cols[colno].param_type = PDO_PARAM_LOB;
     450               0 :                                         break;
     451                 :                                 }
     452                 :                         }
     453               0 :                         cols[colno].param_type = PDO_PARAM_INT;
     454               0 :                         break;
     455                 : 
     456                 :                 case INT2OID:
     457                 :                 case INT4OID:
     458              41 :                         cols[colno].param_type = PDO_PARAM_INT;
     459              41 :                         break;
     460                 : 
     461                 :                 case INT8OID:
     462                 :                         if (sizeof(long)>=8) {
     463                 :                                 cols[colno].param_type = PDO_PARAM_INT;
     464                 :                         } else {
     465              12 :                                 cols[colno].param_type = PDO_PARAM_STR;
     466                 :                         }
     467              12 :                         break;
     468                 : 
     469                 :                 case BYTEAOID:
     470               2 :                         cols[colno].param_type = PDO_PARAM_LOB;
     471               2 :                         break;
     472                 : 
     473                 :                 default:
     474              74 :                         cols[colno].param_type = PDO_PARAM_STR;
     475                 :         }
     476                 : 
     477             129 :         return 1;
     478                 : }
     479                 : 
     480                 : static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees  TSRMLS_DC)
     481             403 : {
     482             403 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     483             403 :         struct pdo_column_data *cols = stmt->columns;
     484                 :         size_t tmp_len;
     485                 : 
     486             403 :         if (!S->result) {
     487               0 :                 return 0;
     488                 :         }
     489                 : 
     490                 :         /* We have already increased count by 1 in pgsql_stmt_fetch() */
     491             403 :         if (PQgetisnull(S->result, S->current_row - 1, colno)) { /* Check if we got NULL */
     492              19 :                 *ptr = NULL;
     493              19 :                 *len = 0;
     494                 :         } else {
     495             384 :                 *ptr = PQgetvalue(S->result, S->current_row - 1, colno);
     496             384 :                 *len = PQgetlength(S->result, S->current_row - 1, colno);
     497                 :                 
     498             384 :                 switch(cols[colno].param_type) {
     499                 : 
     500                 :                         case PDO_PARAM_INT:
     501             140 :                                 S->cols[colno].intval = atol(*ptr);
     502             140 :                                 *ptr = (char *) &(S->cols[colno].intval);
     503             140 :                                 *len = sizeof(long);
     504             140 :                                 break;
     505                 : 
     506                 :                         case PDO_PARAM_BOOL:
     507               0 :                                 S->cols[colno].boolval = **ptr == 't' ? 1: 0;
     508               0 :                                 *ptr = (char *) &(S->cols[colno].boolval);
     509               0 :                                 *len = sizeof(zend_bool);
     510               0 :                                 break;
     511                 :                                 
     512                 :                         case PDO_PARAM_LOB:
     513               6 :                                 if (S->cols[colno].pgsql_type == OIDOID) {
     514                 :                                         /* ooo, a real large object */
     515                 :                                         char *end_ptr;
     516               0 :                                         Oid oid = (Oid)strtoul(*ptr, &end_ptr, 10);
     517               0 :                                         int loid = lo_open(S->H->server, oid, INV_READ);
     518               0 :                                         if (loid >= 0) {
     519               0 :                                                 *ptr = (char*)pdo_pgsql_create_lob_stream(stmt->dbh, loid, oid TSRMLS_CC);
     520               0 :                                                 *len = 0;
     521               0 :                                                 return *ptr ? 1 : 0;
     522                 :                                         }
     523               0 :                                         *ptr = NULL;
     524               0 :                                         *len = 0;
     525               0 :                                         return 0;
     526                 :                                 } else {
     527               6 :                                         char *tmp_ptr = PQunescapeBytea(*ptr, &tmp_len);
     528               6 :                                         if (!tmp_ptr) {
     529                 :                                                 /* PQunescapeBytea returned an error */
     530               0 :                                                 *len = 0;
     531               0 :                                                 return 0;
     532                 :                                         }
     533               6 :                                         if (!tmp_len) {
     534                 :                                                 /* Empty string, return as empty stream */
     535               4 :                                                 *ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0);
     536               4 :                                                 PQfreemem(tmp_ptr);
     537               4 :                                                 *len = 0;
     538                 :                                         } else {
     539               2 :                                                 *ptr = estrndup(tmp_ptr, tmp_len);
     540               2 :                                                 PQfreemem(tmp_ptr);
     541               2 :                                                 *len = tmp_len;
     542               2 :                                                 *caller_frees = 1;
     543                 :                                         }
     544                 :                                 }
     545                 :                                 break;
     546                 :                         case PDO_PARAM_NULL:
     547                 :                         case PDO_PARAM_STR:
     548                 :                         case PDO_PARAM_STMT:
     549                 :                         case PDO_PARAM_INPUT_OUTPUT:
     550                 :                         case PDO_PARAM_ZVAL:
     551                 :                         default:
     552                 :                                 break;
     553                 :                 }
     554                 :         }
     555                 : 
     556             403 :         return 1;
     557                 : }
     558                 : 
     559                 : static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
     560               0 : {
     561               0 :         pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
     562                 :         PGresult *res;
     563               0 :         char *q=NULL;
     564                 :         ExecStatusType status;
     565                 :         
     566               0 :         if (!S->result) {
     567               0 :                 return FAILURE;
     568                 :         }
     569                 :         
     570               0 :         if (colno >= stmt->column_count) {
     571               0 :                 return FAILURE;
     572                 :         }
     573                 :         
     574               0 :         array_init(return_value);
     575               0 :         add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
     576                 : 
     577                 :         /* Fetch metadata from Postgres system catalogue */
     578               0 :         spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%d", S->cols[colno].pgsql_type);
     579               0 :         res = PQexec(S->H->server, q);
     580               0 :         efree(q);
     581                 :         
     582               0 :         status = PQresultStatus(res);
     583                 :         
     584               0 :         if (status != PGRES_TUPLES_OK) {
     585                 :                 /* Failed to get system catalogue, but return success
     586                 :                  * with the data we have collected so far
     587                 :                  */
     588               0 :                 goto done;
     589                 :         }
     590                 : 
     591                 :         /* We want exactly one row returned */
     592               0 :         if (1 != PQntuples(res)) {
     593               0 :                 goto done;
     594                 :         }
     595                 : 
     596               0 :         add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0), 1);
     597               0 : done:
     598               0 :         PQclear(res);           
     599               0 :         return 1;
     600                 : }
     601                 : 
     602                 : static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
     603              27 : {
     604              27 :         return 1;
     605                 : }
     606                 : 
     607                 : struct pdo_stmt_methods pgsql_stmt_methods = {
     608                 :         pgsql_stmt_dtor,
     609                 :         pgsql_stmt_execute,
     610                 :         pgsql_stmt_fetch,
     611                 :         pgsql_stmt_describe,
     612                 :         pgsql_stmt_get_col,
     613                 :         pgsql_stmt_param_hook,
     614                 :         NULL, /* set_attr */
     615                 :         NULL, /* get_attr */
     616                 :         pgsql_stmt_get_column_meta,
     617                 :         NULL,  /* next_rowset */
     618                 :         pdo_pgsql_stmt_cursor_closer
     619                 : };
     620                 : 
     621                 : /*
     622                 :  * Local variables:
     623                 :  * tab-width: 4
     624                 :  * c-basic-offset: 4
     625                 :  * End:
     626                 :  * vim600: noet sw=4 ts=4 fdm=marker
     627                 :  * vim<600: noet sw=4 ts=4
     628                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:35 +0000 (34 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.