Skip to content

Commit dbcc77d

Browse files
authored
Fix GH-15893: Pdo\Pgsql backport fixes from GH-16124 (#16158)
1 parent 8a6de2c commit dbcc77d

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

ext/pdo_pgsql/pgsql_driver.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -657,16 +657,14 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS)
657657
PGresult *pgsql_result;
658658
ExecStatusType status;
659659

660-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sA|sss!",
661-
&table_name, &table_name_len, &pg_rows,
662-
&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
663-
RETURN_THROWS();
664-
}
665-
666-
if ((Z_TYPE_P(pg_rows) != IS_ARRAY && !instanceof_function(Z_OBJCE_P(pg_rows), zend_ce_traversable))) {
667-
zend_argument_type_error(2, "must be of type array or Traversable");
668-
RETURN_THROWS();
669-
}
660+
ZEND_PARSE_PARAMETERS_START(2, 5)
661+
Z_PARAM_STRING(table_name, table_name_len)
662+
Z_PARAM_ITERABLE(pg_rows)
663+
Z_PARAM_OPTIONAL
664+
Z_PARAM_STRING(pg_delim, pg_delim_len)
665+
Z_PARAM_STRING(pg_null_as, pg_null_as_len)
666+
Z_PARAM_STRING_OR_NULL(pg_fields, pg_fields_len)
667+
ZEND_PARSE_PARAMETERS_END();
670668

671669
dbh = Z_PDO_DBH_P(ZEND_THIS);
672670
PDO_CONSTRUCT_CHECK;
@@ -712,11 +710,18 @@ void pgsqlCopyFromArray_internal(INTERNAL_FUNCTION_PARAMETERS)
712710
}
713711
} ZEND_HASH_FOREACH_END();
714712
} else {
715-
iter = Z_OBJ_P(pg_rows)->ce->get_iterator(Z_OBJCE_P(pg_rows), pg_rows, 0);
713+
iter = Z_OBJCE_P(pg_rows)->get_iterator(Z_OBJCE_P(pg_rows), pg_rows, 0);
716714
if (iter == NULL || EG(exception)) {
717715
RETURN_THROWS();
718716
}
719717

718+
if (iter->funcs->rewind) {
719+
iter->funcs->rewind(iter);
720+
if (EG(exception)) {
721+
RETURN_THROWS();
722+
}
723+
}
724+
720725
for (; iter->funcs->valid(iter) == SUCCESS && EG(exception) == NULL; iter->funcs->move_forward(iter)) {
721726
tmp = iter->funcs->get_current_data(iter);
722727
if (!_pdo_pgsql_send_copy_data(H, tmp)) {

ext/pdo_pgsql/tests/copy_from_iterator.phpt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ $iterator = new class implements Iterator{
4242
}
4343
};
4444

45+
try {
46+
$db->pgsqlCopyFromArray('test_copy_from_traversable',new stdClass());
47+
} catch (\TypeError $e) {
48+
echo $e->getMessage() . PHP_EOL;
49+
}
50+
4551
$db->pgsqlCopyFromArray('test_copy_from_traversable',$iterator);
4652

4753
$stmt = $db->query("select * from test_copy_from_traversable order by 1");
@@ -56,6 +62,7 @@ $db = PDOTest::test_factory(__DIR__ . '/common.phpt');
5662
$db->query('DROP TABLE IF EXISTS test_copy_from_traversable CASCADE');
5763
?>
5864
--EXPECT--
65+
PDO::pgsqlCopyFromArray(): Argument #2 ($rows) must be of type Traversable|array, stdClass given
5966
array (
6067
0 => 1,
6168
1 => 1,

0 commit comments

Comments
 (0)