Hi. 

I developed some patches for PDO/Postgresql driver in order to add some useful 
methods that were available in the original pgsql driver.

The attached patches apply on 5.3.2 and svn 5.3.x.
If needed, i have patches also for 5.2.x.

Please comment and tell me improvements or tips.

Thank you in advance,

Denis Gasparin

Documentation of the added methods follows:

pgsqlIsInTransaction()

    It uses the native Postgresql functions to check transaction status.
    It returns one of the following status codes:
       * PDO::PGSQL_TRANSACTION_IDLE: connection in idle status
       * PDO::PGSQL_TRANSACTION_ACTIVE: connection is executing a command
       * PDO::PGSQL_TRANSACTION_INTRANS: connection is idle in a valid 
transaction block
       * PDO::PGSQL_TRANSACTION_INERROR: connection is idle, in a failed 
transaction block
       * PDO::PGSQL_TRANSACTION_UNKNOWN: connection is in a bad status



pgsqlCopyFromArray($table,Array $data,$delimiter,$null, Array $fields)

    It uses the native Postgresql copy construct to append $data to $table.
    It returns boolean.
    Parameters:
       * (mandatory) $table: table to append data to
       * (mandatory) $data: Array of rows with data in table field order
                           (or as specified in the $fields array). Fields must 
be separated by $delimiter or by
                           postgresql standard \t)
       * $delimiter: alternative delimiter to use in place of the standard 
postgres delimiter ("\t")
       * $null: alternative string to use as null value. Default is "\N"
       * $fields: array with table fields that are specified in $data parameter



pgsqlCopyFromFile($table,$filename,$delimiter,$null,$fields)
 
    It uses the native Postgresql copy construct to append $filename contents 
to $table.
    It returns boolean.
    Parameters:
       * (mandatory) $table: table to append data to.
       * (mandatory) $filename: file with contents to append to $table. See 
Postgresql documentation for the format.
       * $delimiter: alternative delimiter to use in place of the standard 
postgres delimiter ("\t")
       * $null: alternative string to use as null value. Default is "\N"
       * $fields: array with table fields that are specified in $filename file

pgsqlCopyToArray($table,$delimiter,$null,$fields)

    It uses the native Postgresql copy construct to retrieve $table contents 
and store them to an array.
    It returns an array of rows or false in case of problems.
    The format of the rows into the array is indicated in the $delimiter, $null 
and $fields parameters.
    Parameters:
       * (mandatory) $table: table to retrieve data from.
       * $delimiter: alternative delimiter to use in place of the standard 
postgres delimiter ("\t")
       * $null: alternative string to use as null value. Default is "\N"
       * $fields: array with table fields to include in the row of the array.


pgsqlCopyToFile($table,$filename,$delimiter,$null,$fields)


    It uses the native Postgresql copy construct to retrieve $table contents 
and store them into a file.
    It returns boolean.
    The format of the rows stored into the file is indicated in the $delimiter, 
$null and $fields parameters.
    Parameters:
       * (mandatory) $table: table to retrieve data from.
       * (mandatory) $filename: file where to store the contents of the table
       * $delimiter: alternative delimiter to use in place of the standard 
postgres delimiter ("\t")
       * $null: alternative string to use as null value. Default is "\N"
       * $fields: array with table fields to include in the row of the array.
