Skip to content

Commit 6afdf87

Browse files
committed
textarray framework, compiles but does not do anything yet
1 parent 0017ad5 commit 6afdf87

File tree

1 file changed

+65
-6
lines changed

1 file changed

+65
-6
lines changed

contrib/file_fdw/file_fdw.c

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
#include "postgres.h"
1515

16+
#include <sys/types.h>
17+
#include <sys/stat.h>
18+
#include <unistd.h>
19+
1620
#include "access/reloptions.h"
1721
#include "catalog/pg_foreign_table.h"
1822
#include "catalog/pg_foreign_server.h"
@@ -61,7 +65,10 @@ static struct FileFdwOption valid_options[] = {
6165

6266
/* FIXME: implement force_not_null option */
6367

64-
/* Centinel */
68+
/* Local option */
69+
{ "textarray", ForeignTableRelationId },
70+
71+
/* Sentinel */
6572
{ NULL, InvalidOid }
6673
};
6774

@@ -70,8 +77,9 @@ static struct FileFdwOption valid_options[] = {
7077
*/
7178
typedef struct FileFdwPrivate {
7279
char *filename;
80+
bool textarray; /* make a text array rather than a tuple */
7381
Relation rel; /* scan target relation */
74-
CopyState cstate; /* state of reaind file */
82+
CopyState cstate; /* state of read in file */
7583
List *options; /* merged generic options, excluding filename */
7684
} FileFdwPrivate;
7785

@@ -91,6 +99,8 @@ static void fileIterate(FdwExecutionState *festate, TupleTableSlot *slot);
9199
static void fileEndScan(FdwExecutionState *festate);
92100
static void fileReScan(FdwExecutionState *festate);
93101

102+
/* text array support */
103+
static void makeTextArray(TupleTableSlot *slot, char **raw_fields, int nfields);
94104
/*
95105
* Helper functions
96106
*/
@@ -142,7 +152,7 @@ file_fdw_validator(PG_FUNCTION_ARGS)
142152
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
143153
errmsg("only superuser can change foreign table options")));
144154

145-
/* Vaidate each options */
155+
/* Validate each options */
146156
foreach(cell, options_list)
147157
{
148158
DefElem *def = lfirst(cell);
@@ -298,6 +308,8 @@ filePlanRelScan(Oid foreigntableid, PlannerInfo *root, RelOptInfo *rel)
298308
{
299309
Const *relid;
300310
Value *filename = NULL;
311+
bool textarray = false;
312+
Const *textarray_param;
301313
ulong size;
302314
FdwPlan *fplan;
303315
ForeignTable *table;
@@ -346,6 +358,30 @@ filePlanRelScan(Oid foreigntableid, PlannerInfo *root, RelOptInfo *rel)
346358
(errcode(ERRCODE_FDW_UNABLE_TO_CREATE_REPLY),
347359
errmsg("filename is required for file_fdw scan")));
348360

361+
/*
362+
* Split textarray option off from the list because it's handled
363+
* here instead of being passed as another parameter to BeginCopyFrom().
364+
*/
365+
prev = NULL;
366+
foreach (lc, options)
367+
{
368+
DefElem *def = lfirst(lc);
369+
if (strcmp(def->defname, "textarray") == 0)
370+
{
371+
textarray = defGetBoolean(def);
372+
options = list_delete_cell(options, lc, prev);
373+
break;
374+
}
375+
prev = lc;
376+
}
377+
textarray_param = (Const *) makeBoolConst(textarray,false);
378+
379+
if (text_array)
380+
{
381+
/* make sure the table has one column and it's oy type text[] */
382+
/* XXX fill in this piece */
383+
}
384+
349385
/* Construct FdwPlan and store relid and options in private area */
350386
fplan = makeNode(FdwPlan);
351387
size = estimate_costs(strVal(filename), rel,
@@ -354,6 +390,7 @@ filePlanRelScan(Oid foreigntableid, PlannerInfo *root, RelOptInfo *rel)
354390
fplan->fdw_private = NIL;
355391
fplan->fdw_private = lappend(fplan->fdw_private, relid);
356392
fplan->fdw_private = lappend(fplan->fdw_private, filename);
393+
fplan->fdw_private = lappend(fplan->fdw_private, textarray_param);
357394
fplan->fdw_private = lappend(fplan->fdw_private, options);
358395

359396
return fplan;
@@ -374,6 +411,7 @@ fileBeginScan(FdwPlan *fplan, ParamListInfo params)
374411
Const *relid_const;
375412
Oid relid;
376413
Value *filename;
414+
Const *textarray;
377415
List *options;
378416
Relation rel;
379417
CopyState cstate;
@@ -385,7 +423,8 @@ fileBeginScan(FdwPlan *fplan, ParamListInfo params)
385423
/* Get oid of the relation and option list from private area of FdwPlan. */
386424
relid_const = list_nth(fplan->fdw_private, 0);
387425
filename = list_nth(fplan->fdw_private, 1);
388-
options = list_nth(fplan->fdw_private, 2);
426+
textarray = list_nth(fplan->fdw_private, 2);
427+
options = list_nth(fplan->fdw_private, 3);
389428

390429
relid = DatumGetObjectId(relid_const->constvalue);
391430

@@ -405,6 +444,7 @@ fileBeginScan(FdwPlan *fplan, ParamListInfo params)
405444
festate = palloc0(sizeof(FdwExecutionState));
406445
fdw_private = palloc0(sizeof(FileFdwPrivate));
407446
fdw_private->filename = strVal(filename);
447+
fdw_private->textarray = textarray->constvalue;
408448
fdw_private->rel = rel;
409449
fdw_private->cstate = cstate;
410450
fdw_private->options = options;
@@ -438,8 +478,22 @@ fileIterate(FdwExecutionState *festate, TupleTableSlot *slot)
438478
* EOF.
439479
*/
440480
ExecClearTuple(slot);
441-
found = NextCopyFrom(fdw_private->cstate, slot->tts_values, slot->tts_isnull,
442-
NULL);
481+
if (fdw_private->textarray)
482+
{
483+
char **raw_fields;
484+
int nfields;
485+
486+
found = NextLineCopyFrom(fdw_private->cstate, &raw_fields, &nfields,
487+
NULL);
488+
if (found)
489+
makeTextArray(slot, raw_fields, nfields);
490+
}
491+
else
492+
{
493+
/* let the COPY code do the work */
494+
found = NextCopyFrom(fdw_private->cstate, slot->tts_values,
495+
slot->tts_isnull, NULL);
496+
}
443497
if (found)
444498
ExecStoreVirtualTuple(slot);
445499

@@ -546,3 +600,8 @@ estimate_costs(const char *filename, RelOptInfo *baserel,
546600
return stat_buf.st_size;
547601
}
548602

603+
static void
604+
makeTextArray(TupleTableSlot *slot, char **raw_fields, int nfields)
605+
{
606+
607+
}

0 commit comments

Comments
 (0)