Skip to content

Commit 0bb7d6d

Browse files
committed
ext/pgsql: add meta_cache per-link metadata caching
1 parent 638e354 commit 0bb7d6d

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

ext/pgsql/pgsql.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,15 @@ PHP_RSHUTDOWN_FUNCTION(pgsql)
649649
PGG(default_link) = NULL;
650650
}
651651

652+
zval *pgsql_link;
653+
654+
ZEND_HASH_FOREACH_VAL(&PGG(connections), pgsql_link) {
655+
pgsql_link_handle *link = Z_PGSQL_LINK_P(pgsql_link);
656+
if (link) {
657+
pgsql_meta_cache_destroy(&link->meta_cache);
658+
}
659+
} ZEND_HASH_FOREACH_END();
660+
652661
zend_hash_destroy(&PGG(field_oids));
653662
zend_hash_destroy(&PGG(table_oids));
654663
/* clean up persistent connection */
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
pg_meta_data() - cache behavior and invalidation
3+
--EXTENSIONS--
4+
pgsql
5+
--SKIPIF--
6+
<?php include("inc/skipif.inc"); ?>
7+
--FILE--
8+
<?php
9+
include('inc/config.inc');
10+
11+
$conn = pg_connect($conn_str);
12+
if (!$conn) die("Connection failed\n");
13+
14+
pg_query($conn, "DROP TABLE IF EXISTS test_meta_cache");
15+
pg_query($conn, "CREATE TABLE test_meta_cache (id SERIAL PRIMARY KEY, name TEXT)");
16+
$meta1 = pg_meta_data($conn, 'test_meta_cache');
17+
if (!isset($meta1['id']) || !isset($meta1['name'])) {
18+
echo "FAIL: Basic metadata missing columns\n";
19+
var_dump(array_keys($meta1));
20+
} else {
21+
echo "Basic metadata: OK (columns: " . implode(', ', array_keys($meta1)) . ")\n";
22+
}
23+
24+
pg_query($conn, "ALTER TABLE test_meta_cache ADD COLUMN age INT");
25+
$meta2 = pg_meta_data($conn, 'test_meta_cache');
26+
if (!isset($meta2['age'])) {
27+
echo "FAIL: Column 'age' not seen after ALTER\n";
28+
var_dump(array_keys($meta2));
29+
} else {
30+
echo "ALTER invalidation: OK ('age' found)\n";
31+
}
32+
33+
pg_query($conn, "DROP TABLE test_meta_cache");
34+
pg_query($conn, "CREATE TABLE test_meta_cache (only_column TEXT)");
35+
$meta3 = pg_meta_data($conn, 'test_meta_cache');
36+
if (isset($meta3['id']) || isset($meta3['name']) || isset($meta3['age'])) {
37+
echo "FAIL: Old columns still present after DROP/CREATE\n";
38+
var_dump(array_keys($meta3));
39+
} elseif (!isset($meta3['only_column'])) {
40+
echo "FAIL: New column 'only_column' missing\n";
41+
var_dump(array_keys($meta3));
42+
} else {
43+
echo "DROP/CREATE invalidation: OK (only 'only_column' present)\n";
44+
}
45+
46+
$meta_ext = pg_meta_data($conn, 'test_meta_cache', true);
47+
if (!isset($meta_ext['only_column']['is enum']) || !isset($meta_ext['only_column']['description'])) {
48+
echo "FAIL: Extended metadata missing extra fields\n";
49+
var_dump($meta_ext['only_column']);
50+
} else {
51+
echo "Extended metadata: OK (has 'is enum', 'description')\n";
52+
}
53+
54+
$meta_schema = pg_meta_data($conn, 'public.test_meta_cache');
55+
if (!isset($meta_schema['only_column'])) {
56+
echo "FAIL: Schema-qualified name not recognized\n";
57+
} else {
58+
echo "Schema-qualified name: OK";
59+
}
60+
$meta_false = pg_meta_data($conn, 'non_existent_table');
61+
pg_query($conn, "DROP TABLE test_meta_cache");
62+
pg_close($conn);
63+
echo "Done\n";
64+
?>
65+
--CLEAN--
66+
<?php
67+
include('inc/config.inc');
68+
$db = pg_connect($conn_str);
69+
pg_query($db, "DROP TABLE IF EXISTS test_meta_cache CASCADE");
70+
?>
71+
--EXPECTF--
72+
Basic metadata: OK (columns: %s)
73+
ALTER invalidation: OK ('age' found)
74+
DROP/CREATE invalidation: OK (only 'only_column' present)
75+
Extended metadata: OK (has 'is enum', 'description')
76+
Schema-qualified name: OK
77+
Warning: pg_meta_data(): Table 'non_existent_table' doesn't exists in %s on line %d
78+
Done

0 commit comments

Comments
 (0)