diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index fe4893a..885345e 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -286,6 +286,16 @@ connect_pg_server(ForeignServer *server, UserMapping *user) /* Prepare new session for use */ configure_remote_session(conn); + /* Free memory for "work_mem" parameter */ + for (int i = 0; i < n; i++) + { + if (strcmp(keywords[i], "options") == 0) + { + pfree((void *)(values[i])); + break; + } + } + pfree(keywords); pfree(values); } diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index d912bd9..c529a00 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -8607,3 +8607,28 @@ SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 -- Clean-up RESET enable_partitionwise_aggregate; +-- =================================================================== +-- test for work_mem option +-- =================================================================== +BEGIN; +CREATE SERVER workmem1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( work_mem '64kB' ); +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'workmem1' +AND srvoptions @> array['work_mem=64kB']; + count +------- + 1 +(1 row) + +ALTER SERVER workmem1 OPTIONS( SET work_mem '8MB' ); +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'workmem1' +AND srvoptions @> array['work_mem=8MB']; + count +------- + 1 +(1 row) + +ROLLBACK; diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c index 6854f1b..f45a50a 100644 --- a/contrib/postgres_fdw/option.c +++ b/contrib/postgres_fdw/option.c @@ -22,7 +22,7 @@ #include "commands/extension.h" #include "utils/builtins.h" #include "utils/varlena.h" - +#include "utils/guc.h" /* * Describes the valid options for objects that this wrapper uses. @@ -143,6 +143,19 @@ postgres_fdw_validator(PG_FUNCTION_ARGS) errmsg("%s requires a non-negative integer value", def->defname))); } + else if (strcmp(def->defname, "work_mem") == 0) + { + int work_mem = 0; + bool result; + result = parse_int(defGetString(def), &work_mem, GUC_UNIT_KB, NULL); + if ((!result) || ((work_mem < 64) || (work_mem > MAX_KILOBYTES))) + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid value for option '%s'", + def->defname))); + } + } } PG_RETURN_VOID(); @@ -177,6 +190,8 @@ InitPgFdwOptions(void) /* fetch_size is available on both server and table */ {"fetch_size", ForeignServerRelationId, false}, {"fetch_size", ForeignTableRelationId, false}, + /* work_mem */ + {"work_mem", ForeignServerRelationId, true}, {NULL, InvalidOid, false} }; @@ -299,6 +314,8 @@ ExtractConnectionOptions(List *defelems, const char **keywords, { ListCell *lc; int i; + static const char options[] = "options"; + char *buf; /* Build our options lists if we didn't yet. */ InitPgFdwOptions(); @@ -310,8 +327,18 @@ ExtractConnectionOptions(List *defelems, const char **keywords, if (is_libpq_option(d->defname)) { - keywords[i] = d->defname; - values[i] = defGetString(d); + if (strcmp(d->defname, "work_mem") == 0) + { + keywords[i] = options; + buf = palloc(128); + sprintf(buf, "-c work_mem=%s", defGetString(d)); + values[i] = buf; + } + else + { + keywords[i] = d->defname; + values[i] = defGetString(d); + } i++; } } diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index c0b0dd9..c450eca 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -2348,3 +2348,24 @@ SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 -- Clean-up RESET enable_partitionwise_aggregate; + +-- =================================================================== +-- test for work_mem option +-- =================================================================== +BEGIN; + +CREATE SERVER workmem1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( work_mem '64kB' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'workmem1' +AND srvoptions @> array['work_mem=64kB']; + +ALTER SERVER workmem1 OPTIONS( SET work_mem '8MB' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'workmem1' +AND srvoptions @> array['work_mem=8MB']; + +ROLLBACK; diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index 54b5e98..50a508e 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -313,6 +313,15 @@ + + work_mem + + + This option specifies the size of working memory using . + The default value is depend on th remote instance setting. + + +