31a32
> #include "ext/standard/php_smart_str.h"
81a83,92
> 
> static void php_pdo_pgsql_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
> 	char * str = (char *)rsrc->ptr;
> 	pefree(str,1);
> }
> 
> 
> static int le_pdo_pgsql_descriptor;
> 
> 
88a100
> 	le_pdo_pgsql_descriptor = zend_register_list_destructors_ex(NULL, php_pdo_pgsql_list_dtor, PHP_PDO_PGSQL_RES_NAME, module_number);
89a102,106
>     REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_IDLE", (long)PGSQL_TRANSACTION_IDLE);
>     REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_ACTIVE", (long)PGSQL_TRANSACTION_ACTIVE);
>     REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (long)PGSQL_TRANSACTION_INTRANS);
>     REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (long)PGSQL_TRANSACTION_INERROR);
>     REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (long)PGSQL_TRANSACTION_UNKNOWN);
136a154,238
> 
> int _pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
> {
> 	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
> 	PGresult *result;
> 	char *q=NULL;
>  	ExecStatusType status;
>     smart_str str = {0};
>     zend_rsrc_list_entry *field_type;
>     char *ret=NULL;
> 	zval *resource_val=NULL;
> 
> 	HashTable *list = &EG(persistent_list);
> 
> 	if (!S->result) {
> 		return FAILURE;
> 	}
> 	
> 	if (colno >= stmt->column_count) {
> 		return FAILURE;
> 	}
> 	
> 	array_init(return_value);
> 	add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
> 
>     /* try to lookup the type in the resource list */
>     smart_str_appends(&str, "pgsql_oid_");
>     smart_str_append_unsigned(&str,  S->cols[colno].pgsql_type);
>     smart_str_0(&str);
> 
>     if (zend_hash_find(list,str.c,str.len+1,(void **) &field_type)==SUCCESS) {
>         ret = estrdup((char *)field_type->ptr);
>     } else { /* hash all oid's */
>         int i,num_rows;
>         int oid_offset,name_offset;
>         char *tmp_oid, *end_ptr, *tmp_name,*type_name;
>         zend_rsrc_list_entry new_oid_entry;
> 
>         if ((result = PQexec(S->H->server,"select oid,typname from pg_type")) == NULL || PQresultStatus(result) != PGRES_TUPLES_OK) {
>             if (result) {
>                 PQclear(result);
>             }
>             smart_str_free(&str);
>             return 0;
>         }
>         num_rows = PQntuples(result);
>         oid_offset = PQfnumber(result,"oid");
>         name_offset = PQfnumber(result,"typname");
> 
>         for (i=0; i<num_rows; i++) {
>             if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) {
>                 continue;
>             }
> 
>             str.len = 0;
>             smart_str_appends(&str, "pgsql_oid_");
>             smart_str_appends(&str, tmp_oid);
>             smart_str_0(&str);
> 
>             if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) {
>                 continue;
>             }
>             type_name = pemalloc(strlen(tmp_name)+1,1);
>             memcpy(type_name,tmp_name,strlen(tmp_name)+1);
>             //type_name = pestrdup(tmp_name);
>             ZEND_REGISTER_RESOURCE(resource_val, type_name,le_pdo_pgsql_descriptor);
> 		
>             new_oid_entry.type = le_pdo_pgsql_descriptor;
>             new_oid_entry.ptr = type_name;
>             zend_hash_update(list,str.c,str.len+1,(void *) &new_oid_entry, sizeof(zend_rsrc_list_entry), NULL);
>             if (!ret && strtoul(tmp_oid, &end_ptr, 10)==S->cols[colno].pgsql_type) {
>                 ret = estrdup(tmp_name);
>             }
>         }
>         PQclear(result);
>     }
> 
>     smart_str_free(&str);
> 
> 	add_assoc_string(return_value, "native_type", ret, 1);	
> 	return 1;
> 
> }
> 
> 
31a32
> #include "ext/standard/file.h"
498a500,1003
> /* {{{ proto string PDO::pgsqlIsInTransaction()
>    Returns the status of a transaction according to PDO::PGSQL_TRANSACTION_* constants */
> static PHP_METHOD(PDO, pgsqlIsInTransaction)
> {
> 	pdo_dbh_t *dbh;
> 	pdo_pgsql_db_handle *H;
> 
> 	dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
> 	PDO_CONSTRUCT_CHECK;
> 
> 	H = (pdo_pgsql_db_handle *)dbh->driver_data;
> 
> 	RETURN_LONG(PQtransactionStatus(H->server));
> }
> /* }}} */
> 
> /* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
>    Returns true if the copy worked fine or false if error */
> static PHP_METHOD(PDO, pgsqlCopyFromArray)
> {
>     pdo_dbh_t *dbh;
>     pdo_pgsql_db_handle *H;
> 
>     zval *pg_rows;
>     zval **tmp;
>     char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
>     int  table_name_len, pg_delim_len, pg_null_as_len, pg_fields_len;
>     char *query, *fields;
>     HashPosition pos;
>     int id = -1;
>     PGresult *pgsql_result;
>     ExecStatusType status;
> 
>     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/a|sss",
>                               &table_name, &table_name_len, &pg_rows,
>                               &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
>         return;
>     }
> 
>     if (!pg_delim) {
>         pg_delim = "\t";
>     }
>     if (pg_null_as_len<=0) {
>         pg_null_as = safe_estrdup("\\\\N");
>     }
> 
>     if(pg_fields_len>0) {
>         spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, *pg_delim, pg_null_as);
>     }
>     else {
>         spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, *pg_delim, pg_null_as);
>     }
> 
>     // Obtain db Handler
>     dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
>     PDO_CONSTRUCT_CHECK;
> 
>     H = (pdo_pgsql_db_handle *)dbh->driver_data;
>     // H->server is the db handle for libPQ
> 
> 
>     while ((pgsql_result = PQgetResult(H->server))) {
>         PQclear(pgsql_result);
>     }
>     pgsql_result = PQexec(H->server, query);
> 
>     if (pg_null_as_len<=0) {
>         efree(pg_null_as);
>     }
>     efree(query);
> 
>     if (pgsql_result) {
>         status = PQresultStatus(pgsql_result);
>     } else {
>         status = (ExecStatusType) PQstatus(H->server);
>     }
> 
>     switch (status) {
>         case PGRES_COPY_IN:
>             if (pgsql_result) {
>                 int command_failed = 0;
>                 PQclear(pgsql_result);
>                 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pg_rows), &pos);
>                 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pg_rows), (void **) &tmp, &pos) == SUCCESS) {
>                     convert_to_string_ex(tmp);
>                     query = (char *)emalloc(Z_STRLEN_PP(tmp) + 2);
>                     strlcpy(query, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) + 2);
>                     if(Z_STRLEN_PP(tmp) > 0 && *(query + Z_STRLEN_PP(tmp) - 1) != '\n') {
>                         strlcat(query, "\n", Z_STRLEN_PP(tmp) + 2);
>                     }
>                     if (PQputCopyData(H->server, query, strlen(query)) != 1) {
>                         efree(query);
>                         pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed");
>                         RETURN_FALSE;
>                     }
>                     efree(query);
>                     zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos);
>                 }
>                 if (PQputCopyEnd(H->server, NULL) != 1) {
>                     pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed");
>                     RETURN_FALSE;
>                 }
>                 while ((pgsql_result = PQgetResult(H->server))) {
>                     if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
>                         pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
>                         command_failed = 1;
>                     }
>                     PQclear(pgsql_result);
>                 }
>                 if (command_failed) {
>                     RETURN_FALSE;
>                 }
>             } else {
>                 PQclear(pgsql_result);
>                 RETURN_FALSE;
>             }
>             RETURN_TRUE;
>             break;
>         default:
>             PQclear(pgsql_result);
>             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
>             RETURN_FALSE;
>             break;
>     }
> }
> /* }}} */
> 
> /* {{{ proto string PDO::pgsqlCopyFromFile(string $table_name , string $filename [, string $delimiter [, string $null_as ] [, string $fields])
>    Returns true if the copy worked fine or false if error */
> static PHP_METHOD(PDO, pgsqlCopyFromFile)
> {
>     pdo_dbh_t *dbh;
>     pdo_pgsql_db_handle *H;
> 
>     char *table_name, *filename, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
>     int  table_name_len, filename_len, pg_delim_len, pg_null_as_len, pg_fields_len;
>     char *query, *fields;
>     PGresult *pgsql_result;
>     ExecStatusType status;
>     zval *zcontext = NULL;
> 
>     php_stream_context *context = NULL;
> 
> 
>     size_t line_len = 0;
>     php_stream *stream;
>     char *buf = NULL;
> 
>     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|sss",
>                               &table_name, &table_name_len, &filename, &filename_len,
>                               &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
>         return;
>     }
> 
>     if (!pg_delim) {
>         pg_delim = "\t";
>     }
>     if (pg_null_as_len<=0) {
>         pg_null_as = safe_estrdup("\\\\N");
>     }
> 
>     if(pg_fields_len>0) {
>         spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, *pg_delim, pg_null_as);
>     }
>     else {
>         spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, *pg_delim, pg_null_as);
>     }
> 
>     // Obtain db Handler
>     dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
>     PDO_CONSTRUCT_CHECK;
> 
>     H = (pdo_pgsql_db_handle *)dbh->driver_data;
>     // H->server is the db handle for libPQ
> 
> 
>     // Check filename
>     context = php_stream_context_from_zval(zcontext, 0);
> 
>     stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
>     if (!stream) {
> 		pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file");
>         RETURN_FALSE;
>     }
> 
> 
> 
>     while ((pgsql_result = PQgetResult(H->server))) {
>         PQclear(pgsql_result);
>     }
>     pgsql_result = PQexec(H->server, query);
> 
>     if (pg_null_as_len<=0) {
>         efree(pg_null_as);
>     }
>     efree(query);
> 
>     if (pgsql_result) {
>         status = PQresultStatus(pgsql_result);
>     } else {
>         status = (ExecStatusType) PQstatus(H->server);
>     }
> 
>     switch (status) {
>         case PGRES_COPY_IN:
>             if (pgsql_result) {
>                 int command_failed = 0;
>                 PQclear(pgsql_result);
>                 buf = php_stream_get_line(stream, NULL, 0, &line_len);
> 				while(buf != NULL) {
>                     if (PQputCopyData(H->server, buf, strlen(buf)) != 1) {
>                         efree(buf);
>                         pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed");
> 			    		php_stream_close(stream);
>                         RETURN_FALSE;
>                     }
>                     efree(buf);
>                     buf = php_stream_get_line(stream, NULL, 0, &line_len);
>                 } 
> 
>                 efree(buf);
> 
> 			    php_stream_close(stream);
> 
>                 if (PQputCopyEnd(H->server, NULL) != 1) {
>                     pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed");
>                     RETURN_FALSE;
>                 }
>                 while ((pgsql_result = PQgetResult(H->server))) {
>                     if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
>                         pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
>                         command_failed = 1;
>                     }
>                     PQclear(pgsql_result);
>                 }
>                 if (command_failed) {
>                     RETURN_FALSE;
>                 }
>             } else {
>                 PQclear(pgsql_result);
>                 RETURN_FALSE;
>             }
>             RETURN_TRUE;
>             break;
>         default:
>             PQclear(pgsql_result);
>             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
> 			php_stream_close(stream);
>             RETURN_FALSE;
>             break;
>     }
> }
> /* }}} */
> 
> 
> /* {{{ proto string PDO::pgsqlCopyToFile(string $table_name , $filename, [string $delimiter [, string $null_as [, string $fields]]])
>    Returns true if the copy worked fine or false if error */
> static PHP_METHOD(PDO, pgsqlCopyToFile)
> {
>     pdo_dbh_t *dbh;
>     pdo_pgsql_db_handle *H;
> 
>     char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL, *filename = NULL;
>     int table_name_len, pg_delim_len, pg_null_as_len, pg_fields_len, filename_len;
>     char *query;
>     int id = -1;
> 
>     PGresult *pgsql_result;
>     ExecStatusType status;
>     int copydone = 0;
>     char *csv = (char *)NULL;
>     int ret, bytes_written;
> 
>     zval *zcontext = NULL;
>     php_stream *stream;
> 
>     php_stream_context *context = NULL;
> 
> 
>     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|sss",
>                               &table_name, &table_name_len, &filename, &filename_len,
>                               &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
>         return;
>     }
> 
> 
>     if (!pg_delim) {
>         pg_delim = "\t";
>     }
> 
>     if (pg_null_as_len <= 0) {
>         pg_null_as = safe_estrdup("\\\\N");
>     }
> 
>     if(pg_fields_len>0) {
>         spprintf(&query, 0, "COPY %s (%s) TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, pg_fields, *pg_delim, pg_null_as);
>     }
>     else {
>         spprintf(&query, 0, "COPY %s TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, *pg_delim, pg_null_as);
>     }
> 
>     // Obtain db Handler
>     dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
>     PDO_CONSTRUCT_CHECK;
> 
>     H = (pdo_pgsql_db_handle *)dbh->driver_data;
>     // H->server is the db handle for libPQ
> 
>     // Check and open filename for writing
>     context = php_stream_context_from_zval(zcontext, 0);
> 
>     stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
>     if (!stream) {
>         pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing");
>         RETURN_FALSE;
>     }
> 
> 
>     while ((pgsql_result = PQgetResult(H->server))) {
>         PQclear(pgsql_result);
>     }
>     pgsql_result = PQexec(H->server, query);
> 
> 
> 
>     if (pg_null_as_len <= 0) {
>         efree(pg_null_as);
>     }
> 
>     efree(query);
> 
>     if (pgsql_result) {
>         status = PQresultStatus(pgsql_result);
>     } else {
>         status = (ExecStatusType) PQstatus(H->server);
>     }
> 
> 
>     switch (status) {
>         case PGRES_COPY_OUT:
>             if (pgsql_result) {
>                 PQclear(pgsql_result);
>                 array_init(return_value);
> 
>                 while (!copydone)
>                 {
>                     ret = PQgetCopyData(H->server, &csv, 0);
>                     switch (ret) {
>                         case -1:
>                             copydone = 1;
>                             break;
>                         case 0:
>                         case -2:
>                             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed");
>                             php_stream_close(stream);
>                             RETURN_FALSE;
>                             break;
>                         default:
>                             bytes_written = php_stream_write(stream, csv, ret);
>                             if(bytes_written != ret) {
>                                 pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to write to file");
>                                 PQfreemem(csv);
>                                 php_stream_close(stream);
>                                 RETURN_FALSE;
>                             }
>                             PQfreemem(csv);
>                             break;
>                     }
>                 }
>                 php_stream_close(stream);
> 
>                 while ((pgsql_result = PQgetResult(H->server))) {
>                     PQclear(pgsql_result);
>                 }
>                 RETURN_TRUE;
>             } else {
>                 php_stream_close(stream);
>                 PQclear(pgsql_result);
>                 RETURN_FALSE;
>             }
>             break;
>         default:
>             PQclear(pgsql_result);
>             php_stream_close(stream);
>             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
>             RETURN_FALSE;
>             break;
>     }
> }
> /* }}} */
> 
> 
> 
> /* {{{ proto string PDO::pgsqlCopyToArray(string $table_name , [string $delimiter [, string $null_as [, string $fields]]])
>    Returns true if the copy worked fine or false if error */
> static PHP_METHOD(PDO, pgsqlCopyToArray)
> {
>     pdo_dbh_t *dbh;
>     pdo_pgsql_db_handle *H;
> 
>     char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
>     int table_name_len, pg_delim_len, pg_null_as_len, pg_fields_len;
>     char *query;
>     int id = -1;
> 
>     PGresult *pgsql_result;
>     ExecStatusType status;
>     int copydone = 0;
>     char *csv = (char *)NULL;
>     int ret;
> 
>     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss",
>                               &table_name, &table_name_len,
>                               &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
>         return;
>     }
> 
> 
>     if (!pg_delim) {
>         pg_delim = "\t";
>     }
> 
>     if (pg_null_as_len <= 0) {
>         pg_null_as = safe_estrdup("\\\\N");
>     }
> 
>     if(pg_fields_len>0) {
>         spprintf(&query, 0, "COPY %s (%s) TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, pg_fields, *pg_delim, pg_null_as);
>     }
>     else {
>         spprintf(&query, 0, "COPY %s TO STDOUT DELIMITERS '%c' WITH NULL AS '%s'", table_name, *pg_delim, pg_null_as);
>     }
> 
>     // Obtain db Handler
>     dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
>     PDO_CONSTRUCT_CHECK;
> 
>     H = (pdo_pgsql_db_handle *)dbh->driver_data;
>     // H->server is the db handle for libPQ
> 
> 
> 
>     while ((pgsql_result = PQgetResult(H->server))) {
>         PQclear(pgsql_result);
>     }
>     pgsql_result = PQexec(H->server, query);
> 
> 
> 
> 	if (pg_null_as_len <= 0) {
>     	efree(pg_null_as);
> 	}
> 
>     efree(query);
> 
>     if (pgsql_result) {
>         status = PQresultStatus(pgsql_result);
>     } else {
>         status = (ExecStatusType) PQstatus(H->server);
>     }
> 
> 
>     switch (status) {
>         case PGRES_COPY_OUT:
>             if (pgsql_result) {
>                 PQclear(pgsql_result);
>                 array_init(return_value);
> 
>                 while (!copydone)
>                 {
>                     ret = PQgetCopyData(H->server, &csv, 0);
>                     switch (ret) {
>                         case -1:
>                             copydone = 1;
>                             break;
>                         case 0:
>                         case -2:
>                             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed");
>                             RETURN_FALSE;
>                             break;
>                         default:
>                             add_next_index_string(return_value, csv, 1);
>                             PQfreemem(csv);
>                             break;
>                     }
>                 }
>                 while ((pgsql_result = PQgetResult(H->server))) {
>                     PQclear(pgsql_result);
>                 }
>             } else {
>                 PQclear(pgsql_result);
>                 RETURN_FALSE;
>             }
>             break;
>         default:
>             PQclear(pgsql_result);
>             pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed");
>             RETURN_FALSE;
>             break;
>     }
> }
> /* }}} */
> 
> 
610a1116,1120
> 	PHP_ME(PDO, pgsqlIsInTransaction, NULL, ZEND_ACC_PUBLIC)
> 	PHP_ME(PDO, pgsqlCopyFromArray, NULL, ZEND_ACC_PUBLIC)
> 	PHP_ME(PDO, pgsqlCopyFromFile, NULL, ZEND_ACC_PUBLIC)
> 	PHP_ME(PDO, pgsqlCopyToArray, NULL, ZEND_ACC_PUBLIC)
> 	PHP_ME(PDO, pgsqlCopyToFile, NULL, ZEND_ACC_PUBLIC)
559,589d558
< static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
< {
< 	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
< 	PGresult *res;
< 	char *q=NULL;
< 	ExecStatusType status;
< 	
< 	if (!S->result) {
< 		return FAILURE;
< 	}
< 	
< 	if (colno >= stmt->column_count) {
< 		return FAILURE;
< 	}
< 	
< 	array_init(return_value);
< 	add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type);
< 
< 	/* Fetch metadata from Postgres system catalogue */
< 	spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%d", S->cols[colno].pgsql_type);
< 	res = PQexec(S->H->server, q);
< 	efree(q);
< 	
< 	status = PQresultStatus(res);
< 	
< 	if (status != PGRES_TUPLES_OK) {
< 		/* Failed to get system catalogue, but return success
< 		 * with the data we have collected so far
< 		 */
< 		goto done;
< 	}
591,599c560,561
< 	/* We want exactly one row returned */
< 	if (1 != PQntuples(res)) {
< 		goto done;
< 	}
< 
< 	add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0), 1);
< done:
< 	PQclear(res);		
< 	return 1;
---
> static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC) {
> 	return _pgsql_stmt_get_column_meta(stmt, colno, return_value );
32a33,34
> #define PHP_PDO_PGSQL_RES_NAME "PHP PDO RES NAME"
> 
89a90,91
> extern int _pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);
> 
97a100,107
> enum pdo_pgsql_specific_constants {
> 	PGSQL_TRANSACTION_IDLE = PQTRANS_IDLE,
> 	PGSQL_TRANSACTION_ACTIVE = PQTRANS_ACTIVE,
> 	PGSQL_TRANSACTION_INTRANS = PQTRANS_INTRANS,
> 	PGSQL_TRANSACTION_INERROR = PQTRANS_INERROR,
> 	PGSQL_TRANSACTION_UNKNOWN = PQTRANS_UNKNOWN
> };
> 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to