aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2002-07-24 19:16:43 +0000
committerPeter Eisentraut <peter_e@gmx.net>2002-07-24 19:16:43 +0000
commit43515ba3f8523e492143e2a1a1159022b5424431 (patch)
tree869ce476017bc4bfd40b781717f7846bc79c1f05 /src/backend/commands
parent739adf32eecfe129aea09f543370d886045c7c01 (diff)
downloadpostgresql-43515ba3f8523e492143e2a1a1159022b5424431.tar.gz
postgresql-43515ba3f8523e492143e2a1a1159022b5424431.zip
Remove _deadcode.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/_deadcode/recipe.c1318
-rw-r--r--src/backend/commands/_deadcode/version.c346
2 files changed, 0 insertions, 1664 deletions
diff --git a/src/backend/commands/_deadcode/recipe.c b/src/backend/commands/_deadcode/recipe.c
deleted file mode 100644
index f1b3d84ab48..00000000000
--- a/src/backend/commands/_deadcode/recipe.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * recipe.c
- * routines for handling execution of Tioga recipes
- *
- * 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/commands/_deadcode/Attic/recipe.c,v 1.17 2002/06/20 20:29:27 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "catalog/pg_type.h"
-#include "commands/recipe.h"
-#include "executor/executor.h"
-#include "libpq/libpq-be.h"
-#include "nodes/execnodes.h"
-#include "nodes/makefuncs.h"
-#include "nodes/parsenodes.h"
-#include "nodes/plannodes.h"
-#include "optimizer/planner.h"
-#include "parser/parse_node.h"
-#include "rewrite/rewriteHandler.h"
-#include "rewrite/rewriteManip.h"
-#include "tcop/dest.h"
-#include "tcop/pquery.h"
-#include "utils/builtins.h"
-#include "utils/relcache.h"
-
-/* from tcop/postgres.c */
-extern CommandDest whereToSendOutput;
-
-#ifndef TIOGA
-
-void
-beginRecipe(RecipeStmt *stmt)
-{
- elog(WARNING, "You must compile with TIOGA defined in order to use recipes\n");
-}
-
-#else
-
-#include "tioga/tgRecipe.h"
-
-#define DEBUG_RECIPE 1
-
-/* structure to keep track of the tee node plans */
-typedef struct _teePlanInfo
-{
- char *tpi_relName;
- Query *tpi_parsetree;
- Plan *tpi_plan;
-} TeePlanInfo;
-
-typedef struct _teeInfo
-{
- int num;
- TeePlanInfo *val;
-} TeeInfo;
-
-QueryTreeList *appendQlist(QueryTreeList * q1, QueryTreeList * q2);
-void OffsetVarAttno(Node *node, int varno, int offset);
-
-static void appendTeeQuery(TeeInfo * teeInfo,
- QueryTreeList * q,
- char *teeNodeName);
-
-static Plan *replaceTeeScans(Plan *plan,
- Query *parsetree,
- TeeInfo * teeInfo);
-static void replaceSeqScan(Plan *plan,
- Plan *parent,
- int rt_ind,
- Plan *tplan);
-
-static void tg_rewriteQuery(TgRecipe * r, TgNode * n,
- QueryTreeList * q,
- QueryTreeList * inputQlist);
-static Node *tg_replaceNumberedParam(Node *expression,
- int pnum,
- int rt_ind,
- char *teeRelName);
-static Node *tg_rewriteParamsInExpr(Node *expression,
- QueryTreeList * inputQlist);
-static QueryTreeList *tg_parseSubQuery(TgRecipe * r,
- TgNode * n,
- TeeInfo * teeInfo);
-static QueryTreeList *tg_parseTeeNode(TgRecipe * r,
- TgNode * n,
- int i,
- QueryTreeList * qList,
- TeeInfo * teeInfo);
-
-
-/*
- The Tioga recipe rewrite algorithm:
-
- To parse a Tioga recipe, we start from an eye node and go backwards through
- its input nodes. To rewrite a Tioga node, we do the following:
-
- 1) parse the node we're at in the standard way (calling parser() )
- 2) rewrite its input nodes recursively using Tioga rewrite
- 3) now, with the rewritten input parse trees and the original parse tree
- of the node, we rewrite the the node.
- To do the rewrite, we use the target lists, range tables, and
- qualifications of the input parse trees
-*/
-
-/*
- * beginRecipe:
- * this is the main function to recipe execution
- * this function is invoked for EXECUTE RECIPE ... statements
- *
- * takes in a RecipeStmt structure from the parser
- * and returns a list of cursor names
- */
-
-void
-beginRecipe(RecipeStmt *stmt)
-{
- TgRecipe *r;
- int i,
- numTees;
- QueryTreeList *qList;
- char portalName[1024];
-
- Plan *plan;
- TupleDesc attinfo;
- QueryDesc *queryDesc;
- Query *parsetree;
-
- TeeInfo *teeInfo;
-
- /*
- * retrieveRecipe() reads the recipe from the database and returns a
- * TgRecipe* structure we can work with
- */
-
- r = retrieveRecipe(stmt->recipeName);
-
- if (r == NULL)
- return;
-
- /* find the number of tees in the recipe */
- numTees = r->tees->num;
-
- if (numTees > 0)
- {
- /* allocate a teePlan structure */
- teeInfo = (TeeInfo *) malloc(sizeof(TeeInfo));
- teeInfo->num = numTees;
- teeInfo->val = (TeePlanInfo *) malloc(numTees * sizeof(TeePlanInfo));
- for (i = 0; i < numTees; i++)
- {
- teeInfo->val[i].tpi_relName = r->tees->val[i]->nodeName;
- teeInfo->val[i].tpi_parsetree = NULL;
- teeInfo->val[i].tpi_plan = NULL;
- }
- }
- else
- teeInfo = NULL;
-
- /*
- * for each viewer in the recipe, go backwards from each viewer input
- * and generate a plan. Attach the plan to cursors.
- */
- for (i = 0; i < r->eyes->num; i++)
- {
- TgNodePtr e;
-
- e = r->eyes->val[i];
- if (e->inNodes->num > 1)
- {
- elog(WARNING,
- "beginRecipe: Currently eyes cannot have more than one input");
- }
- if (e->inNodes->num == 0)
- {
- /* no input to this eye, skip it */
- continue;
- }
-
-#ifdef DEBUG_RECIPE
- elog(WARNING, "beginRecipe: eyes[%d] = %s\n", i, e->nodeName);
-#endif /* DEBUG_RECIPE */
-
- qList = tg_parseSubQuery(r, e->inNodes->val[0], teeInfo);
-
- if (qList == NULL)
- {
- /* eye is directly connected to a tee node */
- /* XXX TODO: handle this case */
- }
-
- /* now, plan the queries */
-
- /*
- * should really do everything pg_plan() does, but for now, we
- * skip the rule rewrite and time qual stuff
- */
-
- /*
- * 1) plan the main query, everything from an eye node back to a
- * Tee
- */
- parsetree = qList->qtrees[0];
-
- /*
- * before we plan, we want to see all the changes we did, during
- * the rewrite phase, such as creating the tee tables,
- * CommandCounterIncrement() allows us to see the changes
- */
- CommandCounterIncrement();
-
- plan = planner(parsetree);
-
- /*
- * 2) plan the tee queries, (subgraphs rooted from a Tee) by the
- * time the eye is processed, all tees that contribute to that eye
- * will have been included in the teeInfo list
- */
- if (teeInfo)
- {
- int t;
- Plan *tplan;
- Tee *newplan;
-
- for (t = 0; t < teeInfo->num; t++)
- {
- if (teeInfo->val[t].tpi_plan == NULL)
- {
- /* plan it in the usual fashion */
- tplan = planner(teeInfo->val[t].tpi_parsetree);
-
- /* now add a tee node to the root of the plan */
- elog(WARNING, "adding tee plan node to the root of the %s\n",
- teeInfo->val[t].tpi_relName);
- newplan = (Tee *) makeNode(Tee);
- newplan->plan.targetlist = tplan->targetlist;
- newplan->plan.qual = NULL; /* tplan->qual; */
- newplan->plan.lefttree = tplan;
- newplan->plan.righttree = NULL;
- newplan->leftParent = NULL;
- newplan->rightParent = NULL;
-
- /*
- * the range table of the tee is the range table of
- * the tplan
- */
- newplan->rtentries = teeInfo->val[t].tpi_parsetree->rtable;
- strcpy(newplan->teeTableName,
- teeInfo->val[t].tpi_relName);
- teeInfo->val[t].tpi_plan = (Plan *) newplan;
- }
- }
-
- /*
- * 3) replace the tee table scans in the main plan with actual
- * tee plannodes
- */
-
- plan = replaceTeeScans(plan, parsetree, teeInfo);
-
- } /* if (teeInfo) */
-
- /* define a portal for this viewer input */
- /* for now, eyes can only have one input */
- snprintf(portalName, 1024, "%s%d", e->nodeName, 0);
-
- queryDesc = CreateQueryDesc(parsetree,
- plan,
- whereToSendOutput);
-
- /*
- * call ExecStart to prepare the plan for execution
- */
- attinfo = ExecutorStart(queryDesc, NULL);
-
- ProcessPortal(portalName,
- parsetree,
- plan,
- attinfo,
- whereToSendOutput);
- elog(WARNING, "beginRecipe: cursor named %s is now available", portalName);
- }
-
-}
-
-
-
-/*
- * tg_rewriteQuery -
- * r - the recipe being rewritten
- * n - the node that we're current at
- * q - a QueryTree List containing the parse tree of the node
- * inputQlist - the parsetrees of its input nodes,
- * the size of inputQlist must be the same as the
- * number of input nodes. Some elements in the inpuQlist
- * may be null if the inputs to those nodes are unconnected
- *
- * this is the main routine for rewriting the recipe queries
- * the original query tree 'q' is modified
- */
-
-static void
-tg_rewriteQuery(TgRecipe * r,
- TgNode * n,
- QueryTreeList * q,
- QueryTreeList * inputQlist)
-{
- Query *orig;
- Query *inputQ;
- int i;
- List *rtable;
- List *input_rtable;
- int rt_length;
-
- /* orig is the original parse tree of the node */
- orig = q->qtrees[0];
-
-
- /*
- * step 1:
- *
- * form a combined range table from all the range tables in the original
- * query as well as the input nodes
- *
- * form a combined qualification from the qual in the original plus the
- * quals of the input nodes
- */
-
- /* start with the original range table */
- rtable = orig->rtable;
- rt_length = length(rtable);
-
- for (i = 0; i < n->inNodes->num; i++)
- {
- if (n->inNodes->val[i] != NULL &&
- n->inNodes->val[i]->nodeType != TG_TEE_NODE)
- {
- inputQ = inputQlist->qtrees[i];
- input_rtable = inputQ->rtable;
-
- /*
- * need to offset the var nodes in the qual and targetlist
- * because they are indexed off the original rtable
- */
- OffsetVarNodes((Node *) inputQ->qual, rt_length, 0);
- OffsetVarNodes((Node *) inputQ->targetList, rt_length, 0);
-
- /* append the range tables from the children nodes */
- rtable = nconc(rtable, input_rtable);
-
- /*
- * append the qualifications of the child node into the
- * original qual list
- */
- AddQual(orig, inputQ->qual);
- }
- }
- orig->rtable = rtable;
-
- /*
- * step 2: rewrite the target list of the original parse tree if there
- * are any references to params, replace them with the appropriate
- * target list entry of the children node
- */
- if (orig->targetList != NIL)
- {
- List *tl;
- TargetEntry *tle;
-
- foreach(tl, orig->targetList)
- {
- tle = lfirst(tl);
- if (tle->resdom != NULL)
- tle->expr = tg_rewriteParamsInExpr(tle->expr, inputQlist);
- }
- }
-
- /*
- * step 3: rewrite the qual of the original parse tree if there are
- * any references to params, replace them with the appropriate target
- * list entry of the children node
- */
- if (orig->qual)
- {
- if (nodeTag(orig->qual) == T_List)
- elog(ERROR, "tg_rewriteQuery: Whoa! why is my qual a List???");
- orig->qual = tg_rewriteParamsInExpr(orig->qual, inputQlist);
- }
-
- /*
- * at this point, we're done with the rewrite, the querytreelist q has
- * been modified
- */
-
-}
-
-
-/* tg_replaceNumberedParam:
-
- this procedure replaces the specified numbered param with a
- reference to a range table
-
- this procedure recursively calls itself
-
- it returns a (possibly modified) Node*.
-
-*/
-static Node *
-tg_replaceNumberedParam(Node *expression,
- int pnum, /* the number of the parameter */
- int rt_ind, /* the range table index */
- char *teeRelName) /* the relname of the tee
- * table */
-{
- TargetEntry *param_tle;
- Param *p;
- Var *newVar,
- *oldVar;
-
- if (expression == NULL)
- return NULL;
-
- switch (nodeTag(expression))
- {
- case T_Param:
- {
- /*
- * the node is a parameter, substitute the entry from the
- * target list of the child that corresponds to the
- * parameter number
- */
- p = (Param *) expression;
-
- /* we only deal with the case of numbered parameters */
- if (p->paramkind == PARAM_NUM && p->paramid == pnum)
- {
-
- if (p->param_tlist)
- {
- /*
- * we have a parameter with an attribute like
- * $N.foo so replace it with a new var node
- */
-
- /* param tlist can only have one entry in them! */
- param_tle = (TargetEntry *) (lfirst(p->param_tlist));
- oldVar = (Var *) param_tle->expr;
- oldVar->varno = rt_ind;
- oldVar->varnoold = rt_ind;
- return (Node *) oldVar;
- }
- else
- {
- /* we have $N without the .foo */
- bool defined;
- bool isRel;
-
- /*
- * TODO here, we need to check to see whether the
- * type of the tee is a complex type (relation) or
- * a simple type
- */
-
- /*
- * if it is a simple type, then we need to get the
- * "result" attribute from the tee relation
- */
-
- isRel = (typeidTypeRelid(p->paramtype) != 0);
- if (isRel)
- {
- newVar = makeVar(rt_ind,
- 0, /* the whole tuple */
- TypeGet(teeRelName, &defined),
- -1,
- 0,
- rt_ind,
- 0);
- return (Node *) newVar;
- }
- else
- newVar = makeVar(rt_ind,
- 1, /* just the first field,
- * which is 'result' */
- TypeGet(teeRelName, &defined),
- -1,
- 0,
- rt_ind,
- 0);
- return (Node *) newVar;
-
- }
- }
- else
- elog(WARNING, "tg_replaceNumberedParam: unexpected paramkind value of %d", p->paramkind);
- }
- break;
- case T_Expr:
- {
- /*
- * the node is an expression, we need to recursively call
- * ourselves until we find parameter nodes
- */
- List *l;
- Expr *expr = (Expr *) expression;
- List *newArgs;
-
- /*
- * we have to make a new args lists because Params can be
- * replaced by Var nodes in tg_replaceNumberedParam()
- */
- newArgs = NIL;
-
- /*
- * we only care about argument to expressions, it doesn't
- * matter when the opType is
- */
- /* recursively rewrite the arguments of this expression */
- foreach(l, expr->args)
- {
- newArgs = lappend(newArgs,
- tg_replaceNumberedParam(lfirst(l),
- pnum,
- rt_ind,
- teeRelName));
- }
- /* change the arguments of the expression */
- expr->args = newArgs;
- }
- break;
- default:
- {
- /* ignore other expr types */
- }
- }
-
- return expression;
-}
-
-
-
-
-
-/* tg_rewriteParamsInExpr:
-
- rewrite the params in expressions by using the targetlist entries
- from the input parsetrees
-
- this procedure recursively calls itself
-
- it returns a (possibly modified) Node*.
-
-*/
-static Node *
-tg_rewriteParamsInExpr(Node *expression, QueryTreeList * inputQlist)
-{
- List *tl;
- TargetEntry *param_tle,
- *tle;
- Param *p;
- int childno;
- char *resname;
-
- if (expression == NULL)
- return NULL;
-
- switch (nodeTag(expression))
- {
- case T_Param:
- {
- /*
- * the node is a parameter, substitute the entry from the
- * target list of the child that corresponds to the
- * parameter number
- */
- p = (Param *) expression;
-
- /* we only deal with the case of numbered parameters */
- if (p->paramkind == PARAM_NUM)
- {
- /* paramid's start from 1 */
- childno = p->paramid - 1;
-
- if (p->param_tlist)
- {
- /*
- * we have a parameter with an attribute like
- * $N.foo so match the resname "foo" against the
- * target list of the (N-1)th inputQlist
- */
-
- /* param tlist can only have one entry in them! */
- param_tle = (TargetEntry *) (lfirst(p->param_tlist));
- resname = param_tle->resdom->resname;
-
- if (inputQlist->qtrees[childno])
- {
- foreach(tl, inputQlist->qtrees[childno]->targetList)
- {
- tle = lfirst(tl);
- if (strcmp(resname, tle->resdom->resname) == 0)
- return tle->expr;
- }
- }
- else
- elog(ERROR, "tg_rewriteParamsInExpr:can't substitute for parameter %d when that input is unconnected", p->paramid);
-
- }
- else
- {
- /* we have $N without the .foo */
- /* use the first resdom in the targetlist of the */
- /* appropriate child query */
- tl = inputQlist->qtrees[childno]->targetList;
- tle = lfirst(tl);
- return tle->expr;
- }
- }
- else
- elog(WARNING, "tg_rewriteParamsInExpr: unexpected paramkind value of %d", p->paramkind);
- }
- break;
- case T_Expr:
- {
- /*
- * the node is an expression, we need to recursively call
- * ourselves until we find parameter nodes
- */
- List *l;
- Expr *expr = (Expr *) expression;
- List *newArgs;
-
- /*
- * we have to make a new args lists because Params can be
- * replaced by Var nodes in tg_rewriteParamsInExpr()
- */
- newArgs = NIL;
-
- /*
- * we only care about argument to expressions, it doesn't
- * matter when the opType is
- */
- /* recursively rewrite the arguments of this expression */
- foreach(l, expr->args)
- {
- newArgs = lappend(newArgs,
- tg_rewriteParamsInExpr(lfirst(l), inputQlist));
- }
- /* change the arguments of the expression */
- expr->args = newArgs;
- }
- break;
- default:
- {
- /* ignore other expr types */
- }
- }
-
- return expression;
-}
-
-
-
-/*
- getParamTypes:
- given an element, finds its parameter types.
- the typev array argument is set to the parameter types.
- the parameterCount is returned
-
- this code is very similar to ProcedureDefine() in pg_proc.c
-*/
-static int
-getParamTypes(TgElement * elem, Oid *typev)
-{
- /* this code is similar to ProcedureDefine() */
- int16 parameterCount;
- bool defined;
- Oid toid;
- char *t;
- int i,
- j;
-
- parameterCount = 0;
- for (i = 0; i < FUNC_MAX_ARGS; i++)
- typev[i] = 0;
- for (j = 0; j < elem->inTypes->num; j++)
- {
- if (parameterCount == FUNC_MAX_ARGS)
- {
- elog(ERROR,
- "getParamTypes: Ingredients cannot take > %d arguments", FUNC_MAX_ARGS);
- }
- t = elem->inTypes->val[j];
- if (strcmp(t, "opaque") == 0)
- {
- elog(ERROR,
- "getParamTypes: Ingredient functions cannot take type 'opaque'");
- }
- else
- {
- toid = TypeGet(elem->inTypes->val[j], &defined);
- if (!OidIsValid(toid))
- elog(ERROR, "getParamTypes: arg type '%s' is not defined", t);
- if (!defined)
- elog(WARNING, "getParamTypes: arg type '%s' is only a shell", t);
- }
- typev[parameterCount++] = toid;
- }
-
- return parameterCount;
-}
-
-
-/*
- * tg_parseTeeNode
- *
- * handles the parsing of the tee node
- *
- *
- */
-
-static QueryTreeList *
-tg_parseTeeNode(TgRecipe * r,
- TgNode * n, /* the tee node */
- int i, /* which input this node is to its parent */
- QueryTreeList * qList,
- TeeInfo * teeInfo)
-
-{
- QueryTreeList *q;
- char *tt;
- int rt_ind;
- Query *orig;
-
- /*
- * the input Node is a tee node, so we need to do the following: we
- * need to parse the child of the tee node, we add that to our query
- * tree list we need the name of the tee node table the tee node table
- * is the table into which the tee node may materialize results. Call
- * it TT we add a range table to our existing query with TT in it we
- * need to replace the parameter $i with TT (otherwise the optimizer
- * won't know to use the table on expression containining $i) After
- * that rewrite, the optimizer will generate sequential scans of TT
- *
- * Later, in the glue phase, we replace all instances of TT sequential
- * scans with the actual Tee node
- */
- q = tg_parseSubQuery(r, n, teeInfo);
-
- /* tt is the name of the tee node table */
- tt = n->nodeName;
-
- if (q)
- appendTeeQuery(teeInfo, q, tt);
-
- orig = qList->qtrees[0];
- rt_ind = RangeTablePosn(orig->rtable, tt);
-
- /*
- * check to see that this table is not part of the range table
- * already. This usually only happens if multiple inputs are
- * connected to the same Tee.
- */
- if (rt_ind == 0)
- {
- orig->rtable = lappend(orig->rtable,
- addRangeTableEntry(NULL,
- tt,
- tt,
- FALSE,
- FALSE));
- rt_ind = length(orig->rtable);
- }
-
- orig->qual = tg_replaceNumberedParam(orig->qual,
- i + 1, /* params start at 1 */
- rt_ind,
- tt);
- return qList;
-}
-
-
-/*
- * tg_parseSubQuery:
- * go backwards from a node and parse the query
- *
- * the result parse tree is passed back
- *
- * could return NULL if trying to parse a teeNode
- * that's already been processed by another parent
- *
- */
-
-static QueryTreeList *
-tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo)
-{
- TgElement *elem;
- char *funcName;
- Oid typev[FUNC_MAX_ARGS], /* eight arguments maximum */
- relid;
- int i,
- parameterCount;
-
- QueryTreeList *qList; /* the parse tree of the nodeElement */
- QueryTreeList *inputQlist; /* the list of parse trees for the inputs
- * to this node */
- QueryTreeList *q;
- TgNode *child;
- Relation rel;
- unsigned int len;
- TupleDesc tupdesc;
-
- qList = NULL;
-
- if (n->nodeType == TG_INGRED_NODE)
- {
- /* parse each ingredient node in turn */
-
- elem = n->nodeElem;
- switch (elem->srcLang)
- {
- case TG_SQL:
- {
- /*
- * for SQL ingredients, the SQL query is contained in
- * the 'src' field
- */
-
-#ifdef DEBUG_RECIPE
- elog(WARNING, "calling parser with %s", elem->src);
-#endif /* DEBUG_RECIPE */
-
- parameterCount = getParamTypes(elem, typev);
-
- qList = parser(elem->src, typev, parameterCount);
-
- if (qList->len > 1)
- {
- elog(WARNING,
- "tg_parseSubQuery: parser produced > 1 query tree");
- }
- }
- break;
- case TG_C:
- {
- /* C ingredients are registered functions in postgres */
-
- /*
- * we create a new query string by using the function
- * name (found in the 'src' field) and adding
- * parameters to it so if the function was FOOBAR and
- * took in two arguments, we would create a string
- * select FOOBAR($1,$2)
- */
- char newquery[1000];
-
- funcName = elem->src;
- parameterCount = getParamTypes(elem, typev);
-
- if (parameterCount > 0)
- {
- int i;
-
- snprintf(newquery, 1000, "select %s($1", funcName);
- for (i = 1; i < parameterCount; i++)
- snprintf(newquery, 1000, "%s,$%d", pstrdup(newquery), i);
- snprintf(newquery, 1000, "%s)", pstrdup(newquery));
- }
- else
- snprintf(newquery, 1000, "select %s()", funcName);
-
-#ifdef DEBUG_RECIPE
- elog(WARNING, "calling parser with %s", newquery);
-#endif /* DEBUG_RECIPE */
-
- qList = parser(newquery, typev, parameterCount);
- if (qList->len > 1)
- {
- elog(WARNING,
- "tg_parseSubQuery: parser produced > 1 query tree");
- }
- }
- break;
- case TG_RECIPE_GRAPH:
- elog(WARNING, "tg_parseSubQuery: can't parse recipe graph ingredients yet!");
- break;
- case TG_COMPILED:
- elog(WARNING, "tg_parseSubQuery: can't parse compiled ingredients yet!");
- break;
- default:
- elog(WARNING, "tg_parseSubQuery: unknown srcLang: %d", elem->srcLang);
- }
-
- /* parse each of the subrecipes that are input to this node */
-
- if (n->inNodes->num > 0)
- {
- inputQlist = malloc(sizeof(QueryTreeList));
- inputQlist->len = n->inNodes->num + 1;
- inputQlist->qtrees = (Query **) malloc(inputQlist->len * sizeof(Query *));
- for (i = 0; i < n->inNodes->num; i++)
- {
-
- inputQlist->qtrees[i] = NULL;
- if (n->inNodes->val[i])
- {
- if (n->inNodes->val[i]->nodeType == TG_TEE_NODE)
- {
- qList = tg_parseTeeNode(r, n->inNodes->val[i],
- i, qList, teeInfo);
- }
- else
- { /* input node is not a Tee */
- q = tg_parseSubQuery(r, n->inNodes->val[i],
- teeInfo);
- Assert(q->len == 1);
- inputQlist->qtrees[i] = q->qtrees[0];
- }
- }
- }
-
- /* now, we have all the query trees from our input nodes */
- /* transform the original parse tree appropriately */
- tg_rewriteQuery(r, n, qList, inputQlist);
- }
- }
- else if (n->nodeType == TG_EYE_NODE)
- {
- /*
- * if we hit an eye, we need to stop and make what we have into a
- * subrecipe query block
- */
- elog(WARNING, "tg_parseSubQuery: can't handle eye nodes yet");
- }
- else if (n->nodeType == TG_TEE_NODE)
- {
- /*
- * if we hit a tee, check to see if the parsing has been done for
- * this tee already by the other parent
- */
-
- rel = RelationNameGetRelation(n->nodeName);
- if (RelationIsValid(rel))
- {
- /*
- * this tee has already been visited, no need to do any
- * further processing
- */
- return NULL;
- }
- else
- {
- /* we need to process the child of the tee first, */
- child = n->inNodes->val[0];
-
- if (child->nodeType == TG_TEE_NODE)
- {
- /* nested Tee nodes */
- qList = tg_parseTeeNode(r, child, 0, qList, teeInfo);
- return qList;
- }
-
- Assert(child != NULL);
-
- /* parse the input node */
- q = tg_parseSubQuery(r, child, teeInfo);
- Assert(q->len == 1);
-
- /* add the parsed query to the main list of queries */
- qList = appendQlist(qList, q);
-
- /* need to create the tee table here */
-
- /*
- * the tee table created is used both for materializing the
- * values at the tee node, and for parsing and optimization.
- * The optimization needs to have a real table before it will
- * consider scans on it
- */
-
- /*
- * first, find the type of the tuples being produced by the
- * tee. The type is the same as the output type of the child
- * node.
- *
- * NOTE: we are assuming that the child node only has a single
- * output here!
- */
- getParamTypes(child->nodeElem, typev);
-
- /*
- * the output type is either a complex type, (and is thus a
- * relation) or is a simple type
- */
-
- rel = RelationNameGetRelation(child->nodeElem->outTypes->val[0]);
-
- if (RelationIsValid(rel))
- {
- /*
- * for complex types, create new relation with the same
- * tuple descriptor as the output table type
- */
- len = length(q->qtrees[0]->targetList);
- tupdesc = rel->rd_att;
-
- relid = heap_create_with_catalog(
- child->nodeElem->outTypes->val[0],
- tupdesc, RELKIND_RELATION, false);
- }
- else
- {
- /*
- * we have to create a relation with one attribute of the
- * simple base type. That attribute will have an attr
- * name of "result"
- */
- /* NOTE: ignore array types for the time being */
-
- len = 1;
- tupdesc = CreateTemplateTupleDesc(len);
-
- if (!TupleDescInitEntry(tupdesc, 1,
- "result",
- InvalidOid,
- -1, 0, false))
- elog(WARNING, "tg_parseSubQuery: unexpected result from TupleDescInitEntry");
- else
- {
- relid = heap_create_with_catalog(
- child->nodeElem->outTypes->val[0],
- tupdesc, RELKIND_RELATION, false);
- }
- }
- }
- }
- else if (n->nodeType == TG_RECIPE_NODE)
- elog(WARNING, "tg_parseSubQuery: can't handle embedded recipes yet!");
- else
- elog(WARNING, "unknown nodeType: %d", n->nodeType);
-
- return qList;
-}
-
-/*
- * OffsetVarAttno -
- * recursively find all the var nodes with the specified varno
- * and offset their varattno with the offset
- *
- * code is similar to OffsetVarNodes in rewriteManip.c
- */
-
-void
-OffsetVarAttno(Node *node, int varno, int offset)
-{
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *) node;
-
- OffsetVarAttno(tle->expr, varno, offset);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *) node;
-
- OffsetVarAttno((Node *) expr->args, varno, offset);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *) node;
-
- if (var->varno == varno)
- var->varattno += offset;
- }
- break;
- case T_List:
- {
- List *l;
-
- foreach(l, (List *) node)
- OffsetVarAttno(lfirst(l), varno, offset);
- }
- break;
- default:
- /* ignore the others */
- break;
- }
-}
-
-/*
- * appendQlist
- * add the contents of a QueryTreeList q2 to the end of the QueryTreeList
- * q1
- *
- * returns a new querytree list
- */
-
-QueryTreeList *
-appendQlist(QueryTreeList * q1, QueryTreeList * q2)
-{
- QueryTreeList *newq;
- int i,
- j;
- int newlen;
-
- if (q1 == NULL)
- return q2;
-
- if (q2 == NULL)
- return q1;
-
- newlen = q1->len + q2->len;
- newq = (QueryTreeList *) malloc(sizeof(QueryTreeList));
- newq->len = newlen;
- newq->qtrees = (Query **) malloc(newlen * sizeof(Query *));
- for (i = 0; i < q1->len; i++)
- newq->qtrees[i] = q1->qtrees[i];
- for (j = 0; j < q2->len; j++)
- newq->qtrees[i + j] = q2->qtrees[j];
- return newq;
-}
-
-/*
- * appendTeeQuery
- *
- * modify the query field of the teeInfo list of the particular tee node
- */
-static void
-appendTeeQuery(TeeInfo * teeInfo, QueryTreeList * q, char *teeNodeName)
-{
- int i;
-
- Assert(teeInfo);
-
- for (i = 0; i < teeInfo->num; i++)
- {
- if (strcmp(teeInfo->val[i].tpi_relName, teeNodeName) == 0)
- {
-
- Assert(q->len == 1);
- teeInfo->val[i].tpi_parsetree = q->qtrees[0];
- return;
- }
- }
- elog(WARNING, "appendTeeQuery: teeNodeName '%s' not found in teeInfo");
-}
-
-
-
-/*
- * replaceSeqScan
- * replaces sequential scans of a specified relation with the tee plan
- * the relation is specified by its index in the range table, rt_ind
- *
- * returns the modified plan
- * the offset_attno is the offset that needs to be added to the parent's
- * qual or targetlist because the child plan has been replaced with a tee node
- */
-static void
-replaceSeqScan(Plan *plan, Plan *parent,
- int rt_ind, Plan *tplan)
-{
- Scan *snode;
- Tee *teePlan;
- Result *newPlan;
-
- if (plan == NULL)
- return;
-
- if (plan->type == T_SeqScan)
- {
- snode = (Scan *) plan;
- if (snode->scanrelid == rt_ind)
- {
- /*
- * found the sequential scan that should be replaced with the
- * tplan.
- */
- /* we replace the plan, but we also need to modify its parent */
-
- /*
- * replace the sequential scan with a Result node the reason
- * we use a result node is so that we get the proper
- * projection behavior. The Result node is simply (ab)used as
- * a projection node
- */
-
- newPlan = makeNode(Result);
- newPlan->plan.cost = 0.0;
- newPlan->plan.state = (EState *) NULL;
- newPlan->plan.targetlist = plan->targetlist;
- newPlan->plan.lefttree = tplan;
- newPlan->plan.righttree = NULL;
- newPlan->resconstantqual = NULL;
- newPlan->resstate = NULL;
-
- /* change all the varno's to 1 */
- ChangeVarNodes((Node *) newPlan->plan.targetlist,
- snode->scanrelid, 1);
-
- if (parent)
- {
- teePlan = (Tee *) tplan;
-
- if (parent->lefttree == plan)
- parent->lefttree = (Plan *) newPlan;
- else
- parent->righttree = (Plan *) newPlan;
-
-
- if (teePlan->leftParent == NULL)
- teePlan->leftParent = (Plan *) newPlan;
- else
- teePlan->rightParent = (Plan *) newPlan;
-
-/* comment for now to test out executor-stuff
- if (parent->state) {
- ExecInitNode((Plan*)newPlan, parent->state, (Plan*)newPlan);
- }
-*/
- }
- }
-
- }
- else
- {
- if (plan->lefttree)
- replaceSeqScan(plan->lefttree, plan, rt_ind, tplan);
- if (plan->righttree)
- replaceSeqScan(plan->righttree, plan, rt_ind, tplan);
- }
-}
-
-/*
- * replaceTeeScans
- * places the sequential scans of the Tee table with
- * a connection to the actual tee plan node
- */
-static Plan *
-replaceTeeScans(Plan *plan, Query *parsetree, TeeInfo * teeInfo)
-{
-
- int i;
- List *rtable;
- RangeTblEntry *rte;
- char prefix[5];
- int rt_ind;
- Plan *tplan;
-
- rtable = parsetree->rtable;
- if (rtable == NULL)
- return plan;
-
- /*
- * look through the range table for the tee relation entry, that will
- * give use the varno we need to detect which sequential scans need to
- * be replaced with tee nodes
- */
-
- rt_ind = 0;
- while (rtable != NIL)
- {
- rte = lfirst(rtable);
- rtable = lnext(rtable);
- rt_ind++; /* range table references in varno fields
- * start w/ 1 */
-
- /*
- * look for the "tee_" prefix in the refname, also check to see
- * that the relname and the refname are the same this should
- * eliminate any user-specified table and leave us with the tee
- * table entries only
- */
- if ((strlen(rte->refname) < 4) ||
- (strcmp(rte->relname, rte->refname) != 0))
- continue;
- StrNCpy(prefix, rte->refname, 5);
- if (strcmp(prefix, "tee_") == 0)
- {
- /* okay, we found a tee node entry in the range table */
-
- /* find the appropriate plan in the teeInfo list */
- tplan = NULL;
- for (i = 0; i < teeInfo->num; i++)
- {
- if (strcmp(teeInfo->val[i].tpi_relName,
- rte->refname) == 0)
- tplan = teeInfo->val[i].tpi_plan;
- }
- if (tplan == NULL)
- elog(WARNING, "replaceTeeScans didn't find the corresponding tee plan");
-
- /*
- * replace the sequential scan node with that var number with
- * the tee plan node
- */
- replaceSeqScan(plan, NULL, rt_ind, tplan);
- }
- }
-
- return plan;
-}
-
-
-#endif /* TIOGA */
diff --git a/src/backend/commands/_deadcode/version.c b/src/backend/commands/_deadcode/version.c
deleted file mode 100644
index a88247e684b..00000000000
--- a/src/backend/commands/_deadcode/version.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * version.c
- * This file contains all the rules that govern all version semantics.
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * The version stuff has not been tested under postgres95 and probably
- * doesn't work! - jolly 8/19/95
- *
- *
- * $Id: version.c,v 1.30 2002/06/20 20:29:27 momjian Exp $
- *
- * NOTES
- * At the point the version is defined, 2 physical relations are created
- * <vname>_added and <vname>_deleted.
- *
- * In addition, 4 rules are defined which govern the semantics of
- * versions w.r.t retrieves, appends, replaces and deletes.
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-
-#define MAX_QUERY_LEN 1024
-
-char rule_buf[MAX_QUERY_LEN];
-
-/*
- * problem: the version system assumes that the rules it declares will
- * be fired in the order of declaration, it also assumes
- * goh's silly instead semantics. Unfortunately, it is a pain
- * to make the version system work with the new semantics.
- * However the whole problem can be solved, and some nice
- * functionality can be achieved if we get multiple action rules
- * to work. So thats what I did -- glass
- *
- * Well, at least they've been working for about 20 minutes.
- *
- * So any comments in this code about 1 rule per transction are false...:)
- *
- */
-
-/*
- * This is needed because the rule system only allows
- * *1* rule to be defined per transaction.
- *
- * NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
- * OOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- *
- * DONT DO THAT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- *
- * If you commit the current Xact all the palloced memory GOES AWAY
- * and could be re-palloced in the new Xact and the whole hell breaks
- * loose and poor people like me spend 2 hours of their live chassing
- * a strange memory bug instead of watching the "Get Smart" marathon
- * in NICK !
- * DO NOT COMMIT THE XACT, just increase the Cid counter!
- * _sp.
- */
-#ifdef NOT_USED
-static void
-eval_as_new_xact(char *query)
-{
-
- /*------
- * WARNING! do not uncomment the following lines WARNING!
- *
- * CommitTransactionCommand();
- * StartTransactionCommand();
- *------
- */
- CommandCounterIncrement();
- pg_exec_query(query);
-}
-#endif
-/*
- * Define a version.
- */
-#ifdef NOT_USED
-void
-DefineVersion(char *name, char *fromRelname, char *date)
-{
- char *bname;
- static char saved_basename[512];
- static char saved_snapshot[512];
-
- if (date == NULL)
- {
- /* no time ranges */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- *saved_snapshot = (char) NULL;
- }
- else
- {
- /* version is a snapshot */
- bname = fromRelname;
- strcpy(saved_basename, (char *) bname);
- sprintf(saved_snapshot, "['%s']", date);
- }
-
-
- /*
- * Calls the routine ``GetAttrList'' get the list of attributes from
- * the base relation. Code is put here so that we only need to look up
- * the attribute once for both appends and replaces.
- */
- setAttrList(bname);
-
- VersionCreate(name, saved_basename);
- VersionAppend(name, saved_basename);
- VersionDelete(name, saved_basename, saved_snapshot);
- VersionReplace(name, saved_basename, saved_snapshot);
- VersionRetrieve(name, saved_basename, saved_snapshot);
-}
-#endif
-
-/*
- * Creates the deltas.
- */
-#ifdef NOT_USED
-void
-VersionCreate(char *vname, char *bname)
-{
- static char query_buf[MAX_QUERY_LEN];
-
- /*
- * Creating the dummy version relation for triggering rules.
- */
- sprintf(query_buf, "SELECT * INTO TABLE %s from %s where 1 =2",
- vname, bname);
-
- pg_exec_query(query_buf);
-
- /*
- * Creating the ``v_added'' relation
- */
- sprintf(query_buf, "SELECT * INTO TABLE %s_added from %s where 1 = 2",
- vname, bname);
- eval_as_new_xact(query_buf);
-
- /*
- * Creating the ``v_deleted'' relation.
- */
- sprintf(query_buf, "CREATE TABLE %s_del (DOID oid)", vname);
- eval_as_new_xact(query_buf);
-}
-#endif
-
-
-/*
- * Given the relation name, does a catalog lookup for that relation and
- * sets the global variable 'attr_list' with the list of attributes (names)
- * for that relation.
- */
-#ifdef NOT_USED
-static void
-setAttrList(char *bname)
-{
- Relation rel;
- int i = 0;
- int maxattrs = 0;
- char *attrname;
- char temp_buf[512];
- int notfirst = 0;
-
- rel = heap_openr(bname);
- if (rel == NULL)
- {
- elog(ERROR, "Unable to expand all -- amopenr failed ");
- return;
- }
- maxattrs = RelationGetNumberOfAttributes(rel);
-
- attr_list[0] = '\0';
-
- for (i = maxattrs - 1; i > -1; --i)
- {
- attrname = NameStr(rel->rd_att->attrs[i]->attname);
-
- if (notfirst == 1)
- sprintf(temp_buf, ", %s = new.%s", attrname, attrname);
- else
- {
- sprintf(temp_buf, "%s = new.%s", attrname, attrname);
- notfirst = 1;
- }
- strcat(attr_list, temp_buf);
- }
-
- heap_close(rel);
-
- return;
-}
-#endif
-
-/*
- * This routine defines the rule governing the append semantics of
- * versions. All tuples appended to a version gets appended to the
- * <vname>_added relation.
- */
-#ifdef NOT_USED
-static void
-VersionAppend(char *vname, char *bname)
-{
- sprintf(rule_buf,
- "define rewrite rule %s_append is on INSERT to %s do instead append %s_added(%s)",
- vname, vname, vname, attr_list);
-
- eval_as_new_xact(rule_buf);
-}
-#endif
-
-/*
- * This routine defines the rule governing the retrieval semantics of
- * versions. To retrieve tuples from a version , we need to:
- *
- * 1. Retrieve all tuples in the <vname>_added relation.
- * 2. Retrieve all tuples in the base relation which are not in
- * the <vname>_del relation.
- */
-#ifdef NOT_USED
-void
-VersionRetrieve(char *vname, char *bname, char *snapshot)
-{
-
- sprintf(rule_buf,
- "define rewrite rule %s_retrieve is on SELECT to %s do instead\n\
-SELECT %s_1.oid, %s_1.* from _%s in %s%s, %s_1 in (%s_added | _%s) \
-where _%s.oid !!= '%s_del.DOID'",
- vname, vname, vname, vname, bname,
- bname, snapshot,
- vname, vname, bname, bname, vname);
-
- eval_as_new_xact(rule_buf);
-
- /* printf("%s\n",rule_buf); */
-
-}
-#endif
-
-/*
- * This routine defines the rules that govern the delete semantics of
- * versions. Two things happens when we delete a tuple from a version:
- *
- * 1. If the tuple to be deleted was added to the version *after*
- * the version was created, then we simply delete the tuple
- * from the <vname>_added relation.
- * 2. If the tuple to be deleted is actually in the base relation,
- * then we have to mark that tuple as being deleted by adding
- * it to the <vname>_del relation.
- */
-#ifdef NOT_USED
-void
-VersionDelete(char *vname, char *bname, char *snapshot)
-{
-
- sprintf(rule_buf,
- "define rewrite rule %s_delete1 is on delete to %s do instead\n \
-[delete %s_added where current.oid = %s_added.oid\n \
- append %s_del(DOID = current.oid) from _%s in %s%s \
- where current.oid = _%s.oid] \n",
- vname, vname, vname, vname, vname,
- bname, bname, snapshot, bname);
-
- eval_as_new_xact(rule_buf);
-#ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_delete2 is on delete to %s do instead \n \
- append %s_del(DOID = current.oid) from _%s in %s%s \
- where current.oid = _%s.oid \n",
- vname, vname, vname, bname, bname, snapshot, bname);
-
- eval_as_new_xact(rule_buf);
-#endif /* OLD_REWRITE */
-}
-#endif
-
-/*
- * This routine defines the rules that govern the update semantics
- * of versions. To update a tuple in a version:
- *
- * 1. If the tuple is in <vname>_added, we simply ``replace''
- * the tuple (as per postgres style).
- * 2. if the tuple is in the base relation, then two things have to
- * happen:
- * 2.1 The tuple is marked ``deleted'' from the base relation by
- * adding the tuple to the <vname>_del relation.
- * 2.2 A copy of the tuple is appended to the <vname>_added relation
- */
-#ifdef NOT_USED
-void
-VersionReplace(char *vname, char *bname, char *snapshot)
-{
- sprintf(rule_buf,
- "define rewrite rule %s_replace1 is on replace to %s do instead \n\
-[replace %s_added(%s) where current.oid = %s_added.oid \n\
- append %s_del(DOID = current.oid) from _%s in %s%s \
- where current.oid = _%s.oid\n\
- append %s_added(%s) from _%s in %s%s \
- where current.oid !!= '%s_added.oid' and current.oid = _%s.oid]\n",
- vname, vname, vname, attr_list, vname,
- vname, bname, bname, snapshot, bname,
- vname, attr_list, bname, bname, snapshot, vname, bname);
-
- eval_as_new_xact(rule_buf);
-
-/* printf("%s\n",rule_buf); */
-#ifdef OLD_REWRITE
- sprintf(rule_buf,
- "define rewrite rule %s_replace2 is on replace to %s do \n\
- append %s_del(DOID = current.oid) from _%s in %s%s \
- where current.oid = _%s.oid\n",
- vname, vname, vname, bname, bname, snapshot, bname);
-
- eval_as_new_xact(rule_buf);
-
- sprintf(rule_buf,
- "define rewrite rule %s_replace3 is on replace to %s do instead\n\
- append %s_added(%s) from _%s in %s%s \
- where current.oid !!= '%s_added.oid' and current.oid = \
- _%s.oid\n",
- vname, vname, vname, attr_list, bname, bname, snapshot, vname, bname);
-
- eval_as_new_xact(rule_buf);
-#endif /* OLD_REWRITE */
-/* printf("%s\n",rule_buf); */
-
-}
-
-#endif