diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 14488ca6157db..fc3cf25ba490b 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -494,6 +494,8 @@ PHP_RINIT_FUNCTION(pgsql) PGG(num_links) = PGG(num_persistent); zend_hash_init(&PGG(field_oids), 0, NULL, release_string, 0); zend_hash_init(&PGG(table_oids), 0, NULL, release_string, 0); + zend_hash_init(&PGG(meta), 0, NULL, NULL, 0); + zend_hash_init(&PGG(meta_extended), 0, NULL, NULL, 0); return SUCCESS; } @@ -506,6 +508,8 @@ PHP_RSHUTDOWN_FUNCTION(pgsql) zend_hash_destroy(&PGG(field_oids)); zend_hash_destroy(&PGG(table_oids)); + zend_hash_destroy(&PGG(meta)); + zend_hash_destroy(&PGG(meta_extended)); /* clean up persistent connection */ zend_hash_apply(&EG(persistent_list), (apply_func_t) _rollback_transactions); return SUCCESS; @@ -4147,9 +4151,8 @@ PHP_FUNCTION(pg_flush) /* {{{ php_pgsql_meta_data * table_name must not be empty - * TODO: Add meta_data cache for better performance */ -PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string *table_name, zval *meta, bool extended) +PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, zend_string *table_name, zval *meta, bool extended, bool invalcache) { PGresult *pg_result; char *src, *tmp_name, *tmp_name2 = NULL; @@ -4157,10 +4160,36 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string smart_str querystr = {0}; size_t new_len; int i, num_rows; - zval elem; + zend_string *field; + zval elem, nmeta, *tmp, *nelem, *val; + HashTable *zmeta; + + const char pg_cache_field[] = "pg_meta_data_cached"; ZEND_ASSERT(ZSTR_LEN(table_name) != 0); + zmeta = (extended ? &PGG(meta_extended) : &PGG(meta)); + + if ((tmp = zend_hash_find(zmeta, table_name)) != NULL) { + if (!invalcache) { + ZVAL_COPY_VALUE(meta, tmp); + nelem = zend_hash_str_find(Z_ARR_P(meta), pg_cache_field, sizeof(pg_cache_field) - 1); + ZEND_ASSERT(nelem != NULL); + if (Z_TYPE_INFO_P(nelem) == IS_FALSE) { + ZVAL_BOOL(nelem, true); + } + zval_addref_p(tmp); + return SUCCESS; + } else { + ZEND_HASH_FOREACH_STR_KEY_VAL(&PGG(meta), field, val) { + zend_hash_del(&PGG(meta), field); + } ZEND_HASH_FOREACH_END(); + ZEND_HASH_FOREACH_STR_KEY_VAL(&PGG(meta_extended), field, val) { + zend_hash_del(&PGG(meta_extended), field); + } ZEND_HASH_FOREACH_END(); + } + } + src = estrdup(ZSTR_VAL(table_name)); tmp_name = php_strtok_r(src, ".", &tmp_name2); if (!tmp_name) { @@ -4250,6 +4279,31 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string name = PQgetvalue(pg_result,i,0); add_assoc_zval(meta, name, &elem); } + + add_assoc_bool_ex(meta, pg_cache_field, sizeof(pg_cache_field) - 1, false); + + tmp = zend_hash_add(zmeta, table_name, &nmeta); + array_init_size(tmp, zend_hash_num_elements(Z_ARR_P(meta))); + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARR_P(meta), field, val) { + ZVAL_DEREF(val); + if (Z_TYPE_P(val) != IS_ARRAY) { + zend_hash_update(Z_ARR_P(tmp), field, val); + } else { + zend_string *sfield; + zval *nelem, *sval, ntmp; + + zend_string_delref(field); + nelem = zend_hash_add(Z_ARR_P(tmp), field, &ntmp); + array_init_size(nelem, zend_hash_num_elements(Z_ARR_P(val))); + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARR_P(val), sfield, sval) { + zend_string_delref(sfield); + zend_hash_update(Z_ARR_P(nelem), sfield, sval); + } ZEND_HASH_FOREACH_END(); + } + } ZEND_HASH_FOREACH_END(); + PQclear(pg_result); return SUCCESS; @@ -4263,11 +4317,11 @@ PHP_FUNCTION(pg_meta_data) zval *pgsql_link; pgsql_link_handle *link; zend_string *table_name; - bool extended=0; + bool extended=0, invalcache=0; PGconn *pgsql; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|b", - &pgsql_link, pgsql_link_ce, &table_name, &extended) == FAILURE + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|bb", + &pgsql_link, pgsql_link_ce, &table_name, &extended, &invalcache) == FAILURE ) { RETURN_THROWS(); } @@ -4283,7 +4337,7 @@ PHP_FUNCTION(pg_meta_data) } array_init(return_value); - if (php_pgsql_meta_data(pgsql, table_name, return_value, extended) == FAILURE) { + if (php_pgsql_meta_data(pgsql, table_name, return_value, extended, invalcache) == FAILURE) { zend_array_destroy(Z_ARR_P(return_value)); /* destroy array */ RETURN_FALSE; } @@ -4459,7 +4513,7 @@ static zend_string *php_pgsql_add_quotes(zend_string *src) /* {{{ php_pgsql_convert * check and convert array values (fieldname=>value pair) for sql */ -PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *table_name, const zval *values, zval *result, zend_ulong opt) +PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, zend_string *table_name, const zval *values, zval *result, zend_ulong opt, bool invalcache) { zend_string *field = NULL; zval meta, *def, *type, *not_null, *has_default, *is_enum, *val, new_val; @@ -4476,7 +4530,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * array_init(&meta); /* table_name is escaped by php_pgsql_meta_data */ - if (php_pgsql_meta_data(pg_link, table_name, &meta, 0) == FAILURE) { + if (php_pgsql_meta_data(pg_link, table_name, &meta, 0, invalcache) == FAILURE) { zval_ptr_dtor(&meta); return FAILURE; } @@ -5112,9 +5166,10 @@ PHP_FUNCTION(pg_convert) pgsql_link_handle *link; zend_string *table_name; zend_ulong option = 0; + bool invalcache=0; PGconn *pg_link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", &pgsql_link, pgsql_link_ce, &table_name, &values, &option) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|lb", &pgsql_link, pgsql_link_ce, &table_name, &values, &option, &invalcache) == FAILURE) { RETURN_THROWS(); } @@ -5137,7 +5192,7 @@ PHP_FUNCTION(pg_convert) php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } array_init(return_value); - if (php_pgsql_convert(pg_link, table_name, values, return_value, option) == FAILURE) { + if (php_pgsql_convert(pg_link, table_name, values, return_value, option, invalcache) == FAILURE) { zend_array_destroy(Z_ARR_P(return_value)); RETURN_FALSE; } @@ -5198,7 +5253,7 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z /* }}} */ /* {{{ php_pgsql_insert */ -PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *table, zval *var_array, zend_ulong opt, zend_string **sql) +PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, zend_string *table, zval *var_array, zend_ulong opt, zend_string **sql, bool invalcache) { zval *val, converted; char buf[256]; @@ -5223,7 +5278,7 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t /* convert input array if needed */ if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { array_init(&converted); - if (php_pgsql_convert(pg_link, table, var_array, &converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { + if (php_pgsql_convert(pg_link, table, var_array, &converted, (opt & PGSQL_CONV_OPTS), invalcache) == FAILURE) { goto cleanup; } var_array = &converted; @@ -5322,9 +5377,10 @@ PHP_FUNCTION(pg_insert) PGresult *pg_result; ExecStatusType status; zend_string *sql = NULL; + bool invalcache=0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", - &pgsql_link, pgsql_link_ce, &table, &values, &option) == FAILURE + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|lb", + &pgsql_link, pgsql_link_ce, &table, &values, &option, &invalcache) == FAILURE ) { RETURN_THROWS(); } @@ -5351,7 +5407,7 @@ PHP_FUNCTION(pg_insert) if (option & PGSQL_DML_EXEC) { /* return object when executed */ option = option & ~PGSQL_DML_EXEC; - if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql) == FAILURE) { + if (php_pgsql_insert(pg_link, table, values, option|PGSQL_DML_STRING, &sql, invalcache) == FAILURE) { RETURN_FALSE; } pg_result = PQexec(pg_link, ZSTR_VAL(sql)); @@ -5392,7 +5448,7 @@ PHP_FUNCTION(pg_insert) } break; } - } else if (php_pgsql_insert(pg_link, table, values, option, &sql) == FAILURE) { + } else if (php_pgsql_insert(pg_link, table, values, option, &sql, invalcache) == FAILURE) { RETURN_FALSE; } if (return_sql) { @@ -5466,7 +5522,7 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, /* }}} */ /* {{{ php_pgsql_update */ -PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *table, zval *var_array, zval *ids_array, zend_ulong opt, zend_string **sql) +PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, zend_string *table, zval *var_array, zval *ids_array, zend_ulong opt, zend_string **sql, bool invalcache) { zval var_converted, ids_converted; smart_str querystr = {0}; @@ -5487,12 +5543,12 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { array_init(&var_converted); - if (php_pgsql_convert(pg_link, table, var_array, &var_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { + if (php_pgsql_convert(pg_link, table, var_array, &var_converted, (opt & PGSQL_CONV_OPTS), invalcache) == FAILURE) { goto cleanup; } var_array = &var_converted; array_init(&ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS), invalcache) == FAILURE) { goto cleanup; } ids_array = &ids_converted; @@ -5541,9 +5597,10 @@ PHP_FUNCTION(pg_update) zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; zend_string *sql = NULL; + bool invalcache=0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPaa|l", - &pgsql_link, pgsql_link_ce, &table, &values, &ids, &option) == FAILURE + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPaa|lb", + &pgsql_link, pgsql_link_ce, &table, &values, &ids, &option, &invalcache) == FAILURE ) { RETURN_THROWS(); } @@ -5566,7 +5623,7 @@ PHP_FUNCTION(pg_update) if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_update(pg_link, table, values, ids, option, &sql) == FAILURE) { + if (php_pgsql_update(pg_link, table, values, ids, option, &sql, invalcache) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { @@ -5577,7 +5634,7 @@ PHP_FUNCTION(pg_update) /* }}} */ /* {{{ php_pgsql_delete */ -PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *table, zval *ids_array, zend_ulong opt, zend_string **sql) +PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, zend_string *table, zval *ids_array, zend_ulong opt, zend_string **sql, bool invalcache) { zval ids_converted; smart_str querystr = {0}; @@ -5595,7 +5652,7 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { array_init(&ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS), invalcache) == FAILURE) { goto cleanup; } ids_array = &ids_converted; @@ -5638,9 +5695,10 @@ PHP_FUNCTION(pg_delete) zend_ulong option = PGSQL_DML_EXEC; PGconn *pg_link; zend_string *sql; + bool invalcache=0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|l", - &pgsql_link, pgsql_link_ce, &table, &ids, &option + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|lb", + &pgsql_link, pgsql_link_ce, &table, &ids, &option, &invalcache ) == FAILURE) { RETURN_THROWS(); } @@ -5663,7 +5721,7 @@ PHP_FUNCTION(pg_delete) if (php_pgsql_flush_query(pg_link)) { php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } - if (php_pgsql_delete(pg_link, table, ids, option, &sql) == FAILURE) { + if (php_pgsql_delete(pg_link, table, ids, option, &sql, invalcache) == FAILURE) { RETURN_FALSE; } if (option & PGSQL_DML_STRING) { @@ -5715,7 +5773,7 @@ PHP_PGSQL_API void php_pgsql_result2array(PGresult *pg_result, zval *ret_array, /* }}} */ /* {{{ php_pgsql_select */ -PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *table, zval *ids_array, zval *ret_array, zend_ulong opt, long result_type, zend_string **sql) +PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, zend_string *table, zval *ids_array, zval *ret_array, zend_ulong opt, long result_type, zend_string **sql, bool invalcache) { zval ids_converted; smart_str querystr = {0}; @@ -5735,7 +5793,7 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t ZVAL_UNDEF(&ids_converted); if (!(opt & (PGSQL_DML_NO_CONV|PGSQL_DML_ESCAPE))) { array_init(&ids_converted); - if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS)) == FAILURE) { + if (php_pgsql_convert(pg_link, table, ids_array, &ids_converted, (opt & PGSQL_CONV_OPTS), invalcache) == FAILURE) { goto cleanup; } ids_array = &ids_converted; @@ -5782,10 +5840,11 @@ PHP_FUNCTION(pg_select) zend_long result_type = PGSQL_ASSOC; PGconn *pg_link; zend_string *sql = NULL; + bool invalcache=0; /* TODO Document result_type param on php.net (apparently it was added in PHP 7.1) */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|ll", - &pgsql_link, pgsql_link_ce, &table, &ids, &option, &result_type + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OPa|llb", + &pgsql_link, pgsql_link_ce, &table, &ids, &option, &result_type, &invalcache ) == FAILURE) { RETURN_THROWS(); } @@ -5813,7 +5872,7 @@ PHP_FUNCTION(pg_select) php_error_docref(NULL, E_NOTICE, "Detected unhandled result(s) in connection"); } array_init(return_value); - if (php_pgsql_select(pg_link, table, ids, return_value, option, result_type, &sql) == FAILURE) { + if (php_pgsql_select(pg_link, table, ids, return_value, option, result_type, &sql, invalcache) == FAILURE) { zval_ptr_dtor(return_value); RETURN_FALSE; } diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index fd58fb92c0045..08273c6846206 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -922,28 +922,28 @@ function pg_flush(PgSql\Connection $connection): int|bool {} * @return array|false * @refcount 1 */ - function pg_meta_data(PgSql\Connection $connection, string $table_name, bool $extended = false): array|false {} + function pg_meta_data(PgSql\Connection $connection, string $table_name, bool $extended = false, bool $invalcache = false): array|false {} /** * @return array|false * @refcount 1 */ - function pg_convert(PgSql\Connection $connection, string $table_name, array $values, int $flags = 0): array|false {} + function pg_convert(PgSql\Connection $connection, string $table_name, array $values, int $flags = 0, bool $invalcache = false): array|false {} /** @refcount 1 */ - function pg_insert(PgSql\Connection $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC): PgSql\Result|string|bool {} + function pg_insert(PgSql\Connection $connection, string $table_name, array $values, int $flags = PGSQL_DML_EXEC, bool $invalcache = false): PgSql\Result|string|bool {} /** @refcount 1 */ - function pg_update(PgSql\Connection $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} + function pg_update(PgSql\Connection $connection, string $table_name, array $values, array $conditions, int $flags = PGSQL_DML_EXEC, bool $invalcache = false): string|bool {} /** @refcount 1 */ - function pg_delete(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC): string|bool {} + function pg_delete(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, bool $invalcache = false): string|bool {} /** * @return array|string|false * @refcount 1 */ - function pg_select(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC): array|string|false {} + function pg_select(PgSql\Connection $connection, string $table_name, array $conditions, int $flags = PGSQL_DML_EXEC, int $mode = PGSQL_ASSOC, bool $invalcache = false): array|string|false {} #ifdef LIBPQ_HAS_PIPELINING function pg_enter_pipeline_mode(PgSql\Connection $connection): bool {} diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index 839842bbc3944..5aa3958571efd 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f5b563282ffa08a4f79293fcf91df284433a6f5c */ + * Stub hash: 2e211767225bd016d7f842dd6528c47e18ffb762 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql\\Connection, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) @@ -411,6 +411,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_meta_data, 0, 2, MAY_BE_ARRAY ZEND_ARG_OBJ_INFO(0, connection, PgSql\\Connection, 0) ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extended, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_convert, 0, 3, MAY_BE_ARRAY|MAY_BE_FALSE) @@ -418,6 +419,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_convert, 0, 3, MAY_BE_ARRAY|M ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_insert, 0, 3, PgSql\\Result, MAY_BE_STRING|MAY_BE_BOOL) @@ -425,6 +427,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_insert, 0, 3, PgSql\\Resu ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|MAY_BE_BOOL) @@ -433,6 +436,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_update, 0, 4, MAY_BE_STRING|M ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_delete, 0, 3, MAY_BE_STRING|MAY_BE_BOOL) @@ -440,6 +444,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_delete, 0, 3, MAY_BE_STRING|M ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_select, 0, 3, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_FALSE) @@ -448,6 +453,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_select, 0, 3, MAY_BE_ARRAY|MA ZEND_ARG_TYPE_INFO(0, conditions, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PGSQL_DML_EXEC") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "PGSQL_ASSOC") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, invalcache, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() #if defined(LIBPQ_HAS_PIPELINING) diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index f297f91b3ecde..5abf04cfd9513 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -74,12 +74,12 @@ PHP_MINFO_FUNCTION(pgsql); #define PGSQL_DML_ESCAPE (1<<12) /* No convert, but escape only */ /* exported functions */ -PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string *table_name, zval *meta, bool extended); -PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string *table_name, const zval *values, zval *result, zend_ulong opt); -PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *table, zval *values, zend_ulong opt, zend_string **sql); -PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *table, zval *values, zval *ids, zend_ulong opt , zend_string **sql); -PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *table, zval *ids, zend_ulong opt, zend_string **sql); -PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *table, zval *ids, zval *ret_array, zend_ulong opt, long fetch_option, zend_string **sql ); +PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, zend_string *table_name, zval *meta, bool extended, bool invalcache); +PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, zend_string *table_name, const zval *values, zval *result, zend_ulong opt, bool invalcache); +PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, zend_string *table, zval *values, zend_ulong opt, zend_string **sql, bool invalcache); +PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, zend_string *table, zval *values, zval *ids, zend_ulong opt , zend_string **sql, bool invalcache); +PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, zend_string *table, zval *ids, zend_ulong opt, zend_string **sql, bool invalcache); +PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, zend_string *table, zval *ids, zval *ret_array, zend_ulong opt, long fetch_option, zend_string **sql, bool invalcache); PHP_PGSQL_API void php_pgsql_result2array(PGresult *pg_result, zval *ret_array, long fetch_option); /* internal functions */ @@ -191,6 +191,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pgsql) HashTable field_oids; HashTable table_oids; HashTable connections; + HashTable meta,meta_extended; ZEND_END_MODULE_GLOBALS(pgsql) ZEND_EXTERN_MODULE_GLOBALS(pgsql) diff --git a/ext/pgsql/tests/11pg_meta_data.phpt b/ext/pgsql/tests/11pg_meta_data.phpt index fb595023a2a09..345f54c4d495f 100644 --- a/ext/pgsql/tests/11pg_meta_data.phpt +++ b/ext/pgsql/tests/11pg_meta_data.phpt @@ -16,8 +16,8 @@ $meta = pg_meta_data($db, $table_name); var_dump($meta); ?> ---EXPECT-- -array(3) { +--EXPECTF-- +array(4) { ["num"]=> array(7) { ["num"]=> @@ -69,4 +69,6 @@ array(3) { ["is enum"]=> bool(false) } + ["pg_meta_data_cached"]=> + bool(%s) } diff --git a/ext/pgsql/tests/pg_meta_data_001.phpt b/ext/pgsql/tests/pg_meta_data_001.phpt index a69fcb2ef63eb..8e12b9a8131f0 100644 --- a/ext/pgsql/tests/pg_meta_data_001.phpt +++ b/ext/pgsql/tests/pg_meta_data_001.phpt @@ -21,6 +21,10 @@ pg_query($conn, 'CREATE TABLE foo (id INT, id3 INT)'); var_dump(pg_meta_data($conn, 'foo')); var_dump(pg_meta_data($conn, 'phptests.foo')); var_dump(pg_meta_data($conn, 'phptests.foo', TRUE)); +var_dump(pg_meta_data($conn, 'phptests.foo')); +var_dump(pg_meta_data($conn, 'phptests.foo', TRUE)); +var_dump(pg_meta_data($conn, 'phptests.foo', FALSE, TRUE)); +var_dump(pg_meta_data($conn, 'phptests.foo', TRUE)); pg_query($conn, 'DROP TABLE foo'); @@ -29,7 +33,7 @@ pg_query($conn, 'DROP SCHEMA phptests'); ?> --EXPECT-- -array(2) { +array(3) { ["id"]=> array(7) { ["num"]=> @@ -64,8 +68,10 @@ array(2) { ["is enum"]=> bool(false) } + ["pg_meta_data_cached"]=> + bool(false) } -array(2) { +array(3) { ["id"]=> array(7) { ["num"]=> @@ -100,8 +106,10 @@ array(2) { ["is enum"]=> bool(false) } + ["pg_meta_data_cached"]=> + bool(false) } -array(2) { +array(3) { ["id"]=> array(11) { ["num"]=> @@ -152,4 +160,174 @@ array(2) { ["description"]=> string(0) "" } + ["pg_meta_data_cached"]=> + bool(false) +} +array(3) { + ["id"]=> + array(7) { + ["num"]=> + int(1) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["id2"]=> + array(7) { + ["num"]=> + int(2) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["pg_meta_data_cached"]=> + bool(true) +} +array(3) { + ["id"]=> + array(11) { + ["num"]=> + int(1) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + ["is base"]=> + bool(true) + ["is composite"]=> + bool(false) + ["is pseudo"]=> + bool(false) + ["description"]=> + string(0) "" + } + ["id2"]=> + array(11) { + ["num"]=> + int(2) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + ["is base"]=> + bool(true) + ["is composite"]=> + bool(false) + ["is pseudo"]=> + bool(false) + ["description"]=> + string(0) "" + } + ["pg_meta_data_cached"]=> + bool(true) +} +array(3) { + ["id"]=> + array(7) { + ["num"]=> + int(1) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["id3"]=> + array(7) { + ["num"]=> + int(2) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["pg_meta_data_cached"]=> + bool(false) +} +array(3) { + ["id"]=> + array(7) { + ["num"]=> + int(1) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["id2"]=> + array(7) { + ["num"]=> + int(2) + ["type"]=> + string(4) "int4" + ["len"]=> + int(4) + ["not null"]=> + bool(false) + ["has default"]=> + bool(false) + ["array dims"]=> + int(0) + ["is enum"]=> + bool(false) + } + ["pg_meta_data_cached"]=> + bool(false) }