-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/pdo_pgsql: Retrieve the memory usage of the query result resource #14260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
0aaeae6
a420d3a
b5769e6
da6b54b
c58707d
37e203e
218ff1e
8701022
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -705,6 +705,30 @@ static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt) | |
return 1; | ||
} | ||
|
||
static int pgsql_stmt_get_attr(pdo_stmt_t *stmt, zend_long attr, zval *val) | ||
{ | ||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data; | ||
|
||
switch (attr) { | ||
#ifdef HAVE_PG_RESULT_MEMORY_SIZE | ||
case PDO_PGSQL_ATTR_RESULT_MEMORY_SIZE: | ||
if(stmt->executed) { | ||
ZVAL_LONG(val, PQresultMemorySize(S->result)); | ||
} else { | ||
char *tmp; | ||
spprintf(&tmp, 0, "statement '%s' has not been executed yet", S->stmt_name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you re allocating on the heap then you need to free it at some point. If you run your own test you ll see. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, you're right... |
||
|
||
pdo_pgsql_error_stmt_msg(stmt, 0, "HY000", tmp); | ||
ZVAL_NULL(val); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not know if we should emit a PDO exception in this case, @SakiTakamachi what do you think ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can throw an exception here, because it's obviously wrong to try to get the size of a result when there is no "result" yet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah but mainly these are used for debugging purposes? In that case, throwing an exception might make the method difficult to use. If it's unexecuted, does it make sense to interpret this as 0 memory allocation and return 0 (or null)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, I prefer to throw an exception for incorrect operations. On the other hand, if you In both cases, it doesn't take me much time since I have the modified code at hand as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather, it seems like the problem is that fetching an unexecuted result doesn't result in an error.... That's a relic of PDO when exceptions didn't exist, and I don't think it should still be that way if don't take BC into account. I'll wait for David's opinion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, excuse me. This also has a status.... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added If we should not emit exception, I think the current code is the best. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can even be more informative since you have access to the statement's name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh I see, it works only if you enable pgsql too (symbol is defined here). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for your time! ! ! |
||
} | ||
return 1; | ||
#endif | ||
|
||
default: | ||
return 0; | ||
} | ||
} | ||
|
||
const struct pdo_stmt_methods pgsql_stmt_methods = { | ||
pgsql_stmt_dtor, | ||
pgsql_stmt_execute, | ||
|
@@ -713,7 +737,7 @@ const struct pdo_stmt_methods pgsql_stmt_methods = { | |
pgsql_stmt_get_col, | ||
pgsql_stmt_param_hook, | ||
NULL, /* set_attr */ | ||
NULL, /* get_attr */ | ||
pgsql_stmt_get_attr, | ||
pgsql_stmt_get_column_meta, | ||
NULL, /* next_rowset */ | ||
pdo_pgsql_stmt_cursor_closer | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--TEST-- | ||
PDO PgSQL PDOStatement::getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE) | ||
--EXTENSIONS-- | ||
pdo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This statement is unnecessary because pdo is always loaded when pdo_pgsql is loaded. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I fixed: 8701022 |
||
pdo_pgsql | ||
--SKIPIF-- | ||
<?php | ||
require __DIR__ . '/config.inc'; | ||
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc'; | ||
PDOTest::skip(); | ||
if (!defined('PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE')) die('skip constant PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE does not exist'); | ||
--FILE-- | ||
<?php | ||
|
||
require_once __DIR__ . "/config.inc"; | ||
|
||
/** @var Pdo */ | ||
$db = Pdo::connect($config['ENV']['PDOTEST_DSN']); | ||
|
||
echo 'Result set with only 1 row: '; | ||
$statement = $db->query('select 1'); | ||
$result_1 = $statement->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE); | ||
var_dump($result_1); | ||
|
||
echo 'Result set with many rows: '; | ||
$result = $db->query('select generate_series(1, 10000)'); | ||
$result_2 = $result->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE); | ||
var_dump($result_2); | ||
|
||
echo 'Large result sets should require more memory than small ones: '; | ||
var_dump($result_2 > $result_1); | ||
|
||
echo 'Statements that are not executed should not consume memory: '; | ||
$statement = $db->prepare('select 1'); | ||
$result_3 = $statement->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE); | ||
var_dump($result_3); | ||
|
||
echo 'and should emit Error: '; | ||
printf("%s: %d: %s\n", ...$statement->errorInfo()); | ||
|
||
--EXPECTF-- | ||
Result set with only 1 row: int(%d) | ||
Result set with many rows: int(%d) | ||
Large result sets should require more memory than small ones: bool(true) | ||
Statements that are not executed should not consume memory: NULL | ||
and should emit Error: HY000: 0: statement '%s' has not been executed yet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I should write this down.
The purpose of subclasses is to allow driver specific functionality to be provided in the subclasses.
This statement would mean having the same constants in PDO core, which may go against the subclassing philosophy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, since PDO::getAttribute is not a subclass-specific method, I'm not sure what to do.