summaryrefslogtreecommitdiff
path: root/contrib/file_fdw/file_fdw.c
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2023-03-13 10:01:56 -0400
committerAndrew Dunstan <andrew@dunslane.net>2023-03-13 10:01:56 -0400
commit9f8377f7a27910bf0f35bf5169a8046731948a79 (patch)
treee0a19449e4cebb8923dfcd1bba95a1d3363faa32 /contrib/file_fdw/file_fdw.c
parent7b14e20b12cc8358cad9bdd05dd6b7de7f73c431 (diff)
Add a DEFAULT option to COPY FROM
This allows for a string which if an input field matches causes the column's default value to be inserted. The advantage of this is that the default can be inserted in some rows and not others, for which non-default data is available. The file_fdw extension is also modified to take allow use of this option. Israel Barth Rubio Discussion: https://postgr.es/m/CAO_rXXAcqesk6DsvioOZ5zmeEmpUN5ktZf-9=9yu+DTr0Xr8Uw@mail.gmail.com
Diffstat (limited to 'contrib/file_fdw/file_fdw.c')
-rw-r--r--contrib/file_fdw/file_fdw.c20
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;