diff options
Diffstat (limited to 'contrib/file_fdw/file_fdw.c')
-rw-r--r-- | contrib/file_fdw/file_fdw.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c index 2d2b0b6a6b9..99b21e8316d 100644 --- a/contrib/file_fdw/file_fdw.c +++ b/contrib/file_fdw/file_fdw.c @@ -72,6 +72,7 @@ static const struct FileFdwOption valid_options[] = { {"quote", ForeignTableRelationId}, {"escape", ForeignTableRelationId}, {"null", ForeignTableRelationId}, + {"default", ForeignTableRelationId}, {"encoding", ForeignTableRelationId}, {"force_not_null", AttributeRelationId}, {"force_null", AttributeRelationId}, @@ -712,6 +713,9 @@ static TupleTableSlot * fileIterateForeignScan(ForeignScanState *node) { FileFdwExecutionState *festate = (FileFdwExecutionState *) node->fdw_state; + EState *estate = CreateExecutorState(); + ExprContext *econtext; + MemoryContext oldcontext; TupleTableSlot *slot = node->ss.ss_ScanTupleSlot; bool found; ErrorContextCallback errcallback; @@ -728,15 +732,25 @@ fileIterateForeignScan(ForeignScanState *node) * ExecStoreVirtualTuple. If we don't find another row in the file, we * just skip the last step, leaving the slot empty as required. * - * We can pass ExprContext = NULL because we read all columns from the - * file, so no need to evaluate default expressions. + * We pass ExprContext because there might be a use of the DEFAULT option + * in COPY FROM, so we may need to evaluate default expressions. */ ExecClearTuple(slot); - found = NextCopyFrom(festate->cstate, NULL, + econtext = GetPerTupleExprContext(estate); + + /* + * DEFAULT expressions need to be evaluated in a per-tuple context, so + * switch in case we are doing that. + */ + oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + found = NextCopyFrom(festate->cstate, econtext, slot->tts_values, slot->tts_isnull); if (found) ExecStoreVirtualTuple(slot); + /* Switch back to original memory context */ + MemoryContextSwitchTo(oldcontext); + /* Remove error callback. */ error_context_stack = errcallback.previous; |