Skip to content

Commit 215ef4a

Browse files
ext/pdo_pgsql: Retrieve the memory usage of the query result resource
1 parent 73abf4f commit 215ef4a

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

ext/pdo_pgsql/pdo_pgsql.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ PHP_MINIT_FUNCTION(pdo_pgsql)
156156
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (zend_long)PGSQL_TRANSACTION_INTRANS);
157157
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (zend_long)PGSQL_TRANSACTION_INERROR);
158158
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (zend_long)PGSQL_TRANSACTION_UNKNOWN);
159+
#ifdef HAVE_PG_RESULT_MEMORY_SIZE
160+
REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_RESULT_MEMORY_SIZE", (zend_long)PRO_PGSQL_ATTR_RESULT_MEMORY_SIZE);
161+
#endif
159162

160163
PdoPgsql_ce = register_class_PdoPgsql(pdo_dbh_ce);
161164
PdoPgsql_ce->create_object = pdo_dbh_new;

ext/pdo_pgsql/pgsql_statement.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,26 @@ static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt)
705705
return 1;
706706
}
707707

708+
static int pgsql_stmt_get_attr(pdo_stmt_t *stmt, zend_long attr, zval *val)
709+
{
710+
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
711+
712+
switch (attr) {
713+
#ifdef HAVE_PG_RESULT_MEMORY_SIZE
714+
case PRO_PGSQL_ATTR_RESULT_MEMORY_SIZE:
715+
if(stmt->executed) {
716+
ZVAL_LONG(val, PQresultMemorySize(S->result));
717+
} else {
718+
ZVAL_NULL(val);
719+
}
720+
return 1;
721+
#endif
722+
723+
default:
724+
return 0;
725+
}
726+
}
727+
708728
const struct pdo_stmt_methods pgsql_stmt_methods = {
709729
pgsql_stmt_dtor,
710730
pgsql_stmt_execute,
@@ -713,7 +733,7 @@ const struct pdo_stmt_methods pgsql_stmt_methods = {
713733
pgsql_stmt_get_col,
714734
pgsql_stmt_param_hook,
715735
NULL, /* set_attr */
716-
NULL, /* get_attr */
736+
pgsql_stmt_get_attr,
717737
pgsql_stmt_get_column_meta,
718738
NULL, /* next_rowset */
719739
pdo_pgsql_stmt_cursor_closer

ext/pdo_pgsql/php_pdo_pgsql_int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ extern const struct pdo_stmt_methods pgsql_stmt_methods;
8686

8787
enum {
8888
PDO_PGSQL_ATTR_DISABLE_PREPARES = PDO_ATTR_DRIVER_SPECIFIC,
89+
PRO_PGSQL_ATTR_RESULT_MEMORY_SIZE,
8990
};
9091

9192
struct pdo_pgsql_lob_self {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
PDO PgSQL PDOStatement::getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE)
3+
--EXTENSIONS--
4+
pdo
5+
pdo_pgsql
6+
--SKIPIF--
7+
<?php
8+
require __DIR__ . '/config.inc';
9+
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
10+
PDOTest::skip();
11+
if (!defined('PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE')) die('skip constant PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE does not exist');
12+
?>
13+
--FILE--
14+
<?php
15+
16+
require_once __DIR__ . "/config.inc";
17+
18+
/** @var Pdo */
19+
$db = Pdo::connect($config['ENV']['PDOTEST_DSN']);
20+
21+
echo 'Result set with only 1 row: ';
22+
$statement = $db->query('select 1');
23+
$result_1 = $statement->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE);
24+
var_dump($result_1);
25+
26+
echo 'Result set with many rows: ';
27+
$result = $db->query('select generate_series(1, 10000)');
28+
$result_2 = $result->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE);
29+
var_dump($result_2);
30+
31+
echo 'Large result sets should require more memory than small ones: ';
32+
var_dump($result_2 > $result_1);
33+
34+
echo 'Statements that are not executed should not consume memory: ';
35+
$statement = $db->prepare('select 1');
36+
$result_3 = $statement->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE);
37+
var_dump($result_3);
38+
39+
--EXPECTF--
40+
Result set with only 1 row: int(%d)
41+
Result set with many rows: int(%d)
42+
Large result sets should require more memory than small ones: bool(true)
43+
Statements that are not executed should not consume memory: NULL

0 commit comments

Comments
 (0)