Skip to content

Commit e41cf7a

Browse files
committed
Fix GH-7996: Adding new parameter to pg_copy_from/pg_copy_to
By default is the same as the QUOTE setting and must be one character only. It specifies the character appearing before one that matches the QUOTE setting.
1 parent 028cfda commit e41cf7a

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

ext/pgsql/pgsql.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,21 +3211,23 @@ PHP_FUNCTION(pg_copy_to)
32113211
pgsql_link_handle *link;
32123212
zend_string *table_name;
32133213
zend_string *pg_delimiter = NULL;
3214+
zend_string *pg_escape = NULL;
32143215
char *pg_null_as = NULL;
32153216
size_t pg_null_as_len = 0;
32163217
bool free_pg_null = false;
32173218
char *query;
32183219
PGconn *pgsql;
32193220
PGresult *pgsql_result;
32203221
ExecStatusType status;
3221-
char *csv = (char *)NULL;
3222+
char *csv = NULL;
32223223

3223-
ZEND_PARSE_PARAMETERS_START(2, 4)
3224+
ZEND_PARSE_PARAMETERS_START(2, 5)
32243225
Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce)
32253226
Z_PARAM_PATH_STR(table_name)
32263227
Z_PARAM_OPTIONAL
32273228
Z_PARAM_STR(pg_delimiter)
32283229
Z_PARAM_STRING(pg_null_as, pg_null_as_len)
3230+
Z_PARAM_STR(pg_escape)
32293231
ZEND_PARSE_PARAMETERS_END();
32303232

32313233
link = Z_PGSQL_LINK_P(pgsql_link);
@@ -3242,8 +3244,14 @@ PHP_FUNCTION(pg_copy_to)
32423244
pg_null_as = estrdup("\\\\N");
32433245
free_pg_null = true;
32443246
}
3247+
if (!pg_escape) {
3248+
pg_escape = ZSTR_CHAR('"');
3249+
} else if (ZSTR_LEN(pg_escape) != 1) {
3250+
zend_argument_value_error(5, "must be one character");
3251+
RETURN_THROWS();
3252+
}
32453253

3246-
spprintf(&query, 0, "COPY %s TO STDOUT DELIMITER E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), pg_null_as);
3254+
spprintf(&query, 0, "COPY %s TO STDOUT DELIMITER E'%c' ESCAPE E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), *ZSTR_VAL(pg_escape), pg_null_as);
32473255

32483256
while ((pgsql_result = PQgetResult(pgsql))) {
32493257
PQclear(pgsql_result);
@@ -3310,6 +3318,7 @@ PHP_FUNCTION(pg_copy_from)
33103318
zval *value;
33113319
zend_string *table_name;
33123320
zend_string *pg_delimiter = NULL;
3321+
zend_string *pg_escape = NULL;
33133322
char *pg_null_as = NULL;
33143323
size_t pg_null_as_len;
33153324
bool pg_null_as_free = false;
@@ -3318,13 +3327,14 @@ PHP_FUNCTION(pg_copy_from)
33183327
PGresult *pgsql_result;
33193328
ExecStatusType status;
33203329

3321-
ZEND_PARSE_PARAMETERS_START(3, 5)
3330+
ZEND_PARSE_PARAMETERS_START(3, 6)
33223331
Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce)
33233332
Z_PARAM_PATH_STR(table_name)
33243333
Z_PARAM_ARRAY(pg_rows)
33253334
Z_PARAM_OPTIONAL
33263335
Z_PARAM_STR(pg_delimiter)
33273336
Z_PARAM_STRING(pg_null_as, pg_null_as_len)
3337+
Z_PARAM_STR(pg_escape)
33283338
ZEND_PARSE_PARAMETERS_END();
33293339

33303340
link = Z_PGSQL_LINK_P(pgsql_link);
@@ -3341,8 +3351,14 @@ PHP_FUNCTION(pg_copy_from)
33413351
pg_null_as = estrdup("\\\\N");
33423352
pg_null_as_free = true;
33433353
}
3354+
if (!pg_escape) {
3355+
pg_escape = ZSTR_CHAR('"');
3356+
} else if (ZSTR_LEN(pg_escape) != 1) {
3357+
zend_argument_value_error(6, "must be one character");
3358+
RETURN_THROWS();
3359+
}
33443360

3345-
spprintf(&query, 0, "COPY %s FROM STDIN DELIMITER E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), pg_null_as);
3361+
spprintf(&query, 0, "COPY %s FROM STDIN DELIMITER E'%c' ESCAPE E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), *ZSTR_VAL(pg_escape), pg_null_as);
33463362
while ((pgsql_result = PQgetResult(pgsql))) {
33473363
PQclear(pgsql_result);
33483364
}

ext/pgsql/pgsql.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,9 @@ function pg_put_line($connection, string $query = UNKNOWN): bool {}
834834
* @return array<int, string>|false
835835
* @refcount 1
836836
*/
837-
function pg_copy_to(PgSql\Connection $connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N"): array|false {}
837+
function pg_copy_to(PgSql\Connection $connection, string $table_name, string $separator = "\t", string $null_as = "\\\\N", string $escape = "\""): array|false {}
838838

839-
function pg_copy_from(PgSql\Connection $connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N"): bool {}
839+
function pg_copy_from(PgSql\Connection $connection, string $table_name, array $rows, string $separator = "\t", string $null_as = "\\\\N", string $escape = "\""): bool {}
840840

841841
/**
842842
* @param PgSql\Connection|string $connection

ext/pgsql/pgsql_arginfo.h

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)