@@ -68,7 +68,9 @@ enum FdwScanPrivateIndex
68
68
/* SQL statement to execute remotely (as a String node) */
69
69
FdwScanPrivateSelectSql ,
70
70
/* Integer list of attribute numbers retrieved by the SELECT */
71
- FdwScanPrivateRetrievedAttrs
71
+ FdwScanPrivateRetrievedAttrs ,
72
+ /* Integer representing the desired fetch_size */
73
+ FdwScanPrivateFetchSize
72
74
};
73
75
74
76
/*
@@ -126,6 +128,8 @@ typedef struct PgFdwScanState
126
128
/* working memory contexts */
127
129
MemoryContext batch_cxt ; /* context holding current batch of tuples */
128
130
MemoryContext temp_cxt ; /* context for per-tuple temporary data */
131
+
132
+ int fetch_size ; /* number of tuples per fetch */
129
133
} PgFdwScanState ;
130
134
131
135
/*
@@ -380,6 +384,7 @@ postgresGetForeignRelSize(PlannerInfo *root,
380
384
fpinfo -> fdw_startup_cost = DEFAULT_FDW_STARTUP_COST ;
381
385
fpinfo -> fdw_tuple_cost = DEFAULT_FDW_TUPLE_COST ;
382
386
fpinfo -> shippable_extensions = NIL ;
387
+ fpinfo -> fetch_size = 100 ;
383
388
384
389
foreach (lc , fpinfo -> server -> options )
385
390
{
@@ -394,16 +399,17 @@ postgresGetForeignRelSize(PlannerInfo *root,
394
399
else if (strcmp (def -> defname , "extensions" ) == 0 )
395
400
fpinfo -> shippable_extensions =
396
401
ExtractExtensionList (defGetString (def ), false);
402
+ else if (strcmp (def -> defname , "fetch_size" ) == 0 )
403
+ fpinfo -> fetch_size = strtol (defGetString (def ), NULL ,10 );
397
404
}
398
405
foreach (lc , fpinfo -> table -> options )
399
406
{
400
407
DefElem * def = (DefElem * ) lfirst (lc );
401
408
402
409
if (strcmp (def -> defname , "use_remote_estimate" ) == 0 )
403
- {
404
410
fpinfo -> use_remote_estimate = defGetBoolean (def );
405
- break ; /* only need the one value */
406
- }
411
+ else if ( strcmp ( def -> defname , "fetch_size" ) == 0 )
412
+ fpinfo -> fetch_size = strtol ( defGetString ( def ), NULL , 10 );
407
413
}
408
414
409
415
/*
@@ -1012,6 +1018,9 @@ postgresGetForeignPlan(PlannerInfo *root,
1012
1018
*/
1013
1019
fdw_private = list_make2 (makeString (sql .data ),
1014
1020
retrieved_attrs );
1021
+ fdw_private = list_make3 (makeString (sql .data ),
1022
+ retrieved_attrs ,
1023
+ makeInteger (fpinfo -> fetch_size ));
1015
1024
1016
1025
/*
1017
1026
* Create the ForeignScan node from target list, filtering expressions,
@@ -1088,6 +1097,8 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags)
1088
1097
FdwScanPrivateSelectSql ));
1089
1098
fsstate -> retrieved_attrs = (List * ) list_nth (fsplan -> fdw_private ,
1090
1099
FdwScanPrivateRetrievedAttrs );
1100
+ fsstate -> fetch_size = intVal (list_nth (fsplan -> fdw_private ,
1101
+ FdwScanPrivateFetchSize ));
1091
1102
1092
1103
/* Create contexts for batches of tuples and per-tuple temp workspace. */
1093
1104
fsstate -> batch_cxt = AllocSetContextCreate (estate -> es_query_cxt ,
@@ -2214,15 +2225,11 @@ fetch_more_data(ForeignScanState *node)
2214
2225
{
2215
2226
PGconn * conn = fsstate -> conn ;
2216
2227
char sql [64 ];
2217
- int fetch_size ;
2218
2228
int numrows ;
2219
2229
int i ;
2220
2230
2221
- /* The fetch size is arbitrary, but shouldn't be enormous. */
2222
- fetch_size = 100 ;
2223
-
2224
2231
snprintf (sql , sizeof (sql ), "FETCH %d FROM c%u" ,
2225
- fetch_size , fsstate -> cursor_number );
2232
+ fsstate -> fetch_size , fsstate -> cursor_number );
2226
2233
2227
2234
res = PQexec (conn , sql );
2228
2235
/* On error, report the original query, not the FETCH. */
@@ -2250,7 +2257,7 @@ fetch_more_data(ForeignScanState *node)
2250
2257
fsstate -> fetch_ct_2 ++ ;
2251
2258
2252
2259
/* Must be EOF if we didn't get as many tuples as we asked for. */
2253
- fsstate -> eof_reached = (numrows < fetch_size );
2260
+ fsstate -> eof_reached = (numrows < fsstate -> fetch_size );
2254
2261
2255
2262
PQclear (res );
2256
2263
res = NULL ;
@@ -2563,6 +2570,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
2563
2570
{
2564
2571
PgFdwAnalyzeState astate ;
2565
2572
ForeignTable * table ;
2573
+ ForeignServer * server ;
2566
2574
UserMapping * user ;
2567
2575
PGconn * conn ;
2568
2576
unsigned int cursor_number ;
@@ -2593,6 +2601,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
2593
2601
* owner, even if the ANALYZE was started by some other user.
2594
2602
*/
2595
2603
table = GetForeignTable (RelationGetRelid (relation ));
2604
+ server = GetForeignServer (table -> serverid );
2596
2605
user = GetUserMapping (relation -> rd_rel -> relowner , table -> serverid );
2597
2606
conn = GetConnection (user , false);
2598
2607
@@ -2620,6 +2629,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
2620
2629
int fetch_size ;
2621
2630
int numrows ;
2622
2631
int i ;
2632
+ ListCell * lc ;
2623
2633
2624
2634
/* Allow users to cancel long query */
2625
2635
CHECK_FOR_INTERRUPTS ();
@@ -2632,6 +2642,26 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
2632
2642
2633
2643
/* The fetch size is arbitrary, but shouldn't be enormous. */
2634
2644
fetch_size = 100 ;
2645
+ foreach (lc , server -> options )
2646
+ {
2647
+ DefElem * def = (DefElem * ) lfirst (lc );
2648
+
2649
+ if (strcmp (def -> defname , "fetch_size" ) == 0 )
2650
+ {
2651
+ fetch_size = strtol (defGetString (def ), NULL ,10 );
2652
+ break ;
2653
+ }
2654
+ }
2655
+ foreach (lc , table -> options )
2656
+ {
2657
+ DefElem * def = (DefElem * ) lfirst (lc );
2658
+
2659
+ if (strcmp (def -> defname , "fetch_size" ) == 0 )
2660
+ {
2661
+ fetch_size = strtol (defGetString (def ), NULL ,10 );
2662
+ break ;
2663
+ }
2664
+ }
2635
2665
2636
2666
/* Fetch some rows */
2637
2667
snprintf (fetch_sql , sizeof (fetch_sql ), "FETCH %d FROM c%u" ,
0 commit comments