Skip to content

Commit aa7c74c

Browse files
committed
Support num_segments option for foreign servers and tables
Support specifying the num_segments option for foreign servers and tables, Greenplum will create that amount of QEs if the `mpp_execute` option's value is 'all segments'. ``` CREATE FOREIGN TABLE ft1 ( c1 int ) SERVER s1 OPTIONS (mpp_execute 'all segments', num_segments '42'); ```
1 parent bd3562a commit aa7c74c

File tree

8 files changed

+83
-4
lines changed

8 files changed

+83
-4
lines changed

src/backend/commands/foreigncmds.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,14 @@ transformGenericOptions(Oid catalogId,
188188
result = optionListToArray(resultOptions);
189189

190190
/*
191-
* Check and separate out the mpp_execute option, fdwvalidator doesn't have
191+
* Check and separate out the extra options, fdwvalidator doesn't have
192192
* to handle it. USER MAPPING doesn't have the mpp_execute option.
193193
*/
194194
if (catalogId != UserMappingRelationId)
195+
{
195196
SeparateOutMppExecute(&resultOptions);
197+
SeparateOutNumSegments(&resultOptions);
198+
}
196199

197200
if (OidIsValid(fdwvalidator))
198201
{

src/backend/foreign/foreign.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "catalog/pg_foreign_server.h"
1919
#include "catalog/pg_foreign_table.h"
2020
#include "catalog/pg_user_mapping.h"
21+
#include "cdb/cdbutil.h"
2122
#include "commands/defrem.h"
2223
#include "foreign/fdwapi.h"
2324
#include "foreign/foreign.h"
@@ -74,6 +75,41 @@ SeparateOutMppExecute(List **options)
7475
return exec_location;
7576
}
7677

78+
/* Get and separate out the num_segments option */
79+
int32
80+
SeparateOutNumSegments(List **options)
81+
{
82+
ListCell *lc = NULL;
83+
ListCell *prev = NULL;
84+
char *num_segments_str = NULL;
85+
int32 num_segments = 0;
86+
87+
foreach(lc, *options)
88+
{
89+
DefElem *def = (DefElem *) lfirst(lc);
90+
91+
if (strcmp(def->defname, "num_segments") == 0)
92+
{
93+
num_segments_str = defGetString(def);
94+
num_segments = pg_atoi(num_segments_str, sizeof(int32), 0);
95+
96+
if (num_segments <= 0)
97+
{
98+
ereport(ERROR,
99+
(errcode(ERRCODE_SYNTAX_ERROR),
100+
errmsg("\"%d\" is not a valid num_segments value",
101+
num_segments)));
102+
}
103+
104+
*options = list_delete_cell(*options, lc, prev);
105+
break;
106+
}
107+
108+
prev = lc;
109+
}
110+
return num_segments;
111+
}
112+
77113
/*
78114
* GetForeignDataWrapper - look up the foreign-data wrapper by OID.
79115
*/
@@ -224,6 +260,12 @@ GetForeignServerExtended(Oid serverid, bits16 flags)
224260
server->exec_location = fdw->exec_location;
225261
}
226262

263+
server->num_segments = SeparateOutNumSegments(&server->options);
264+
if (server->num_segments <= 0)
265+
{
266+
server->num_segments = getgpsegmentCount();
267+
}
268+
227269
ReleaseSysCache(tp);
228270

229271
return server;
@@ -329,13 +371,20 @@ GetForeignTable(Oid relid)
329371
else
330372
ft->options = untransformRelOptions(datum);
331373

374+
ForeignServer *server = GetForeignServer(ft->serverid);
375+
332376
ft->exec_location = SeparateOutMppExecute(&ft->options);
333377
if (ft->exec_location == FTEXECLOCATION_NOT_DEFINED)
334378
{
335-
ForeignServer *server = GetForeignServer(ft->serverid);
336379
ft->exec_location = server->exec_location;
337380
}
338381

382+
ft->num_segments = SeparateOutNumSegments(&ft->options);
383+
if (ft->num_segments <= 0)
384+
{
385+
ft->num_segments = server->num_segments;
386+
}
387+
339388
ReleaseSysCache(tp);
340389

341390
return ft;

src/backend/optimizer/util/pathnode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,7 +3318,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
33183318
CdbPathLocus_MakeGeneral(&(pathnode->path.locus));
33193319
break;
33203320
case FTEXECLOCATION_ALL_SEGMENTS:
3321-
CdbPathLocus_MakeStrewn(&(pathnode->path.locus), getgpsegmentCount());
3321+
CdbPathLocus_MakeStrewn(&(pathnode->path.locus), rel->num_segments);
33223322
break;
33233323
case FTEXECLOCATION_COORDINATOR:
33243324
CdbPathLocus_MakeEntry(&(pathnode->path.locus));
@@ -3383,7 +3383,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel,
33833383
CdbPathLocus_MakeGeneral(&(pathnode->path.locus));
33843384
break;
33853385
case FTEXECLOCATION_ALL_SEGMENTS:
3386-
CdbPathLocus_MakeStrewn(&(pathnode->path.locus), getgpsegmentCount());
3386+
CdbPathLocus_MakeStrewn(&(pathnode->path.locus), rel->num_segments);
33873387
break;
33883388
case FTEXECLOCATION_COORDINATOR:
33893389
CdbPathLocus_MakeEntry(&(pathnode->path.locus));

