summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeFunctionscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeFunctionscan.c')
-rw-r--r--src/backend/executor/nodeFunctionscan.c469
1 files changed, 0 insertions, 469 deletions
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
deleted file mode 100644
index 3645a188334..00000000000
--- a/src/backend/executor/nodeFunctionscan.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * nodeFunctionscan.c
- * Support routines for scanning RangeFunctions (functions in rangetable).
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.2 2002/06/20 20:29:28 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-/*
- * INTERFACE ROUTINES
- * ExecFunctionScan scans a function.
- * ExecFunctionNext retrieve next tuple in sequential order.
- * ExecInitFunctionScan creates and initializes a functionscan node.
- * ExecEndFunctionScan releases any storage allocated.
- * ExecFunctionReScan rescans the function
- */
-#include "postgres.h"
-
-#include "miscadmin.h"
-#include "access/heapam.h"
-#include "catalog/pg_type.h"
-#include "executor/execdebug.h"
-#include "executor/execdefs.h"
-#include "executor/execdesc.h"
-#include "executor/nodeFunctionscan.h"
-#include "parser/parsetree.h"
-#include "parser/parse_expr.h"
-#include "parser/parse_type.h"
-#include "storage/lmgr.h"
-#include "tcop/pquery.h"
-#include "utils/lsyscache.h"
-#include "utils/syscache.h"
-#include "utils/tuplestore.h"
-
-static TupleTableSlot *FunctionNext(FunctionScan *node);
-static TupleTableSlot *function_getonetuple(TupleTableSlot *slot,
- Node *expr,
- ExprContext *econtext,
- TupleDesc tupdesc,
- bool returnsTuple,
- bool *isNull,
- ExprDoneCond *isDone);
-static FunctionMode get_functionmode(Node *expr);
-
-/* ----------------------------------------------------------------
- * Scan Support
- * ----------------------------------------------------------------
- */
-/* ----------------------------------------------------------------
- * FunctionNext
- *
- * This is a workhorse for ExecFunctionScan
- * ----------------------------------------------------------------
- */
-static TupleTableSlot *
-FunctionNext(FunctionScan *node)
-{
- TupleTableSlot *slot;
- Node *expr;
- ExprContext *econtext;
- TupleDesc tupdesc;
- EState *estate;
- ScanDirection direction;
- Tuplestorestate *tuplestorestate;
- FunctionScanState *scanstate;
- bool should_free;
- HeapTuple heapTuple;
-
- /*
- * get information from the estate and scan state
- */
- scanstate = (FunctionScanState *) node->scan.scanstate;
- estate = node->scan.plan.state;
- direction = estate->es_direction;
- econtext = scanstate->csstate.cstate.cs_ExprContext;
-
- tuplestorestate = scanstate->tuplestorestate;
- tupdesc = scanstate->tupdesc;
- expr = scanstate->funcexpr;
-
- /*
- * If first time through, read all tuples from function and pass them to
- * tuplestore.c. Subsequent calls just fetch tuples from tuplestore.
- */
- if (tuplestorestate == NULL)
- {
- /*
- * Initialize tuplestore module.
- */
- tuplestorestate = tuplestore_begin_heap(true, /* randomAccess */
- SortMem);
-
- scanstate->tuplestorestate = (void *) tuplestorestate;
-
- /*
- * Compute all the function tuples and pass to tuplestore.
- */
- for (;;)
- {
- bool isNull;
- ExprDoneCond isDone;
-
- isNull = false;
- isDone = ExprSingleResult;
- slot = function_getonetuple(scanstate->csstate.css_ScanTupleSlot,
- expr, econtext, tupdesc,
- scanstate->returnsTuple,
- &isNull, &isDone);
- if (TupIsNull(slot))
- break;
-
- tuplestore_puttuple(tuplestorestate, (void *) slot->val);
- ExecClearTuple(slot);
-
- if (isDone != ExprMultipleResult)
- break;
- }
-
- /*
- * Complete the store.
- */
- tuplestore_donestoring(tuplestorestate);
- }
-
- /*
- * Get the next tuple from tuplestore. Return NULL if no more tuples.
- */
- slot = scanstate->csstate.css_ScanTupleSlot;
- heapTuple = tuplestore_getheaptuple(tuplestorestate,
- ScanDirectionIsForward(direction),
- &should_free);
-
- return ExecStoreTuple(heapTuple, slot, InvalidBuffer, should_free);
-}
-
-/* ----------------------------------------------------------------
- * ExecFunctionScan(node)
- *
- * Scans the Function sequentially and returns the next qualifying
- * tuple.
- * It calls the ExecScan() routine and passes it the access method
- * which retrieve tuples sequentially.
- *
- */
-
-TupleTableSlot *
-ExecFunctionScan(FunctionScan *node)
-{
- /*
- * use FunctionNext as access method
- */
- return ExecScan(&node->scan, (ExecScanAccessMtd) FunctionNext);
-}
-
-/* ----------------------------------------------------------------
- * ExecInitFunctionScan
- * ----------------------------------------------------------------
- */
-bool
-ExecInitFunctionScan(FunctionScan *node, EState *estate, Plan *parent)
-{
- FunctionScanState *scanstate;
- RangeTblEntry *rte;
- Oid funcrettype;
- Oid funcrelid;
- TupleDesc tupdesc;
-
- /*
- * FunctionScan should not have any children.
- */
- Assert(outerPlan((Plan *) node) == NULL);
- Assert(innerPlan((Plan *) node) == NULL);
-
- /*
- * assign the node's execution state
- */
- node->scan.plan.state = estate;
-
- /*
- * create new ScanState for node
- */
- scanstate = makeNode(FunctionScanState);
- node->scan.scanstate = &scanstate->csstate;
-
- /*
- * Miscellaneous initialization
- *
- * create expression context for node
- */
- ExecAssignExprContext(estate, &scanstate->csstate.cstate);
-
-#define FUNCTIONSCAN_NSLOTS 2
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->csstate.cstate);
- ExecInitScanTupleSlot(estate, &scanstate->csstate);
-
- /*
- * get info about function
- */
- rte = rt_fetch(node->scan.scanrelid, estate->es_range_table);
- Assert(rte->rtekind == RTE_FUNCTION);
- funcrettype = exprType(rte->funcexpr);
- funcrelid = typeidTypeRelid(funcrettype);
-
- /*
- * Build a suitable tupledesc representing the output rows
- */
- if (OidIsValid(funcrelid))
- {
- /*
- * Composite data type, i.e. a table's row type
- * Same as ordinary relation RTE
- */
- Relation rel;
-
- rel = relation_open(funcrelid, AccessShareLock);
- tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
- relation_close(rel, AccessShareLock);
- scanstate->returnsTuple = true;
- }
- else
- {
- /*
- * Must be a base data type, i.e. scalar
- */
- char *attname = strVal(lfirst(rte->eref->colnames));
-
- tupdesc = CreateTemplateTupleDesc(1);
- TupleDescInitEntry(tupdesc,
- (AttrNumber) 1,
- attname,
- funcrettype,
- -1,
- 0,
- false);
- scanstate->returnsTuple = false;
- }
- scanstate->tupdesc = tupdesc;
- ExecSetSlotDescriptor(scanstate->csstate.css_ScanTupleSlot,
- tupdesc, false);
-
- /*
- * Other node-specific setup
- */
- scanstate->tuplestorestate = NULL;
- scanstate->funcexpr = rte->funcexpr;
-
- scanstate->functionmode = get_functionmode(rte->funcexpr);
-
- scanstate->csstate.cstate.cs_TupFromTlist = false;
-
- /*
- * initialize tuple type
- */
- ExecAssignResultTypeFromTL((Plan *) node, &scanstate->csstate.cstate);
- ExecAssignProjectionInfo((Plan *) node, &scanstate->csstate.cstate);
-
- return TRUE;
-}
-
-int
-ExecCountSlotsFunctionScan(FunctionScan *node)
-{
- return ExecCountSlotsNode(outerPlan(node)) +
- ExecCountSlotsNode(innerPlan(node)) +
- FUNCTIONSCAN_NSLOTS;
-}
-
-/* ----------------------------------------------------------------
- * ExecEndFunctionScan
- *
- * frees any storage allocated through C routines.
- * ----------------------------------------------------------------
- */
-void
-ExecEndFunctionScan(FunctionScan *node)
-{
- FunctionScanState *scanstate;
- EState *estate;
-
- /*
- * get information from node
- */
- scanstate = (FunctionScanState *) node->scan.scanstate;
- estate = node->scan.plan.state;
-
- /*
- * Free the projection info and the scan attribute info
- *
- * Note: we don't ExecFreeResultType(scanstate) because the rule manager
- * depends on the tupType returned by ExecMain(). So for now, this is
- * freed at end-transaction time. -cim 6/2/91
- */
- ExecFreeProjectionInfo(&scanstate->csstate.cstate);
- ExecFreeExprContext(&scanstate->csstate.cstate);
-
- /*
- * clean out the tuple table
- */
- ExecClearTuple(scanstate->csstate.cstate.cs_ResultTupleSlot);
- ExecClearTuple(scanstate->csstate.css_ScanTupleSlot);
-
- /*
- * Release tuplestore resources
- */
- if (scanstate->tuplestorestate != NULL)
- tuplestore_end((Tuplestorestate *) scanstate->tuplestorestate);
- scanstate->tuplestorestate = NULL;
-}
-
-/* ----------------------------------------------------------------
- * ExecFunctionMarkPos
- *
- * Calls tuplestore to save the current position in the stored file.
- * ----------------------------------------------------------------
- */
-void
-ExecFunctionMarkPos(FunctionScan *node)
-{
- FunctionScanState *scanstate;
-
- scanstate = (FunctionScanState *) node->scan.scanstate;
-
- /*
- * if we haven't materialized yet, just return.
- */
- if (!scanstate->tuplestorestate)
- return;
-
- tuplestore_markpos((Tuplestorestate *) scanstate->tuplestorestate);
-}
-
-/* ----------------------------------------------------------------
- * ExecFunctionRestrPos
- *
- * Calls tuplestore to restore the last saved file position.
- * ----------------------------------------------------------------
- */
-void
-ExecFunctionRestrPos(FunctionScan *node)
-{
- FunctionScanState *scanstate;
-
- scanstate = (FunctionScanState *) node->scan.scanstate;
-
- /*
- * if we haven't materialized yet, just return.
- */
- if (!scanstate->tuplestorestate)
- return;
-
- tuplestore_restorepos((Tuplestorestate *) scanstate->tuplestorestate);
-}
-
-/* ----------------------------------------------------------------
- * ExecFunctionReScan
- *
- * Rescans the relation.
- * ----------------------------------------------------------------
- */
-void
-ExecFunctionReScan(FunctionScan *node, ExprContext *exprCtxt, Plan *parent)
-{
- FunctionScanState *scanstate;
-
- /*
- * get information from node
- */
- scanstate = (FunctionScanState *) node->scan.scanstate;
-
- ExecClearTuple(scanstate->csstate.cstate.cs_ResultTupleSlot);
-
- /*
- * If we haven't materialized yet, just return.
- */
- if (!scanstate->tuplestorestate)
- return;
-
- /*
- * Here we have a choice whether to drop the tuplestore (and recompute
- * the function outputs) or just rescan it. This should depend on
- * whether the function expression contains parameters and/or is
- * marked volatile. FIXME soon.
- */
- if (node->scan.plan.chgParam != NULL)
- {
- tuplestore_end((Tuplestorestate *) scanstate->tuplestorestate);
- scanstate->tuplestorestate = NULL;
- }
- else
- tuplestore_rescan((Tuplestorestate *) scanstate->tuplestorestate);
-}
-
-/*
- * Run the underlying function to get the next tuple
- */
-static TupleTableSlot *
-function_getonetuple(TupleTableSlot *slot,
- Node *expr,
- ExprContext *econtext,
- TupleDesc tupdesc,
- bool returnsTuple,
- bool *isNull,
- ExprDoneCond *isDone)
-{
- HeapTuple tuple;
- Datum retDatum;
- char nullflag;
-
- /*
- * get the next Datum from the function
- */
- retDatum = ExecEvalExprSwitchContext(expr, econtext, isNull, isDone);
-
- /*
- * check to see if we're really done
- */
- if (*isDone == ExprEndResult)
- slot = NULL;
- else
- {
- if (returnsTuple)
- {
- /*
- * Composite data type, i.e. a table's row type
- * function returns pointer to tts??
- */
- slot = (TupleTableSlot *) retDatum;
- }
- else
- {
- /*
- * Must be a base data type, i.e. scalar
- * turn it into a tuple
- */
- nullflag = *isNull ? 'n' : ' ';
- tuple = heap_formtuple(tupdesc, &retDatum, &nullflag);
-
- /*
- * save the tuple in the scan tuple slot and return the slot.
- */
- slot = ExecStoreTuple(tuple, /* tuple to store */
- slot, /* slot to store in */
- InvalidBuffer, /* buffer associated with
- * this tuple */
- true); /* pfree this pointer */
- }
- }
-
- return slot;
-}
-
-static FunctionMode
-get_functionmode(Node *expr)
-{
- /*
- * for the moment, hardwire this
- */
- return PM_REPEATEDCALL;
-}