37static bool pgsql_handle_in_transaction(
pdo_dbh_t *dbh);
39static char * _pdo_pgsql_trim_message(
const char *message,
int persistent)
41 size_t i =
strlen(message)-1;
44 if (i>1 && (message[i-1] ==
'\r' || message[i-1] ==
'\n') && message[i] ==
'.') {
47 while (i>0 && (message[i] ==
'\r' || message[i] ==
'\n')) {
58static zend_string* _pdo_pgsql_escape_credentials(
char *str)
72 char *errmsg = PQerrorMessage(
H->server);
84 strcpy(*pdo_err,
"HY000");
105static void _pdo_pgsql_notice(
void *
context,
const char *message)
112 zend_call_known_fcc(fc,
NULL, 1, &zarg,
NULL);
113 zval_ptr_dtor_str(&zarg);
137 if (
H->notice_callback) {
138 zend_fcc_dtor(
H->notice_callback);
139 efree(
H->notice_callback);
140 H->notice_callback =
NULL;
149 return lo_write(self->conn, self->lfd, (
char*)
buf,
count);
155 return lo_read(self->conn, self->lfd,
buf,
count);
158static int pgsql_lob_close(
php_stream *stream,
int close_handle)
164 lo_close(self->conn, self->lfd);
181#ifdef ZEND_ENABLE_ZVAL_LONG64
187 return pos >= 0 ? 0 : -1;
195 "pdo_pgsql lob stream",
211 self->
conn =
H->server;
230 if (
H->lob_streams) {
232 if (
res->type >= 0) {
243 if (
H->lob_streams) {
247 H->lob_streams =
NULL;
254 if (
H->einfo.errmsg) {
256 H->einfo.errmsg =
NULL;
272 int execute_only = 0;
275 stmt->driver_data =
S;
282 if (
S->cursor_name) {
285 spprintf(&
S->cursor_name, 0,
"pdo_crsr_%08x", ++
H->stmt_counter);
287 }
else if (driver_options) {
295 emulate =
H->disable_native_prepares ||
H->emulate_prepares;
296 execute_only =
H->disable_prepares;
303 stmt->named_rewrite_template =
"$%d";
310 strcpy(
dbh->error_code, stmt->error_code);
312 }
else if (
ret == 1) {
316 S->query = zend_string_copy(sql);
319 if (!emulate && !execute_only) {
322 spprintf(&
S->stmt_name, 0,
"pdo_stmt_%08x", ++
H->stmt_counter);
335 bool in_trans = pgsql_handle_in_transaction(
dbh);
342 qs = PQresultStatus(
res);
343 if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) {
348 H->pgoid = PQoidValue(
res);
349 if (qs == PGRES_COMMAND_OK) {
355 if (in_trans && !pgsql_handle_in_transaction(
dbh)) {
364 unsigned char *escaped;
374 escaped = PQescapeByteaConn(
H->server, (
unsigned char *)
ZSTR_VAL(unquoted),
ZSTR_LEN(unquoted), &tmp_len);
375 quotedlen = tmp_len + 1;
376 quoted =
emalloc(quotedlen + 1);
377 memcpy(quoted+1, escaped, quotedlen-2);
379 quoted[quotedlen-1] =
'\'';
380 quoted[quotedlen] =
'\0';
387 quoted[quotedlen + 1] =
'\'';
388 quoted[quotedlen + 2] =
'\0';
392 quoted_str = zend_string_init(quoted, quotedlen, 0);
405 res = PQexec(
H->server,
"SELECT LASTVAL()");
410 res = PQexecParams(
H->server,
"SELECT CURRVAL($1)", 1,
NULL, q,
NULL,
NULL, 0);
414 if (
res && (
status == PGRES_TUPLES_OK)) {
415 id = zend_string_init((
char *)PQgetvalue(
res, 0, 0), PQgetlength(
res, 0, 0), 0);
429 int version = PQlibVersion();
430 int major = version / 10000;
432 int minor = version % 10000;
435 int minor = version / 100 % 100;
436 int revision = version % 100;
466 switch (PQstatus(
H->server)) {
467 case CONNECTION_STARTED:
471 case CONNECTION_MADE:
476 case CONNECTION_AWAITING_RESPONSE:
480 case CONNECTION_AUTH_OK:
481 ZVAL_STRINGL(
return_value,
"Received authentication; waiting for backend start-up to finish.",
strlen(
"Received authentication; waiting for backend start-up to finish."));
483#ifdef CONNECTION_SSL_STARTUP
484 case CONNECTION_SSL_STARTUP:
488 case CONNECTION_SETENV:
492#ifdef CONNECTION_CONSUME
493 case CONNECTION_CONSUME:
497#ifdef CONNECTION_GSS_STARTUP
498 case CONNECTION_SSL_STARTUP:
502#ifdef CONNECTION_CHECK_TARGET
503 case CONNECTION_CHECK_TARGET:
507#ifdef CONNECTION_CHECK_STANDBY
508 case CONNECTION_CHECK_STANDBY:
520 int spid = PQbackendPID(
H->server);
525 "PID: %d; Client Encoding: %s; Is Superuser: %s; Session Authorization: %s; Date Style: %s",
527 (
char*)PQparameterStatus(
H->server,
"client_encoding"),
528 (
char*)PQparameterStatus(
H->server,
"is_superuser"),
529 (
char*)PQparameterStatus(
H->server,
"session_authorization"),
530 (
char*)PQparameterStatus(
H->server,
"DateStyle"));
547 if (!PQconsumeInput(
H->server) || PQstatus(
H->server) == CONNECTION_BAD) {
558 return PQtransactionStatus(
H->server) > PQTRANS_IDLE;
561static bool pdo_pgsql_transaction_cmd(
const char *cmd,
pdo_dbh_t *
dbh)
567 res = PQexec(
H->server, cmd);
569 if (PQresultStatus(
res) != PGRES_COMMAND_OK) {
580 return pdo_pgsql_transaction_cmd(
"BEGIN",
dbh);
585 bool ret = pdo_pgsql_transaction_cmd(
"COMMIT",
dbh);
592 dbh->in_txn = pgsql_handle_in_transaction(
dbh);
600 int ret = pdo_pgsql_transaction_cmd(
"ROLLBACK",
dbh);
616 char *table_name, *pg_delim =
NULL, *pg_null_as =
NULL, *pg_fields =
NULL;
617 size_t table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
620 PGresult *pgsql_result;
624 &table_name, &table_name_len, &pg_rows,
625 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) ==
FAILURE) {
629 if (!zend_hash_num_elements(
Z_ARRVAL_P(pg_rows))) {
640 spprintf(&query, 0,
"COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
642 spprintf(&query, 0,
"COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
648 while ((pgsql_result = PQgetResult(
H->server))) {
649 PQclear(pgsql_result);
651 pgsql_result = PQexec(
H->server, query);
657 status = PQresultStatus(pgsql_result);
659 status = (ExecStatusType) PQstatus(
H->server);
662 if (
status == PGRES_COPY_IN && pgsql_result) {
663 int command_failed = 0;
664 size_t buffer_len = 0;
667 PQclear(pgsql_result);
670 if (!try_convert_to_string(tmp)) {
677 query =
erealloc(query, buffer_len + 2);
681 if (query[query_len - 1] !=
'\n') {
682 query[query_len++] =
'\n';
684 query[query_len] =
'\0';
685 if (PQputCopyData(
H->server, query, query_len) != 1) {
696 if (PQputCopyEnd(
H->server,
NULL) != 1) {
702 while ((pgsql_result = PQgetResult(
H->server))) {
703 if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
707 PQclear(pgsql_result);
714 PQclear(pgsql_result);
732 char *table_name, *filename, *pg_delim =
NULL, *pg_null_as =
NULL, *pg_fields =
NULL;
733 size_t table_name_len,
filename_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
735 PGresult *pgsql_result;
741 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) ==
FAILURE) {
759 spprintf(&query, 0,
"COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
761 spprintf(&query, 0,
"COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
766 while ((pgsql_result = PQgetResult(
H->server))) {
767 PQclear(pgsql_result);
769 pgsql_result = PQexec(
H->server, query);
774 status = PQresultStatus(pgsql_result);
776 status = (ExecStatusType) PQstatus(
H->server);
779 if (
status == PGRES_COPY_IN && pgsql_result) {
781 int command_failed = 0;
784 PQclear(pgsql_result);
786 if (PQputCopyData(
H->server,
buf, line_len) != 1) {
797 if (PQputCopyEnd(
H->server,
NULL) != 1) {
803 while ((pgsql_result = PQgetResult(
H->server))) {
804 if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) {
808 PQclear(pgsql_result);
816 PQclear(pgsql_result);
834 char *table_name, *pg_delim =
NULL, *pg_null_as =
NULL, *pg_fields =
NULL, *filename =
NULL;
835 size_t table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len,
filename_len;
838 PGresult *pgsql_result;
845 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) ==
FAILURE) {
862 while ((pgsql_result = PQgetResult(
H->server))) {
863 PQclear(pgsql_result);
868 spprintf(&query, 0,
"COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
870 spprintf(&query, 0,
"COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
872 pgsql_result = PQexec(
H->server, query);
876 status = PQresultStatus(pgsql_result);
878 status = (ExecStatusType) PQstatus(
H->server);
881 if (
status == PGRES_COPY_OUT && pgsql_result) {
882 PQclear(pgsql_result);
885 int ret = PQgetCopyData(
H->server, &csv, 0);
889 }
else if (
ret > 0) {
908 while ((pgsql_result = PQgetResult(
H->server))) {
909 PQclear(pgsql_result);
915 PQclear(pgsql_result);
934 char *table_name, *pg_delim =
NULL, *pg_null_as =
NULL, *pg_fields =
NULL;
935 size_t table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
938 PGresult *pgsql_result;
942 &table_name, &table_name_len,
943 &pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) ==
FAILURE) {
953 while ((pgsql_result = PQgetResult(
H->server))) {
954 PQclear(pgsql_result);
959 spprintf(&query, 0,
"COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
961 spprintf(&query, 0,
"COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim :
'\t'), (pg_null_as_len ? pg_null_as :
"\\\\N"));
963 pgsql_result = PQexec(
H->server, query);
967 status = PQresultStatus(pgsql_result);
969 status = (ExecStatusType) PQstatus(
H->server);
972 if (
status == PGRES_COPY_OUT && pgsql_result) {
973 PQclear(pgsql_result);
978 int ret = PQgetCopyData(
H->server, &csv, 0);
981 }
else if (
ret > 0) {
991 while ((pgsql_result = PQgetResult(
H->server))) {
992 PQclear(pgsql_result);
996 PQclear(pgsql_result);
1022 lfd = lo_creat(
H->server, INV_READ|INV_WRITE);
1024 if (
lfd != InvalidOid) {
1050 char *modestr =
"rb";
1052 int mode = INV_READ;
1056 &oidstr, &oidstrlen, &modestr, &modestrlen)) {
1060 oid = (Oid)strtoul(oidstr, &end_ptr, 10);
1066 mode = INV_READ|INV_WRITE;
1103 char *oidstr, *end_ptr;
1107 &oidstr, &oidlen)) {
1111 oid = (Oid)strtoul(oidstr, &end_ptr, 10);
1122 if (1 == lo_unlink(
H->server,
oid)) {
1144 PGnotify *pgsql_notify;
1147 &result_type, &ms_timeout)) {
1155 result_type =
dbh->default_fetch_type;
1163 if (ms_timeout < 0) {
1166#ifdef ZEND_ENABLE_ZVAL_LONG64
1167 }
else if (ms_timeout >
INT_MAX) {
1175 if (!PQconsumeInput(
H->server)) {
1180 pgsql_notify = PQnotifies(
H->server);
1182 if (ms_timeout && !pgsql_notify) {
1185 if (!PQconsumeInput(
H->server)) {
1190 pgsql_notify = PQnotifies(
H->server);
1193 if (!pgsql_notify) {
1201 if (pgsql_notify->extra && pgsql_notify->extra[0]) {
1206 add_assoc_string(
return_value,
"message", pgsql_notify->relname);
1207 add_assoc_long(
return_value,
"pid", pgsql_notify->be_pid);
1208 if (pgsql_notify->extra && pgsql_notify->extra[0]) {
1209 add_assoc_string(
return_value,
"payload", pgsql_notify->extra);
1213 PQfreemem(pgsql_notify);
1263 zend_fcc_dup(
H->notice_callback, &fcc);
1270 zend_fcc_dtor(&fcc);
1280 return class_PDO_PGSql_Ext_methods;
1296 H->emulate_prepares = bval;
1302 H->disable_prepares = bval;
1310 pgsql_handle_closer,
1311 pgsql_handle_preparer,
1313 pgsql_handle_quoter,
1315 pgsql_handle_commit,
1316 pgsql_handle_rollback,
1318 pdo_pgsql_last_insert_id,
1319 pdo_pgsql_fetch_error_func,
1320 pdo_pgsql_get_attribute,
1321 pdo_pgsql_check_liveness,
1322 pdo_pgsql_get_driver_methods,
1324 pgsql_handle_in_transaction,
1329static int pdo_pgsql_handle_factory(
pdo_dbh_t *dbh,
zval *driver_options)
1346 H->einfo.errcode = 0;
1347 H->einfo.errmsg =
NULL;
1354 while ((
p = memchr(
p,
';', (e -
p)))) {
1358 if (driver_options) {
1377 smart_str_0(&conn_str);
1379 H->server = PQconnectdb(
ZSTR_VAL(conn_str.
s));
1390 smart_str_free(&conn_str);
1392 if (PQstatus(
H->server) != CONNECTION_OK) {
1397 PQsetNoticeProcessor(
H->server, _pdo_pgsql_notice, (
void *)dbh);
1402 dbh->
methods = &pgsql_methods;
1409 dbh->
methods = &pgsql_methods;
1411 pgsql_handle_closer(dbh);
1420 pdo_pgsql_handle_factory
file(string $filename, int $flags=0, $context=null)
strpbrk(string $string, string $characters)
count(Countable|array $value, int $mode=COUNT_NORMAL)
strstr(string $haystack, string $needle, bool $before_needle=false)
zend_ffi_ctype_name_buf buf
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
PDO_API bool pdo_get_bool_param(bool *bval, zval *value)
void pdo_throw_exception(unsigned int driver_errcode, char *driver_errmsg, pdo_error_type *pdo_error)
int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *msg, const char *file, int line)
void pdo_pgsql_close_lob_streams(pdo_dbh_t *dbh)
void pgsqlLOBUnlink_internal(INTERNAL_FUNCTION_PARAMETERS)
void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS)
void pgsqlCopyToArray_internal(INTERNAL_FUNCTION_PARAMETERS)
void pdo_pgsql_cleanup_notice_callback(pdo_pgsql_db_handle *H)
void pgsqlCopyFromFile_internal(INTERNAL_FUNCTION_PARAMETERS)
const php_stream_ops pdo_pgsql_lob_stream_ops
const pdo_driver_t pdo_pgsql_driver
void pgsqlLOBCreate_internal(INTERNAL_FUNCTION_PARAMETERS)
void pgsqlGetPid_internal(INTERNAL_FUNCTION_PARAMETERS)
void pgsqlGetNotify_internal(INTERNAL_FUNCTION_PARAMETERS)
void pgsqlCopyToFile_internal(INTERNAL_FUNCTION_PARAMETERS)
void pdo_libpq_version(char *buf, size_t len)
php_stream * pdo_pgsql_create_lob_stream(zval *dbh, int lfd, Oid oid)
void pgsqlLOBOpen_internal(INTERNAL_FUNCTION_PARAMETERS)
const struct pdo_stmt_methods pgsql_stmt_methods
unsigned const char * pos
#define PDO_CONSTRUCT_CHECK_WITH_CLEANUP(cleanup)
#define PDO_CONSTRUCT_CHECK
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery)
struct _pdo_dbh_t pdo_dbh_t
#define PDO_DRIVER_HEADER(name)
struct _pdo_stmt_t pdo_stmt_t
@ PDO_PARAM_EVT_FETCH_POST
@ PDO_PARAM_EVT_FETCH_PRE
@ PDO_PARAM_EVT_EXEC_POST
@ PDO_DBH_DRIVER_METHOD_KIND_DBH
@ PDO_ATTR_EMULATE_PREPARES
@ PDO_ATTR_CONNECTION_STATUS
@ PDO_ATTR_SERVER_VERSION
@ PDO_ATTR_CLIENT_VERSION
#define PDO_HANDLE_DBH_ERR()
#define PDO_DBH_CLEAR_ERR()
#define pdo_pgsql_sqlstate(r)
@ PDO_PGSQL_ATTR_DISABLE_PREPARES
#define pdo_pgsql_error(d, e, z)
#define pdo_pgsql_error_msg(d, e, m)
int pdo_pgsql_scanner(pdo_scanner_t *s)
#define PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE
struct _php_stream php_stream
#define php_stream_get_line(stream, buf, maxlen, retlen)
#define php_stream_get_resource_id(stream)
#define php_stream_to_zval(stream, zval)
#define php_stream_open_wrapper_ex(path, mode, options, opened, context)
#define php_stream_close(stream)
struct _php_stream_ops php_stream_ops
#define php_stream_alloc(ops, thisptr, persistent_id, mode)
#define php_stream_write(stream, buf, count)
PHPAPI zend_string * php_addcslashes_str(const char *str, size_t len, const char *what, size_t what_len)
unsigned max_escaped_char_length
pdo_error_type error_code
unsigned alloc_own_columns
const struct pdo_dbh_methods * methods
pdo_error_type error_code
#define INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result add_next_index_null(zval *arg)
ZEND_API zend_result add_next_index_stringl(zval *arg, const char *str, size_t length)
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
ZEND_API void add_index_string(zval *arg, zend_ulong index, const char *str)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
ZEND_API void add_index_long(zval *arg, zend_ulong index, zend_long n)
ZEND_API const zend_fcall_info empty_fcall_info
ZEND_API const zend_fcall_info_cache empty_fcall_info_cache
struct _zend_fcall_info_cache zend_fcall_info_cache
struct _zend_function_entry zend_function_entry
#define ZEND_PARSE_PARAMETERS_NONE()
#define ZVAL_STRING(z, s)
struct _zend_fcall_info zend_fcall_info
#define ZEND_FCC_INITIALIZED(fcc)
#define ZVAL_STRINGL(z, s, l)
#define pestrdup(s, persistent)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
#define erealloc(ptr, size)
#define safe_emalloc(nmemb, size, offset)
#define pecalloc(nmemb, size, persistent)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zend_result ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_REVERSE_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
ZEND_API void ZEND_FASTCALL zend_list_close(zend_resource *res)
struct _zend_string zend_string
ZEND_API void smart_str_append_printf(smart_str *dest, const char *format,...)
#define Z_STRVAL_P(zval_p)
#define Z_ARRVAL_P(zval_p)
struct _zend_resource zend_resource
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
ZEND_RESULT_CODE zend_result
#define ZVAL_COPY_VALUE(z, v)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)