src/backend/optimizer/util/plancat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
#include "cdb/cdbappendonlyam.h"
6060
#include "cdb/cdbrelsize.h"
61+
#include "cdb/cdbutil.h"
6162
#include "catalog/pg_appendonly.h"
6263
#include "catalog/pg_foreign_server.h"
6364
#include "catalog/pg_inherits.h"
@@ -456,12 +457,14 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
456457
rel->serverid = GetForeignServerIdByRelId(RelationGetRelid(relation));
457458
rel->fdwroutine = GetFdwRoutineForRelation(relation, true);
458459
rel->exec_location = GetForeignTable(RelationGetRelid(relation))->exec_location;
460+
rel->num_segments = GetForeignTable(RelationGetRelid(relation))->num_segments;
459461
}
460462
else
461463
{
462464
rel->serverid = InvalidOid;
463465
rel->fdwroutine = NULL;
464466
rel->exec_location = FTEXECLOCATION_NOT_DEFINED;
467+
rel->num_segments = getgpsegmentCount();
465468
}
466469

467470
/* Collect info about relation's foreign keys, if relevant */

src/include/foreign/foreign.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ typedef struct ForeignServer
5353
char *serverversion; /* server version, optional */
5454
List *options; /* srvoptions as DefElem list */
5555
char exec_location; /* execute on MASTER, ANY or ALL SEGMENTS, Greenplum MPP specific */
56+
int32 num_segments; /* the number of segments of the foreign cluster */
5657
} ForeignServer;
5758

5859
typedef struct UserMapping
@@ -69,6 +70,7 @@ typedef struct ForeignTable
6970
Oid serverid; /* server Oid */
7071
List *options; /* ftoptions as DefElem list */
7172
char exec_location; /* execute on COORDINATOR, ANY or ALL SEGMENTS, Greenplum MPP specific */
73+
int32 num_segments; /* the number of segments of the foreign table */
7274
} ForeignTable;
7375

7476
/* Flags for GetForeignServerExtended */
@@ -79,6 +81,7 @@ typedef struct ForeignTable
7981

8082

8183
extern char SeparateOutMppExecute(List **options);
84+
extern int32 SeparateOutNumSegments(List **options);
8285
extern ForeignServer *GetForeignServer(Oid serverid);
8386
extern ForeignServer *GetForeignServerExtended(Oid serverid,
8487
bits16 flags);

src/include/nodes/pathnodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ typedef struct RelOptInfo
864864
Oid userid; /* identifies user to check access as */
865865
bool useridiscurrent; /* join is only valid for current user */
866866
char exec_location; /* execute on MASTER, ANY or ALL SEGMENTS, Greenplum MPP specific */
867+
int32 num_segments; /* number of segments, Greenplum MPP specific */
867868
/* use "struct FdwRoutine" to avoid including fdwapi.h here */
868869
struct FdwRoutine *fdwroutine;
869870
void *fdw_private;

src/test/regress/expected/gp_foreign_data.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,16 @@ CREATE FOREIGN TABLE ft3 (
2626
CREATE FOREIGN TABLE ft4 (
2727
c1 int
2828
) SERVER s0 OPTIONS (delimiter ',', mpp_execute 'all segments');
29+
-- Test num_segments option
30+
CREATE SERVER s1 FOREIGN DATA WRAPPER dummy OPTIONS (num_segments '3');
31+
CREATE FOREIGN TABLE ft5 (
32+
c1 int
33+
) SERVER s1 OPTIONS (delimiter ',', mpp_execute 'all segments', num_segments '5');
34+
\d+ ft5
35+
Foreign table "public.ft5"
36+
Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description
37+
--------+---------+-----------+----------+---------+-------------+---------+--------------+-------------
38+
c1 | integer | | | | | plain | |
39+
Server: s1
40+
FDW options: (delimiter ',', mpp_execute 'all segments', num_segments '5')
41+

src/test/regress/sql/gp_foreign_data.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,10 @@ CREATE FOREIGN TABLE ft3 (
2424
CREATE FOREIGN TABLE ft4 (
2525
c1 int
2626
) SERVER s0 OPTIONS (delimiter ',', mpp_execute 'all segments');
27+
28+
-- Test num_segments option
29+
CREATE SERVER s1 FOREIGN DATA WRAPPER dummy OPTIONS (num_segments '3');
30+
CREATE FOREIGN TABLE ft5 (
31+
c1 int
32+
) SERVER s1 OPTIONS (delimiter ',', mpp_execute 'all segments', num_segments '5');
33+
\d+ ft5

0 commit comments

Comments
 (0)