1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Postgres95 1.01 Distribution - Virgin Sources

This commit is contained in:
Marc G. Fournier
1996-07-09 06:22:35 +00:00
commit d31084e9d1
868 changed files with 242656 additions and 0 deletions

View File

@ -0,0 +1,33 @@
#-------------------------------------------------------------------------
#
# Makefile.inc--
# Makefile for the nodes module
#
# Copyright (c) 1994, Regents of the University of California
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/nodes/Attic/Makefile.inc,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
#
# NOTES
# Originally, the nodes module is a home-brew, C++ like inheritance
# system. However, the automatically generated tags, accessor functions
# and the header files themselves are difficult to maintain. We need
# real language support. Emulation doesn't quite do it...
#
# See nodes/README for an explanation of the new no-frills nodes
# structures.
# - ay 11/5/94
#
#-------------------------------------------------------------------------
VPATH:= $(VPATH):$(CURDIR)/nodes
SRCS_NODES= nodeFuncs.c nodes.c list.c \
copyfuncs.c equalfuncs.c makefuncs.c outfuncs.c readfuncs.c \
print.c read.c
HEADERS+= execnodes.h makefuncs.h memnodes.h nodeFuncs.h nodes.h \
params.h parsenodes.h pg_list.h plannodes.h primnodes.h relation.h

65
src/backend/nodes/README Normal file
View File

@ -0,0 +1,65 @@
*******************************************************************************
* *
* EXPLANATION OF THE NODE STRUCTURES *
* - Andrew Yu (11/94) *
* *
* Copyright (c) 1994, Regents of the University of California *
* *
* $Id: README,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
* *
*******************************************************************************
INTRODUCTION
The current node structures are plain old C structures. "Inheritance" is
achieved by convention. No additional functions will be generated. Functions
that manipulate node structures reside in this directory.
FILES IN THIS DIRECTORY
Node manipulation functions:
copyfuncs.c - copying a node
equalfuncs.c - comparing a node
outfuncs.c - convert a node to ascii representation
readfuncs.c - convert ascii representation back to a node
makefuncs.c - creator functions for primitive nodes
Node definitions:
nodes.h - define node tags (NodeTag)
pg_list.h - generic list
primnodes.h - primitive nodes
parsenodes.h - parse tree nodes
plannodes.h - plan tree nodes
relation.h - inner plan tree nodes
execnodes.h - executor nodes
memnodes.h - memory nodes
STEPS TO ADD A NODE
Suppose you wana define a node Foo:
1. add a tag (T_Foo) to the enum NodeTag in nodes.h (You may have to
recompile the whole tree after doing this.)
2. add the structure definition to the appropriate ???nodes.h file. If you
intend to inherit from, say a Plan node, put Plan as the first field of
you definition.
3. if you intend to use copyObject, equal, nodeToString or stringToNode,
add an appropriate function to copyfuncs.c, equalfuncs.c, outfuncs.c
and readfuncs.c accordingly. (Except for frequently used nodes, don't
bother writing a creator function in makefuncs.c)
HISTORICAL NOTE
Prior to the current simple C structure definitions, the Node structures
uses a pseudo-inheritance system which automatically generates creator and
accessor functions. Since every node inherits from LispValue, the whole thing
is a mess. Here's a little anecdote:
LispValue definition -- class used to support lisp structures
in C. This is here because we did not want to totally rewrite
planner and executor code which depended on lisp structures when
we ported postgres V1 from lisp to C. -cim 4/23/90

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,703 @@
/*-------------------------------------------------------------------------
*
* equalfuncs.c--
* equal functions to compare the nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "nodes/nodes.h"
#include "nodes/primnodes.h"
#include "nodes/relation.h"
#include "nodes/execnodes.h"
#include "nodes/plannodes.h"
#include "utils/builtins.h" /* for namestrcmp() */
#include "utils/datum.h"
#include "utils/elog.h"
#include "storage/itemptr.h"
/*
* Stuff from primnodes.h
*/
/*
* Resdom is a subclass of Node.
*/
static bool
_equalResdom(Resdom *a, Resdom *b)
{
if (a->resno != b->resno)
return (false);
if (a->restype != b->restype)
return (false);
if (a->reslen != b->reslen)
return (false);
if (strcmp(a->resname, b->resname) != 0)
return (false);
if (a->reskey != b->reskey)
return (false);
if (a->reskeyop != b->reskeyop)
return (false);
return (true);
}
static bool
_equalFjoin(Fjoin *a, Fjoin *b)
{
int nNodes;
if (a->fj_initialized != b->fj_initialized)
return (false);
if (a->fj_nNodes != b->fj_nNodes)
return (false);
if (!equal(a->fj_innerNode, b->fj_innerNode))
return (false);
nNodes = a->fj_nNodes;
if (memcmp(a->fj_results, b->fj_results, nNodes*sizeof(Datum)) != 0)
return (false);
if (memcmp(a->fj_alwaysDone, b->fj_alwaysDone, nNodes*sizeof(bool)) != 0)
return (false);
return(true);
}
/*
* Expr is a subclass of Node.
*/
static bool
_equalExpr(Expr *a, Expr *b)
{
if (a->opType != b->opType)
return (false);
if (!equal(a->oper, b->oper))
return (false);
if (!equal(a->args, b->args))
return (false);
return (true);
}
bool _equalIter(Iter *a, Iter *b)
{
return (equal(a->iterexpr, b->iterexpr));
}
static bool
_equalStream(Stream *a, Stream *b)
{
if (a->clausetype != b->clausetype)
return(false);
if (a->groupup != b->groupup)
return(false);
if (a->groupcost != b->groupcost)
return(false);
if (a->groupsel != b->groupsel)
return(false);
if (!equal(a->pathptr, b->pathptr))
return(false);
if (!equal(a->cinfo, b->cinfo))
return(false);
if (!equal(a->upstream, b->upstream))
return(false);
return(equal(a->downstream, b->downstream));
}
/*
* Var is a subclass of Expr.
*/
static bool
_equalVar(Var *a, Var *b)
{
if (a->varno != b->varno)
return (false);
if (a->varattno != b->varattno)
return (false);
if (a->vartype != b->vartype)
return (false);
if (a->varnoold != b->varnoold)
return (false);
if (a->varoattno != b->varoattno)
return (false);
return (true);
}
static bool
_equalArray(Array *a, Array *b)
{
if (a->arrayelemtype != b->arrayelemtype)
return (false);
if (a->arrayndim != b->arrayndim)
return (false);
if (a->arraylow.indx[0] != b->arraylow.indx[0])
return (false);
if (a->arrayhigh.indx[0] != b->arrayhigh.indx[0])
return (false);
if (a->arraylen != b->arraylen)
return (false);
return(TRUE);
}
static bool
_equalArrayRef(ArrayRef *a, ArrayRef *b)
{
if (a->refelemtype != b->refelemtype)
return (false);
if (a->refattrlength != b->refattrlength)
return (false);
if (a->refelemlength != b->refelemlength)
return (false);
if (a->refelembyval != b->refelembyval)
return (false);
if (!equal(a->refupperindexpr, b->refupperindexpr))
return (false);
if (!equal(a->reflowerindexpr, b->reflowerindexpr))
return (false);
if (!equal(a->refexpr, b->refexpr))
return (false);
return (equal(a->refassgnexpr, b->refassgnexpr));
}
/*
* Oper is a subclass of Expr.
*/
static bool
_equalOper(Oper *a, Oper *b)
{
if (a->opno != b->opno)
return (false);
if (a->opresulttype != b->opresulttype)
return (false);
return (true);
}
/*
* Const is a subclass of Expr.
*/
static bool
_equalConst(Const *a, Const *b)
{
/*
** this function used to do a pointer compare on a and b. That's
** ridiculous. -- JMH, 7/11/92
*/
if (a->consttype != b->consttype)
return(false);
if (a->constlen != b->constlen)
return(false);
if (a->constisnull != b->constisnull)
return(false);
if (a->constbyval != b->constbyval)
return(false);
return(datumIsEqual(a->constvalue, b->constvalue,
a->consttype, a->constbyval, a->constlen));
}
/*
* Param is a subclass of Expr.
*/
static bool
_equalParam(Param *a, Param *b)
{
if (a->paramkind != b->paramkind)
return (false);
if (a->paramtype != b->paramtype)
return (false);
if (!equal(a->param_tlist, b->param_tlist))
return (false);
switch (a->paramkind) {
case PARAM_NAMED:
case PARAM_NEW:
case PARAM_OLD:
if (strcmp(a->paramname, b->paramname) != 0)
return (false);
break;
case PARAM_NUM:
if (a->paramid != b->paramid)
return (false);
break;
case PARAM_INVALID:
/*
* XXX: Hmmm... What are we supposed to return
* in this case ??
*/
return(true);
break;
default:
elog(WARN, "_equalParam: Invalid paramkind value: %d",
a->paramkind);
}
return (true);
}
/*
* Func is a subclass of Expr.
*/
static bool
_equalFunc(Func *a, Func *b)
{
if (a->funcid != b->funcid)
return (false);
if (a->functype != b->functype)
return (false);
if (a->funcisindex != b->funcisindex)
return (false);
if (a->funcsize != b->funcsize)
return (false);
if (!equal(a->func_tlist, b->func_tlist))
return (false);
if (!equal(a->func_planlist, b->func_planlist))
return (false);
return (true);
}
/*
* CInfo is a subclass of Node.
*/
static bool
_equalCInfo(CInfo *a, CInfo *b)
{
Assert(IsA(a,CInfo));
Assert(IsA(b,CInfo));
if (!equal(a->clause, b->clause))
return(false);
if (a->selectivity != b->selectivity)
return(false);
if (a->notclause != b->notclause)
return(false);
#ifdef EqualMergeOrderExists
if (!EqualMergeOrder(a->mergesortorder,b->mergesortorder))
return(false);
#endif
if(a->hashjoinoperator != b->hashjoinoperator)
return(false);
return(equal((a->indexids),
(b->indexids)));
}
static bool
_equalJoinMethod(JoinMethod *a, JoinMethod *b)
{
Assert(IsA(a,JoinMethod));
Assert(IsA(b,JoinMethod));
if (!equal((a->jmkeys),
(b->jmkeys)))
return(false);
if (!equal((a->clauses),
(b->clauses)))
return(false);
return(true);
}
static bool
_equalPath(Path *a, Path *b)
{
if (a->pathtype != b->pathtype)
return(false);
if (a->parent != b->parent)
return(false);
/*
if (a->path_cost != b->path_cost)
return(false);
*/
if (a->p_ordering.ordtype == SORTOP_ORDER) {
int i = 0;
if (a->p_ordering.ord.sortop==NULL ||
b->p_ordering.ord.sortop==NULL) {
if (a->p_ordering.ord.sortop != b->p_ordering.ord.sortop)
return false;
} else {
while(a->p_ordering.ord.sortop[i]!=0 &&
b->p_ordering.ord.sortop[i]!=0) {
if (a->p_ordering.ord.sortop[i] != b->p_ordering.ord.sortop[i])
return false;
i++;
}
if (a->p_ordering.ord.sortop[i]!=0 ||
b->p_ordering.ord.sortop[i]!=0)
return false;
}
} else {
if (!equal((a->p_ordering.ord.merge),
(b->p_ordering.ord.merge)))
return(false);
}
if (!equal((a->keys),
(b->keys)))
return(false);
/*
if (a->outerjoincost != b->outerjoincost)
return(false);
*/
if (!equali((a->joinid),
(b->joinid)))
return(false);
return(true);
}
static bool
_equalIndexPath(IndexPath *a, IndexPath *b)
{
if (!_equalPath((Path*)a,(Path*)b))
return(false);
if (!equali((a->indexid), (b->indexid)))
return(false);
if (!equal((a->indexqual), (b->indexqual)))
return(false);
return(true);
}
static bool
_equalJoinPath(JoinPath *a,JoinPath *b)
{
Assert(IsA_JoinPath(a));
Assert(IsA_JoinPath(b));
if (!_equalPath((Path*)a,(Path*)b))
return(false);
if (!equal((a->pathclauseinfo), (b->pathclauseinfo)))
return(false);
if (!equal((a->outerjoinpath), (b->outerjoinpath)))
return(false);
if (!equal((a->innerjoinpath), (b->innerjoinpath)))
return(false);
return(true);
}
static bool
_equalMergePath(MergePath *a, MergePath *b)
{
Assert(IsA(a,MergePath));
Assert(IsA(b,MergePath));
if (!_equalJoinPath((JoinPath*)a,(JoinPath*)b))
return(false);
if (!equal((a->path_mergeclauses), (b->path_mergeclauses)))
return(false);
if (!equal((a->outersortkeys), (b->outersortkeys)))
return(false);
if (!equal((a->innersortkeys), (b->innersortkeys)))
return(false);
return(true);
}
static bool
_equalHashPath(HashPath *a, HashPath *b)
{
Assert(IsA(a,HashPath));
Assert(IsA(b,HashPath));
if (!_equalJoinPath((JoinPath*)a,(JoinPath*)b))
return(false);
if (!equal((a->path_hashclauses), (b->path_hashclauses)))
return(false);
if (!equal((a->outerhashkeys), (b->outerhashkeys)))
return(false);
if (!equal((a->innerhashkeys), (b->innerhashkeys)))
return(false);
return(true);
}
static bool
_equalJoinKey(JoinKey *a, JoinKey *b)
{
Assert(IsA(a,JoinKey));
Assert(IsA(b,JoinKey));
if (!equal((a->outer),(b->outer)))
return(false);
if (!equal((a->inner),(b->inner)))
return(false);
return(true);
}
static bool
_equalMergeOrder(MergeOrder *a, MergeOrder *b)
{
if (a == (MergeOrder*)NULL && b == (MergeOrder*)NULL)
return(true);
Assert(IsA(a,MergeOrder));
Assert(IsA(b,MergeOrder));
if (a->join_operator != b->join_operator)
return(false);
if (a->left_operator != b->left_operator)
return(false);
if (a->right_operator != b->right_operator)
return(false);
if (a->left_type != b->left_type)
return(false);
if (a->right_type != b->right_type)
return(false);
return(true);
}
static bool
_equalHInfo(HInfo *a, HInfo *b)
{
Assert(IsA(a,HInfo));
Assert(IsA(b,HInfo));
if (a->hashop != b->hashop)
return(false);
return(true);
}
/* XXX This equality function is a quick hack, should be
* fixed to compare all fields.
*/
static bool
_equalIndexScan(IndexScan *a, IndexScan *b)
{
Assert(IsA(a,IndexScan));
Assert(IsA(b,IndexScan));
/*
if(a->scan.plan.cost != b->scan.plan.cost)
return(false);
*/
if (!equal((a->indxqual),(b->indxqual)))
return(false);
if (a->scan.scanrelid != b->scan.scanrelid)
return(false);
if (!equali((a->indxid),(b->indxid)))
return(false);
return(true);
}
static bool
_equalJInfo(JInfo *a, JInfo *b)
{
Assert(IsA(a,JInfo));
Assert(IsA(b,JInfo));
if (!equal((a->otherrels),(b->otherrels)))
return(false);
if (!equal((a->jinfoclauseinfo),(b->jinfoclauseinfo)))
return(false);
if (a->mergesortable != b->mergesortable)
return(false);
if (a->hashjoinable != b->hashjoinable)
return(false);
return(true);
}
/*
* Stuff from execnodes.h
*/
/*
* EState is a subclass of Node.
*/
static bool
_equalEState(EState *a, EState *b)
{
if (a->es_direction != b->es_direction)
return (false);
if (!equal(a->es_range_table, b->es_range_table))
return (false);
if (a->es_result_relation_info != b->es_result_relation_info)
return (false);
return (true);
}
/*
* equal -- are two lists equal?
*
* This is a comparison by value. It would be simpler to write it
* to be recursive, but it should run faster if we iterate.
*/
static bool
_equalValue(Value *a, Value *b)
{
if (a->type != b->type)
return (false);
switch(a->type) {
case T_String:
return strcmp(a->val.str, b->val.str);
case T_Integer:
return (a->val.ival==b->val.ival);
case T_Float:
return (a->val.dval==b->val.dval);
default:
break;
}
return (true);
}
/*
* equal--
* returns whether two nodes are equal
*/
bool
equal(void *a, void *b)
{
bool retval;
if (a == b)
return(true);
/*
* note that a!=b, so only one of them can be NULL
*/
if (a==NULL || b==NULL)
return (false);
/*
* are they the same type of nodes?
*/
if (nodeTag(a)!=nodeTag(b))
return (false);
switch(nodeTag(a)) {
case T_Resdom:
retval = _equalResdom(a, b);
break;
case T_Fjoin:
retval = _equalFjoin(a, b);
break;
case T_Expr:
retval = _equalExpr(a, b);
break;
case T_Iter:
retval = _equalIter(a, b);
break;
case T_Stream:
retval = _equalStream(a, b);
break;
case T_Var:
retval = _equalVar(a, b);
break;
case T_Array:
retval = _equalArray(a, b);
break;
case T_ArrayRef:
retval = _equalArrayRef(a, b);
break;
case T_Oper:
retval = _equalOper(a, b);
break;
case T_Const:
retval = _equalConst(a, b);
break;
case T_Param:
retval = _equalParam(a, b);
break;
case T_Func:
retval = _equalFunc(a, b);
break;
case T_CInfo:
retval = _equalCInfo(a, b);
break;
case T_JoinMethod:
retval = _equalJoinMethod(a, b);
break;
case T_Path:
retval = _equalPath(a, b);
break;
case T_IndexPath:
retval = _equalIndexPath(a, b);
break;
case T_JoinPath:
retval = _equalJoinPath(a, b);
break;
case T_MergePath:
retval = _equalMergePath(a, b);
break;
case T_HashPath:
retval = _equalHashPath(a, b);
break;
case T_JoinKey:
retval = _equalJoinKey(a, b);
break;
case T_MergeOrder:
retval = _equalMergeOrder(a, b);
break;
case T_HInfo:
retval = _equalHInfo(a, b);
break;
case T_IndexScan:
retval = _equalIndexScan(a, b);
break;
case T_JInfo:
retval = _equalJInfo(a, b);
break;
case T_EState:
retval = _equalEState(a, b);
break;
case T_Integer: case T_String: case T_Float:
retval = _equalValue(a, b);
break;
case T_List:
{
List *la = (List*)a;
List *lb = (List*)b;
List *l;
if (a==NULL && b==NULL)
return (true);
if (length(a)!=length(b))
return (false);
foreach(l, la) {
if (!equal(lfirst(l), lfirst(lb)))
return (false);
lb = lnext(lb);
}
retval = true;
}
break;
default:
elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
nodeTag(a));
break;
}
return retval;
}
/*
* equali--
* compares two lists of integers
*
* XXX temp hack. needs something like T_IntList
*/
bool equali(List *a, List *b)
{
List *la = (List*)a;
List *lb = (List*)b;
List *l;
if (a==NULL && b==NULL)
return (true);
if (length(a)!=length(b))
return (false);
foreach(l, la) {
if (lfirsti(l) != lfirsti(lb))
return (false);
lb = lnext(lb);
}
return true;
}

View File

@ -0,0 +1,689 @@
/*-------------------------------------------------------------------------
*
* execnodes.h--
* definitions for executor state nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef EXECNODES_H
#define EXECNODES_H
#include "postgres.h"
#include "nodes/nodes.h"
#include "nodes/primnodes.h"
#include "nodes/pg_list.h"
#include "nodes/memnodes.h"
#include "storage/item.h"
#include "access/sdir.h"
#include "access/htup.h"
#include "access/tupdesc.h"
#include "access/funcindex.h"
#include "utils/rel.h"
#include "access/relscan.h"
#include "executor/hashjoin.h"
#include "executor/tuptable.h"
/* ----------------
* IndexInfo information
*
* this class holds the information saying what attributes
* are the key attributes for this index. -cim 10/15/89
*
* NumKeyAttributes number of key attributes for this index
* KeyAttributeNumbers array of attribute numbers used as keys
* Predicate partial-index predicate for this index
* ----------------
*/
typedef struct IndexInfo {
NodeTag type;
int ii_NumKeyAttributes;
AttrNumber *ii_KeyAttributeNumbers;
FuncIndexInfoPtr ii_FuncIndexInfo;
Node *ii_Predicate;
} IndexInfo;
/* ----------------
* RelationInfo information
*
* whenever we update an existing relation, we have to
* update indices on the relation. The RelationInfo class
* is used to hold all the information on result relations,
* including indices.. -cim 10/15/89
*
* RangeTableIndex result relation's range table index
* RelationDesc relation descriptor for result relation
* NumIndices number indices existing on result relation
* IndexRelationDescs array of relation descriptors for indices
* IndexRelationInfo array of key/attr info for indices
* ----------------
*/
typedef struct RelationInfo {
NodeTag type;
Index ri_RangeTableIndex;
Relation ri_RelationDesc;
int ri_NumIndices;
RelationPtr ri_IndexRelationDescs;
IndexInfo **ri_IndexRelationInfo;
} RelationInfo;
/* ----------------
* ExprContext
*
* This class holds the "current context" information
* needed to evaluate expressions for doing tuple qualifications
* and tuple projections. For example, if an expression refers
* to an attribute in the current inner tuple then we need to know
* what the current inner tuple is and so we look at the expression
* context.
* ----------------
*/
typedef struct ExprContext {
NodeTag type;
TupleTableSlot *ecxt_scantuple;
TupleTableSlot *ecxt_innertuple;
TupleTableSlot *ecxt_outertuple;
Relation ecxt_relation;
Index ecxt_relid;
ParamListInfo ecxt_param_list_info;
List *ecxt_range_table;
Datum *ecxt_values; /* precomputed values for aggreg */
char *ecxt_nulls; /* null flags for aggreg values */
} ExprContext;
/* ----------------
* ProjectionInfo node information
*
* This is all the information needed to preform projections
* on a tuple. Nodes which need to do projections create one
* of these. In theory, when a node wants to preform a projection
* it should just update this information as necessary and then
* call ExecProject(). -cim 6/3/91
*
* targetlist target list for projection
* len length of target list
* tupValue array of pointers to projection results
* exprContext expression context for ExecTargetList
* slot slot to place projection result in
* ----------------
*/
typedef struct ProjectionInfo {
NodeTag type;
List *pi_targetlist;
int pi_len;
Datum *pi_tupValue;
ExprContext *pi_exprContext;
TupleTableSlot *pi_slot;
} ProjectionInfo;
/* ----------------
* JunkFilter
*
* this class is used to store information regarding junk attributes.
* A junk attribute is an attribute in a tuple that is needed only for
* storing intermediate information in the executor, and does not belong
* in the tuple proper. For example, when we do a delete or replace
* query, the planner adds an entry to the targetlist so that the tuples
* returned to ExecutePlan() contain an extra attribute: the t_ctid of
* the tuple to be deleted/replaced. This is needed for amdelete() and
* amreplace(). In doing a delete this does not make much of a
* difference, but in doing a replace we have to make sure we disgard
* all the junk in a tuple before calling amreplace(). Otherwise the
* inserted tuple will not have the correct schema. This solves a
* problem with hash-join and merge-sort replace plans. -cim 10/10/90
*
* targetList: the original target list (including junk attributes).
* length: the length of 'targetList'.
* tupType: the tuple descriptor for the "original" tuple
* (including the junk attributes).
* cleanTargetList: the "clean" target list (junk attributes removed).
* cleanLength: the length of 'cleanTargetList'
* cleanTupTyp: the tuple descriptor of the "clean" tuple (with
* junk attributes removed).
* cleanMap: A map with the correspondance between the non junk
* attributes of the "original" tuple and the
* attributes of the "clean" tuple.
* ----------------
*/
typedef struct JunkFilter {
NodeTag type;
List *jf_targetList;
int jf_length;
TupleDesc jf_tupType;
List *jf_cleanTargetList;
int jf_cleanLength;
TupleDesc jf_cleanTupType;
AttrNumber *jf_cleanMap;
} JunkFilter;
/* ----------------
* EState information
*
* direction direction of the scan
*
* range_table array of scan relation information
*
* result_relation_information for update queries
*
* into_relation_descriptor relation being retrieved "into"
*
* param_list_info information needed to transform
* Param nodes into Const nodes
*
* BaseId during InitPlan(), each node is
* given a number. this is the next
* number to be assigned.
*
* tupleTable this is a pointer to an array
* of pointers to tuples used by
* the executor at any given moment.
*
* junkFilter contains information used to
* extract junk attributes from a tuple.
* (see JunkFilter above)
*
* refcount local buffer refcounts used in
* an ExecMain cycle. this is introduced
* to avoid ExecStart's unpinning each
* other's buffers when called recursively
* ----------------
*/
typedef struct EState {
NodeTag type;
ScanDirection es_direction;
List *es_range_table;
RelationInfo *es_result_relation_info;
Relation es_into_relation_descriptor;
ParamListInfo es_param_list_info;
int es_BaseId;
TupleTable es_tupleTable;
JunkFilter *es_junkFilter;
int *es_refcount;
} EState;
/* ----------------
* Executor Type information needed by plannodes.h
*
*| Note: the bogus classes CommonState and CommonScanState exist only
*| because our inheritance system only allows single inheritance
*| and we have to have unique slot names. Hence two or more
*| classes which want to have a common slot must ALL inherit
*| the slot from some other class. (This is a big hack to
*| allow our classes to share slot names..)
*|
*| Example:
*| the class Result and the class NestLoop nodes both want
*| a slot called "OuterTuple" so they both have to inherit
*| it from some other class. In this case they inherit
*| it from CommonState. "CommonState" and "CommonScanState" are
*| the best names I could come up with for this sort of
*| stuff.
*|
*| As a result, many classes have extra slots which they
*| don't use. These slots are denoted (unused) in the
*| comment preceeding the class definition. If you
*| comes up with a better idea of a way of doing things
*| along these lines, then feel free to make your idea
*| known to me.. -cim 10/15/89
* ----------------
*/
/* ----------------------------------------------------------------
* Common Executor State Information
* ----------------------------------------------------------------
*/
/* BaseNode removed -- base_id moved into CommonState - jolly */
/* ----------------
* CommonState information
*
*| this is a bogus class used to hold slots so other
*| nodes can inherit them...
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
*
* ----------------
*/
typedef struct CommonState {
NodeTag type; /* its first field is NodeTag */
int cs_base_id;
TupleTableSlot *cs_OuterTupleSlot;
TupleTableSlot *cs_ResultTupleSlot;
ExprContext *cs_ExprContext;
ProjectionInfo *cs_ProjInfo;
bool cs_TupFromTlist;
} CommonState;
/* ----------------------------------------------------------------
* Control Node State Information
* ----------------------------------------------------------------
*/
/* ----------------
* ResultState information
*
* done flag which tells us to quit when we
* have already returned a constant tuple.
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct ResultState {
CommonState cstate; /* its first field is NodeTag */
int rs_done;
} ResultState;
/* ----------------
* AppendState information
*
* append nodes have this field "unionplans" which is this
* list of plans to execute in sequence.. these variables
* keep track of things..
*
* whichplan which plan is being executed
* nplans how many plans are in the list
* initialized array of ExecInitNode() results
* rtentries range table for the current plan
* result_relation_info_list array of each subplan's result relation info
* junkFilter_list array of each subplan's junk filter
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct AppendState {
CommonState cstate; /* its first field is NodeTag */
int as_whichplan;
int as_nplans;
bool *as_initialized;
List *as_rtentries;
List *as_result_relation_info_list;
List *as_junkFilter_list;
} AppendState;
/* ----------------------------------------------------------------
* Scan State Information
* ----------------------------------------------------------------
*/
/* ----------------
* CommonScanState information
*
* CommonScanState is a class like CommonState, but is used more
* by the nodes like SeqScan and Sort which want to
* keep track of an underlying relation.
*
* currentRelation relation being scanned
* currentScanDesc current scan descriptor for scan
* ScanTupleSlot pointer to slot in tuple table holding scan tuple
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct CommonScanState {
CommonState cstate; /* its first field is NodeTag */
Relation css_currentRelation;
HeapScanDesc css_currentScanDesc;
TupleTableSlot *css_ScanTupleSlot;
} CommonScanState;
/* ----------------
* IndexScanState information
*
*| index scans don't use CommonScanState because
*| the underlying AM abstractions for heap scans and
*| index scans are too different.. It would be nice
*| if the current abstraction was more useful but ... -cim 10/15/89
*
* IndexPtr current index in use
* NumIndices number of indices in this scan
* ScanKeys Skey structures to scan index rels
* NumScanKeys array of no of keys in each Skey struct
* RuntimeKeyInfo array of array of flags for Skeys evaled at runtime
* RelationDescs ptr to array of relation descriptors
* ScanDescs ptr to array of scan descriptors
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct IndexScanState {
CommonState cstate; /* its first field is NodeTag */
int iss_NumIndices;
int iss_IndexPtr;
ScanKey *iss_ScanKeys;
int *iss_NumScanKeys;
Pointer iss_RuntimeKeyInfo;
RelationPtr iss_RelationDescs;
IndexScanDescPtr iss_ScanDescs;
} IndexScanState;
/* ----------------------------------------------------------------
* Join State Information
* ----------------------------------------------------------------
*/
/* ----------------
* JoinState information
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef CommonState JoinState;
/* ----------------
* NestLoopState information
*
* PortalFlag Set to enable portals to work.
*
* JoinState information
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct NestLoopState {
JoinState jstate; /* its first field is NodeTag */
bool nl_PortalFlag;
} NestLoopState;
/* ----------------
* MergeJoinState information
*
* OSortopI outerKey1 sortOp innerKey1 ...
* ISortopO innerkey1 sortOp outerkey1 ...
* JoinState current "state" of join. see executor.h
* MarkedTupleSlot pointer to slot in tuple table for marked tuple
*
* JoinState information
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct MergeJoinState {
JoinState jstate; /* its first field is NodeTag */
List *mj_OSortopI;
List *mj_ISortopO;
int mj_JoinState;
TupleTableSlot *mj_MarkedTupleSlot;
} MergeJoinState;
/* ----------------
* HashJoinState information
*
* hj_HashTable address of the hash table for the hashjoin
* hj_HashTableShmId shared memory id of hash table
* hj_CurBucket the current hash bucket that we are searching
* for matches of the current outer tuple
* hj_CurTuple the current matching inner tuple in the
* current hash bucket
* hj_CurOTuple the current matching inner tuple in the
* current hash overflow chain
* hj_InnerHashKey the inner hash key in the hashjoin condition
* hj_OuterBatches file descriptors for outer batches
* hj_InnerBatches file descriptors for inner batches
* hj_OuterReadPos current read position of outer batch
* hj_OuterReadBlk current read block of outer batch
* hj_OuterTupleSlot tuple slot for outer tuples
* hj_HashTupleSlot tuple slot for hashed tuples
*
*
*
* JoinState information
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct HashJoinState {
JoinState jstate; /* its first field is NodeTag */
HashJoinTable hj_HashTable;
IpcMemoryId hj_HashTableShmId;
HashBucket hj_CurBucket;
HeapTuple hj_CurTuple;
OverflowTuple hj_CurOTuple;
Var *hj_InnerHashKey;
File *hj_OuterBatches;
File *hj_InnerBatches;
char *hj_OuterReadPos;
int hj_OuterReadBlk;
TupleTableSlot *hj_OuterTupleSlot;
TupleTableSlot *hj_HashTupleSlot;
} HashJoinState;
/* ----------------------------------------------------------------
* Materialization State Information
* ----------------------------------------------------------------
*/
/* ----------------
* MaterialState information
*
* materialize nodes are used to materialize the results
* of a subplan into a temporary relation.
*
* Flag indicated whether subplan has been materialized
* TempRelation temporary relation containing result of executing
* the subplan.
*
* CommonScanState information
*
* currentRelation relation descriptor of sorted relation
* currentScanDesc current scan descriptor for scan
* ScanTupleSlot pointer to slot in tuple table holding scan tuple
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct MaterialState {
CommonScanState csstate; /* its first field is NodeTag */
bool mat_Flag;
Relation mat_TempRelation;
} MaterialState;
/* ---------------------
* AggregateState information
*
* done indicated whether aggregate has been materialized
* -------------------------
*/
typedef struct AggState {
CommonScanState csstate; /* its first field is NodeTag */
bool agg_done;
} AggState;
/* ---------------------
* GroupState information
*
* -------------------------
*/
typedef struct GroupState {
CommonScanState csstate; /* its first field is NodeTag */
bool grp_useLastTuple; /* last tuple not processed yet */
bool grp_done;
TupleTableSlot *grp_lastSlot;
} GroupState;
/* ----------------
* SortState information
*
*| sort nodes are really just a kind of a scan since
*| we implement sorts by retrieveing the entire subplan
*| into a temp relation, sorting the temp relation into
*| another sorted relation, and then preforming a simple
*| unqualified sequential scan on the sorted relation..
*| -cim 10/15/89
*
* Flag indicated whether relation has been sorted
* Keys scan key structures used to keep info on sort keys
* TempRelation temporary relation containing result of executing
* the subplan.
*
* CommonScanState information
*
* currentRelation relation descriptor of sorted relation
* currentScanDesc current scan descriptor for scan
* ScanTupleSlot pointer to slot in tuple table holding scan tuple
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct SortState {
CommonScanState csstate; /* its first field is NodeTag */
bool sort_Flag;
ScanKey sort_Keys;
Relation sort_TempRelation;
} SortState;
/* ----------------
* UniqueState information
*
* Unique nodes are used "on top of" sort nodes to discard
* duplicate tuples returned from the sort phase. Basically
* all it does is compare the current tuple from the subplan
* with the previously fetched tuple stored in OuterTuple and
* if the two are identical, then we just fetch another tuple
* from the sort and try again.
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef CommonState UniqueState;
/* ----------------
* HashState information
*
* hashBatches file descriptors for the batches
*
* CommonState information
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
* ExprContext node's current expression context
* ProjInfo info this node uses to form tuple projections
* NumScanAttributes size of ScanAttributes array
* ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct HashState {
CommonState cstate; /* its first field is NodeTag */
File *hashBatches;
} HashState;
/* -----------------------
* TeeState information
* leftPlace : next item in the queue unseen by the left parent
* rightPlace : next item in the queue unseen by the right parent
* lastPlace : last item in the queue
* bufferRelname : name of the relation used as the buffer queue
* bufferRel : the relation used as the buffer queue
* mcxt : for now, tee's have their own memory context
* may be cleaned up later if portals are cleaned up
*
* initially, a Tee starts with [left/right]Place variables set to -1.
* on cleanup, queue is free'd when both leftPlace and rightPlace = -1
* -------------------------
*/
typedef struct TeeState {
CommonState cstate; /* its first field is NodeTag */
int tee_leftPlace;
int tee_rightPlace;
int tee_lastPlace;
char *tee_bufferRelname;
Relation tee_bufferRel;
MemoryContext tee_mcxt;
HeapScanDesc tee_leftScanDesc;
HeapScanDesc tee_rightScanDesc;
} TeeState;
#endif /* EXECNODES_H */

438
src/backend/nodes/list.c Normal file
View File

@ -0,0 +1,438 @@
/*-------------------------------------------------------------------------
*
* list.c--
* various list handling routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
* List of pointers and List of integers separately. Some day,
* someone should unify them. - ay 11/2/94
* This file needs cleanup.
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Oct, 1994 file creation
*
*-------------------------------------------------------------------------
*/
#include <stdarg.h>
#include "postgres.h"
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
#include "utils/builtins.h" /* for namecpy */
#include "utils/elog.h"
#include "utils/palloc.h"
List *
makeList(void *elem, ...)
{
va_list args;
List *retval = NIL;
List *temp = NIL;
List *tempcons = NIL;
va_start(args, elem);
temp = elem;
while (temp != (void *) -1) {
temp = lcons(temp, NIL);
if (tempcons == NIL)
retval = temp;
else
lnext(tempcons) = temp;
tempcons = temp;
temp = va_arg(args, void *);
}
va_end(args);
return (retval);
}
List *
lcons(void *datum, List *list)
{
List *l = makeNode(List);
lfirst(l) = datum;
lnext(l) = list;
return l;
}
List *
lappend(List *list, void *obj)
{
return nconc(list, lcons(obj, NIL));
}
Value *
makeInteger(long i)
{
Value *v = makeNode(Value);
v->type = T_Integer;
v->val.ival = i;
return v;
}
Value *
makeFloat(double d)
{
Value *v = makeNode(Value);
v->type = T_Float;
v->val.dval = d;
return v;
}
Value *
makeString(char *str)
{
Value *v = makeNode(Value);
v->type = T_String;
v->val.str = str;
return v;
}
/* n starts with 0 */
void *
nth(int n, List *l)
{
/* XXX assume list is long enough */
while(n > 0) {
l = lnext(l);
n--;
}
return lfirst(l);
}
/* this is here solely for rt_store. Get rid of me some day! */
void
set_nth(List *l, int n, void *elem)
{
/* XXX assume list is long enough */
while(n > 0) {
l = lnext(l);
n--;
}
lfirst(l) = elem;
return;
}
int
length(List *l)
{
int i=0;
while(l!=NIL) {
l = lnext(l);
i++;
}
return i;
}
void
freeList(List *list)
{
while(list!=NIL) {
List *l = list;
list = lnext(list);
pfree(l);
}
}
/*
* below are for backwards compatibility
*/
List *
append(List *l1, List *l2)
{
List *newlist, *newlist2, *p;
if (l1==NIL)
return copyObject(l2);
newlist = copyObject(l1);
newlist2 = copyObject(l2);
for (p=newlist; lnext(p)!=NIL; p=lnext(p))
;
lnext(p) = newlist2;
return newlist;
}
/*
* below are for backwards compatibility
*/
List *
intAppend(List *l1, List *l2)
{
List *newlist, *newlist2, *p;
if (l1==NIL)
return listCopy(l2);
newlist = listCopy(l1);
newlist2 = listCopy(l2);
for (p=newlist; lnext(p)!=NIL; p=lnext(p))
;
lnext(p) = newlist2;
return newlist;
}
List *
nconc(List *l1, List *l2)
{
List *temp;
if (l1 == NIL)
return l2;
if (l2 == NIL)
return l1;
if (l1 == l2)
elog(WARN, "tryout to nconc a list to itself");
for (temp = l1; lnext(temp)!=NULL; temp = lnext(temp))
;
lnext(temp) = l2;
return(l1); /* list1 is now list1[]list2 */
}
List *
nreverse(List *list)
{
List *rlist = NIL;
List *p = NIL;
if(list==NULL)
return(NIL);
if (length(list) == 1)
return(list);
for (p = list; p!=NULL; p = lnext(p)) {
rlist = lcons(lfirst(p),rlist);
}
lfirst(list) = lfirst(rlist);
lnext(list) = lnext(rlist);
return(list);
}
/*
* same
*
* Returns t if two lists contain the same elements.
* now defined in lispdep.c
*
* XXX only good for IntList -ay
*/
bool
same(List *foo, List *bar)
{
List *temp = NIL;
if (foo == NULL)
return (bar==NULL);
if (bar == NULL)
return (foo==NULL);
if (length(foo) == length(bar)) {
foreach (temp,foo) {
if (!intMember((int)lfirst(temp),bar))
return(false);
}
return(true);
}
return(false);
}
List *
LispUnion(List *foo, List *bar)
{
List *retval = NIL;
List *i = NIL;
List *j = NIL;
if (foo==NIL)
return(bar); /* XXX - should be copy of bar */
if (bar==NIL)
return(foo); /* XXX - should be copy of foo */
foreach (i,foo) {
foreach (j,bar) {
if (! equal(lfirst(i), lfirst(j))) {
retval = lappend(retval,lfirst(i));
break;
}
}
}
foreach(i,bar) {
retval = lappend(retval,lfirst(i));
}
return(retval);
}
List *
LispUnioni(List *foo, List *bar)
{
List *retval = NIL;
List *i = NIL;
List *j = NIL;
if (foo==NIL)
return(bar); /* XXX - should be copy of bar */
if (bar==NIL)
return(foo); /* XXX - should be copy of foo */
foreach (i,foo) {
foreach (j,bar) {
if (lfirsti(i) != lfirsti(j)) {
retval = lappendi(retval,lfirst(i));
break;
}
}
}
foreach(i,bar) {
retval = lappendi(retval, lfirsti(i));
}
return(retval);
}
/*
* member()
* - nondestructive, returns t iff foo is a member of the list
* bar
*/
bool
member(void *foo, List *bar)
{
List *i;
foreach (i,bar)
if (equal((Node*)(lfirst(i)),(Node*)foo))
return(true);
return(false);
}
bool
intMember(int foo, List *bar)
{
List *i;
foreach (i,bar)
if (foo == (int)lfirst(i))
return(true);
return(false);
}
/*
* lremove -
* only does pointer comparisons. Removes 'elem' from the the linked list.
*/
List *
lremove(void *elem, List *list)
{
List *l;
List *prev = NIL;
List *result = list;
foreach(l, list) {
if (elem == lfirst(l))
break;
prev = l;
}
if (l!=NULL) {
if (prev == NIL) {
result = lnext(list);
} else {
lnext(prev) = lnext(l);
}
}
return result;
}
List *
LispRemove(void *elem, List *list)
{
List *temp = NIL;
List *prev = NIL;
if (equal(elem, lfirst(list)))
return lnext(list);
temp = lnext(list);
prev = list;
while(temp!=NIL) {
if (equal(elem, lfirst(temp))) {
lnext(prev) = lnext(temp);
break;
}
temp = lnext(temp);
prev = lnext(prev);
}
return(list);
}
List *
intLispRemove(int elem, List *list)
{
List *temp = NIL;
List *prev = NIL;
if (elem == (int)lfirst(list))
return lnext(list);
temp = lnext(list);
prev = list;
while(temp!=NIL) {
if (elem == (int)lfirst(temp)) {
lnext(prev) = lnext(temp);
break;
}
temp = lnext(temp);
prev = lnext(prev);
}
return(list);
}
List *
set_difference(List *list1, List *list2)
{
List *temp1 = NIL;
List *result = NIL;
if (list2==NIL)
return(list1);
foreach (temp1, list1) {
if (!member(lfirst(temp1), list2))
result = lappend(result, lfirst(temp1));
}
return(result);
}
List *
set_differencei(List *list1, List *list2)
{
List *temp1 = NIL;
List *result = NIL;
if (list2==NIL)
return(list1);
foreach (temp1, list1) {
if (!intMember(lfirsti(temp1), list2))
result = lappendi(result, lfirst(temp1));
}
return(result);
}

View File

@ -0,0 +1,117 @@
/*
* makefuncs.c--
* creator functions for primitive nodes. The functions here are for
* the most frequently created nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
* NOTES
* Creator functions in POSTGRES 4.2 are generated automatically. Most of
* them are rarely used. Now we don't generate them any more. If you want
* one, you have to write it yourself.
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Oct 20, 1994 file creation
*/
#include "postgres.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "nodes/makefuncs.h"
/*
* makeOper -
* creates an Oper node
*/
Oper *
makeOper(Oid opno,
Oid opid,
Oid opresulttype,
int opsize,
FunctionCachePtr op_fcache)
{
Oper *oper = makeNode(Oper);
oper->opno = opno;
oper->opid = opid;
oper->opresulttype = opresulttype;
oper->opsize = opsize;
oper->op_fcache = op_fcache;
return oper;
}
/*
* makeVar -
* creates a Var node
*
*/
Var *
makeVar(Index varno,
AttrNumber varattno,
Oid vartype,
Index varnoold,
AttrNumber varoattno)
{
Var *var = makeNode(Var);
var->varno = varno;
var->varattno = varattno;
var->vartype = vartype;
var->varnoold = varnoold;
var->varoattno = varoattno;
return var;
}
/*
* makeResdom -
* creates a Resdom (Result Domain) node
*/
Resdom *
makeResdom(AttrNumber resno,
Oid restype,
int reslen,
char *resname,
Index reskey,
Oid reskeyop,
int resjunk)
{
Resdom *resdom = makeNode(Resdom);
resdom->resno = resno;
resdom->restype = restype;
resdom->reslen = reslen;
resdom->resname = resname;
resdom->reskey = reskey;
resdom->reskeyop = reskeyop;
resdom->resjunk = resjunk;
return resdom;
}
/*
* makeConst -
* creates a Const node
*/
Const *
makeConst(Oid consttype,
Size constlen,
Datum constvalue,
bool constisnull,
bool constbyval,
bool constisset)
{
Const *cnst = makeNode(Const);
cnst->consttype = consttype;
cnst->constlen = constlen;
cnst->constvalue = constvalue;
cnst->constisnull = constisnull;
cnst->constbyval = constbyval;
cnst->constisset = constisset;
return cnst;
}

View File

@ -0,0 +1,48 @@
/*-------------------------------------------------------------------------
*
* makefuncs.h--
* prototypes for the creator functions (for primitive nodes)
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: makefuncs.h,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef MAKEFUNC_H
#define MAKEFUNC_H
#include "access/attnum.h"
#include "catalog/pg_operator.h"
#include "utils/fcache.h"
#include "nodes/primnodes.h"
extern Oper *makeOper(Oid opno,
Oid opid,
Oid opresulttype,
int opsize,
FunctionCachePtr op_fcache);
extern Var *makeVar(Index varno,
AttrNumber varattno,
Oid vartype,
Index varnoold,
AttrNumber varoattno);
extern Resdom *makeResdom(AttrNumber resno,
Oid restype,
int reslen,
char *resname,
Index reskey,
Oid reskeyop,
int resjunk);
extern Const *makeConst(Oid consttype,
Size constlen,
Datum constvalue,
bool constisnull,
bool constbyval,
bool constisset);
#endif /* MAKEFUNC_H */

View File

@ -0,0 +1,101 @@
/*-------------------------------------------------------------------------
*
* memnodes.h--
* POSTGRES memory context node definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: memnodes.h,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
* XXX the typedefs in this file are different from the other ???nodes.h;
* they are pointers to structures instead of the structures themselves.
* If you're wondering, this is plain laziness. I don't want to touch
* the memory context code which should be revamped altogether some day.
* - ay 10/94
*-------------------------------------------------------------------------
*/
#ifndef MEMNODES_H
#define MEMNODES_H
#include "c.h"
#include "utils/memutils.h"
#include "lib/fstack.h"
#include "nodes/nodes.h"
/*
* MemoryContext --
* A logical context in which memory allocations occur.
*
* The types of memory contexts can be thought of as members of the
* following inheritance hierarchy with properties summarized below.
*
* Node
* |
* MemoryContext___
* / \
* GlobalMemory PortalMemoryContext
* / \
* PortalVariableMemory PortalHeapMemory
*
* Flushed at Flushed at Checkpoints
* Transaction Portal
* Commit Close
*
* GlobalMemory n n n
* PortalVariableMemory n y n
* PortalHeapMemory y y y
*/
typedef struct MemoryContextMethodsData {
Pointer (*alloc)();
void (*free_p)(); /* need to use free as a #define,
so can't use free */
Pointer (*realloc)();
char* (*getName)();
void (*dump)();
} *MemoryContextMethods;
typedef struct MemoryContext {
NodeTag type;
MemoryContextMethods method;
} *MemoryContext;
/* think about doing this right some time but we'll have explicit fields
for now -ay 10/94 */
typedef struct GlobalMemory {
NodeTag type;
MemoryContextMethods method;
AllocSetData setData;
char *name;
OrderedElemData elemData;
} *GlobalMemory;
typedef MemoryContext *PortalMemoryContext;
typedef struct PortalVariableMemory {
NodeTag type;
MemoryContextMethods method;
AllocSetData setData;
} *PortalVariableMemory;
typedef struct PortalHeapMemory {
NodeTag type;
MemoryContextMethods method;
Pointer block;
FixedStackData stackData;
} *PortalHeapMemory;
/*
* MemoryContextIsValid --
* True iff memory context is valid.
*/
#define MemoryContextIsValid(context) \
(IsA(context,MemoryContext) || IsA(context,GlobalMemory) || \
IsA(context,PortalVariableMemory) || IsA(context,PortalHeapMemory))
#endif /* MEMNODES_H */

View File

@ -0,0 +1,116 @@
/*-------------------------------------------------------------------------
*
* nodeFuncs.c--
* All node routines more complicated than simple access/modification
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include "c.h"
#include "nodes/primnodes.h"
#include "nodes/plannodes.h"
#include "nodes/pg_list.h"
#include "nodes/relation.h"
#include "nodes/nodeFuncs.h"
#include "utils/lsyscache.h"
/*
* single_node -
* Returns t if node corresponds to a single-noded expression
*/
bool
single_node(Node *node)
{
if(IsA(node,Ident) || IsA(node,Const) || IsA(node,Var) || IsA(node,Param))
return(true);
else
return(false);
}
/*****************************************************************************
* VAR nodes
*****************************************************************************/
/*
* var_is_outer
* var_is_inner
* var_is_mat
* var_is_rel
*
* Returns t iff the var node corresponds to (respectively):
* the outer relation in a join
* the inner relation of a join
* a materialized relation
* a base relation (i.e., not an attribute reference, a variable from
* some lower join level, or a sort result)
* var node is an array reference
*
*/
bool
var_is_outer (Var *var)
{
return((bool)(var->varno == OUTER));
}
bool
var_is_inner (Var *var)
{
return ( (bool) (var->varno == INNER));
}
bool
var_is_rel (Var *var)
{
return (bool)
! (var_is_inner (var) || var_is_outer (var));
}
/*****************************************************************************
* OPER nodes
*****************************************************************************/
/*
* replace_opid -
*
* Given a oper node, resets the opfid field with the
* procedure OID (regproc id).
*
* Returns the modified oper node.
*
*/
Oper *
replace_opid (Oper *oper)
{
oper->opid = get_opcode(oper->opno);
oper->op_fcache = NULL;
return(oper);
}
/*****************************************************************************
* constant (CONST, PARAM) nodes
*****************************************************************************/
/*
* non_null -
* Returns t if the node is a non-null constant, e.g., if the node has a
* valid `constvalue' field.
*
*/
bool
non_null (Expr *c)
{
if ( IsA(c,Const) && ! ((Const*)c)->constisnull )
return(true);
else
return(false);
}

View File

@ -0,0 +1,23 @@
/*-------------------------------------------------------------------------
*
* nodeFuncs.h--
*
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: nodeFuncs.h,v 1.1.1.1 1996/07/09 06:21:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef NODEFUNCS_H
#define NODEFUNCS_H
extern bool single_node(Node *node);
extern bool var_is_outer(Var *var);
extern bool var_is_inner(Var *var);
extern bool var_is_rel(Var *var);
extern Oper *replace_opid(Oper *oper);
extern bool non_null(Expr *c);
#endif /* NODEFUNCS_H */

45
src/backend/nodes/nodes.c Normal file
View File

@ -0,0 +1,45 @@
/*-------------------------------------------------------------------------
*
* nodes.c--
* support code for nodes (now that we get rid of the home-brew
* inheritance system, our support code for nodes get much simpler)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
* HISTORY
* Andrew Yu Oct 20, 1994 file creation
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/elog.h"
#include "nodes/nodes.h" /* where func declarations of this file goes */
/*
* newNode -
* create a new node of the specified size and tag the node with the
* specified tag.
*
* !WARNING!: Avoid using newNode directly. You should be using the
* macro makeNode. eg. to create a Resdom node, use makeNode(Resdom)
*
*/
Node *
newNode(Size size, NodeTag tag)
{
Node *newNode;
Assert(size >= 4); /* need the tag, at least */
newNode = (Node *)palloc(size);
memset((char *)newNode, 0, size);
newNode->type = tag;
return(newNode);
}

299
src/backend/nodes/nodes.h Normal file
View File

@ -0,0 +1,299 @@
/*-------------------------------------------------------------------------
*
* nodes.h--
* Definitions for tagged nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef NODES_H
#define NODES_H
#include "c.h"
/*
* The first field of every node is NodeTag. Each node created (with makeNode)
* will have one of the following tags as the value of its first field.
*
* Note that the number of the node tags are not contiguous. We left holes
* here so that we can add more tags without changing the existing enum's.
*/
typedef enum NodeTag {
T_Invalid = 0,
/*---------------------
* TAGS FOR PLAN NODES (plannodes.h)
*---------------------
*/
T_Plan = 10,
T_Existential,
T_Result,
T_Append,
T_Scan,
T_SeqScan,
T_IndexScan,
T_Join,
T_NestLoop,
T_MergeJoin,
T_HashJoin,
T_Temp,
T_Material,
T_Sort,
T_Agg,
T_Unique,
T_Hash,
T_Choose,
T_Tee,
T_Group,
/*---------------------
* TAGS FOR PRIMITIVE NODES (primnodes.h)
*---------------------
*/
T_Resdom = 100,
T_Fjoin,
T_Expr,
T_Var,
T_Oper,
T_Const,
T_Param,
T_Aggreg,
T_Func,
T_Array,
T_ArrayRef,
/*---------------------
* TAGS FOR INNER PLAN NODES (relation.h)
*---------------------
*/
T_Rel = 200,
T_Path,
T_IndexPath,
T_JoinPath,
T_MergePath,
T_HashPath,
T_OrderKey,
T_JoinKey,
T_MergeOrder,
T_CInfo,
T_JoinMethod,
T_HInfo,
T_MInfo,
T_JInfo,
T_Iter,
T_Stream,
/*---------------------
* TAGS FOR EXECUTOR NODES (execnodes.h)
*---------------------
*/
T_IndexInfo = 300,
T_RelationInfo,
T_TupleCount,
T_TupleTableSlot,
T_ExprContext,
T_ProjectionInfo,
T_JunkFilter,
T_EState,
T_BaseNode,
T_CommonState,
T_ResultState,
T_AppendState,
T_CommonScanState,
T_ScanState,
T_IndexScanState,
T_JoinState,
T_NestLoopState,
T_MergeJoinState,
T_HashJoinState,
T_MaterialState,
T_AggState,
T_GroupState,
T_SortState,
T_UniqueState,
T_HashState,
T_TeeState,
/*---------------------
* TAGS FOR MEMORY NODES (memnodes.h)
*---------------------
*/
T_MemoryContext = 400,
T_GlobalMemory,
T_PortalMemoryContext,
T_PortalVariableMemory,
T_PortalHeapMemory,
/*---------------------
* TAGS FOR VALUE NODES (pg_list.h)
*---------------------
*/
T_Value = 500,
T_List,
T_Integer,
T_Float,
T_String,
T_Null,
/*---------------------
* TAGS FOR PARSE TREE NODES (parsenode.h)
*---------------------
*/
T_Query = 600,
T_AppendStmt,
T_DeleteStmt,
T_ReplaceStmt,
T_CursorStmt,
T_RetrieveStmt,
T_AddAttrStmt,
T_AggregateStmt,
T_ChangeACLStmt,
T_ClosePortalStmt,
T_ClusterStmt,
T_CopyStmt,
T_CreateStmt,
T_VersionStmt,
T_DefineStmt,
T_DestroyStmt,
T_ExtendStmt,
T_FetchStmt,
T_IndexStmt,
T_MoveStmt,
T_ProcedureStmt,
T_PurgeStmt,
T_RecipeStmt,
T_RemoveFuncStmt,
T_RemoveOperStmt,
T_RemoveStmt,
T_RenameStmt,
T_RuleStmt,
T_NotifyStmt,
T_ListenStmt,
T_TransactionStmt,
T_ViewStmt,
T_LoadStmt,
T_CreatedbStmt,
T_DestroydbStmt,
T_VacuumStmt,
T_ExplainStmt,
T_A_Expr = 700,
T_Attr,
T_A_Const,
T_ParamNo,
T_Ident,
T_FuncCall,
T_A_Indices,
T_ResTarget,
T_ParamString,
T_TimeRange,
T_RelExpr,
T_SortBy,
T_RangeVar,
T_TypeName,
T_IndexElem,
T_ColumnDef,
T_DefElem,
T_TargetEntry,
T_RangeTblEntry,
T_SortClause,
T_GroupClause
} NodeTag;
/*
* The first field of a node of any type is gauranteed to be the NodeTag.
* Hence the type of any node can be gotten by casting it to Node. Declaring
* a variable to be of Node * (instead of void *) can also facilitate
* debugging.
*/
typedef struct Node {
NodeTag type;
} Node;
#define nodeTag(_node_) ((Node*)_node_)->type
#define makeNode(_node_) (_node_*)newNode(sizeof(_node_),T_##_node_)
#define NodeSetTag(n, t) ((Node *)n)->type = t
#define IsA(_node_,_tag_) (nodeTag(_node_) == T_##_tag_)
/* ----------------------------------------------------------------
* IsA functions (no inheritence any more)
* ----------------------------------------------------------------
*/
#define IsA_JoinPath(jp) \
(nodeTag(jp)==T_JoinPath || nodeTag(jp)==T_MergePath || \
nodeTag(jp)==T_HashPath)
#define IsA_Join(j) \
(nodeTag(j)==T_Join || nodeTag(j)==T_NestLoop || \
nodeTag(j)==T_MergeJoin || nodeTag(j)==T_HashJoin)
#define IsA_Temp(t) \
(nodeTag(t)==T_Temp || nodeTag(t)==T_Material || nodeTag(t)==T_Sort || \
nodeTag(t)==T_Unique)
/* ----------------------------------------------------------------
* extern declarations follow
* ----------------------------------------------------------------
*/
/*
* nodes/nodes.c
*/
extern Node *newNode(Size size, NodeTag tag);
/*
* nodes/{outfuncs.c,print.c}
*/
#define nodeDisplay print
extern char *nodeToString(void *obj);
extern void print(void *obj);
/*
* nodes/{readfuncs.c,read.c}
*/
extern void *stringToNode(char *str);
/*
* nodes/copyfuncs.c
*/
extern void *copyObject(void *obj);
/*
* nodes/equalfuncs.c
*/
extern bool equal(void *a, void *b);
/* ----------------
* I don't know why this is here. Most likely a hack..
* -cim 6/3/90
* ----------------
*/
typedef float Cost;
/*
* CmdType -
* enums for type of operation to aid debugging
*
* ??? could have put this in parsenodes.h but many files not in the
* optimizer also need this...
*/
typedef enum CmdType {
CMD_UNKNOWN,
CMD_SELECT, /* select stmt (formerly retrieve) */
CMD_UPDATE, /* update stmt (formerly replace) */
CMD_INSERT, /* insert stmt (formerly append) */
CMD_DELETE,
CMD_NOTIFY,
CMD_UTILITY /* cmds like create, destroy, copy, vacuum, etc. */
} CmdType;
#endif /* NODES_H */

1670
src/backend/nodes/outfuncs.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/*-------------------------------------------------------------------------
*
* params.h--
* Declarations/definitions of stuff needed to handle parameterized plans.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: params.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PARAMS_H
#define PARAMS_H
#include "postgres.h"
#include "access/attnum.h"
/* ----------------------------------------------------------------
*
* The following are the possible values for the 'paramkind'
* field of a Param node.
*
* PARAM_NAMED: The parameter has a name, i.e. something
* like `$.salary' or `$.foobar'.
* In this case field `paramname' must be a valid Name.
* and field `paramid' must be == 0.
*
* PARAM_NUM: The parameter has only a numeric identifier,
* i.e. something like `$1', `$2' etc.
* The number is contained in the `parmid' field.
*
* PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
* The `paramname' & `paramid' refer to the "NEW" tuple
* `paramname' is the attribute name and `paramid' its
* attribute number.
*
* PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
* the "OLD" tuple.
*/
#define PARAM_NAMED 11
#define PARAM_NUM 12
#define PARAM_NEW 13
#define PARAM_OLD 14
#define PARAM_INVALID 100
/* ----------------------------------------------------------------
* ParamListInfo
*
* Information needed in order for the executor to handle
* parameterized plans (you know, $.salary, $.name etc. stuff...).
*
* ParamListInfoData contains information needed when substituting a
* Param node with a Const node.
*
* kind : the kind of parameter.
* name : the parameter name (valid if kind == PARAM_NAMED,
* PARAM_NEW or PARAM_OLD)
* id : the parameter id (valid if kind == PARAM_NUM)
* or the attrno (if kind == PARAM_NEW or PARAM_OLD)
* type : PG_TYPE OID of the value
* length : length in bytes of the value
* isnull : true if & only if the value is null (if true then
* the fields 'length' and 'value' are undefined).
* value : the value that has to be substituted in the place
* of the parameter.
*
* ParamListInfo is to be used as an array of ParamListInfoData
* records. An 'InvalidName' in the name field of such a record
* indicates that this is the last record in the array.
*
* ----------------------------------------------------------------
*/
typedef struct ParamListInfoData {
int kind;
char *name;
AttrNumber id;
Oid type;
Size length;
bool isnull;
bool byval;
Datum value;
} ParamListInfoData;
typedef ParamListInfoData *ParamListInfo;
#endif /* PARAMS_H */

View File

@ -0,0 +1,731 @@
/*-------------------------------------------------------------------------
*
* parsenodes.h--
* definitions for parse tree nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PARSENODES_H
#define PARSENODES_H
#include "nodes/nodes.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "utils/tqual.h"
/*****************************************************************************
* Query Tree
*****************************************************************************/
/*
* Query -
* all statments are turned into a Query tree (via transformStmt)
* for further processing by the optimizer
* utility statements (i.e. non-optimizable statements)
* have the *utilityStmt field set.
*
* we need the isPortal flag because portal names can be null too; can
* get rid of it if we support CURSOR as a commandType.
*
*/
typedef struct Query {
NodeTag type;
CmdType commandType; /* select|insert|update|delete|utility */
Node *utilityStmt; /* non-null if this is a non-optimizable
statement */
int resultRelation; /* target relation (index to rtable) */
char *into; /* portal (cursor) name */
bool isPortal; /* is this a retrieve into portal? */
bool isBinary; /* binary portal? */
char *uniqueFlag; /* NULL, '*', or Unique attribute name */
List *sortClause; /* a list of SortClause's */
List *rtable; /* list of range table entries */
List *targetList; /* target list (of TargetEntry) */
Node *qual; /* qualifications */
List *groupClause; /* list of columns to specified in GROUP BY */
Node *havingQual; /* qualification of each group */
int qry_numAgg; /* number of aggregates in the target list */
Aggreg **qry_aggs; /* the aggregates */
/* internal to planner */
List *base_relation_list_; /* base relation list */
List *join_relation_list_; /* list of relations generated by joins */
bool query_is_archival_; /* archival query flag */
} Query;
/*****************************************************************************
* Other Statements (no optimizations required)
*
* Some of them require a little bit of transformation (which is also
* done by transformStmt). The whole structure is then passed on to
* ProcessUtility (by-passing the optimization step) as the utilityStmt
* field in Query.
*****************************************************************************/
/* ----------------------
* Add Column Statement
* ----------------------
*/
typedef struct AddAttrStmt {
NodeTag type;
char *relname; /* the relation to add attr */
bool inh; /* add recursively to children? */
struct ColumnDef *colDef; /* the attribute definition */
} AddAttrStmt;
/* ----------------------
* Change ACL Statement
* ----------------------
*/
typedef struct ChangeACLStmt {
NodeTag type;
struct AclItem *aclitem;
unsigned modechg;
List *relNames;
} ChangeACLStmt;
/* ----------------------
* Close Portal Statement
* ----------------------
*/
typedef struct ClosePortalStmt {
NodeTag type;
char *portalname; /* name of the portal (cursor) */
} ClosePortalStmt;
/* ----------------------
* Copy Statement
* ----------------------
*/
typedef struct CopyStmt {
NodeTag type;
bool binary; /* is a binary copy? */
char *relname; /* the relation to copy */
int direction; /* TO or FROM */
char *filename; /* if NULL, use stdin/stdout */
char *delimiter; /* delimiter character, \t by default*/
} CopyStmt;
/* ----------------------
* Create Table Statement
* ----------------------
*/
typedef enum ArchType {
ARCH_NONE, ARCH_LIGHT, ARCH_HEAVY /* archive mode */
} ArchType;
typedef struct CreateStmt {
NodeTag type;
char *relname; /* the relation to create */
List *tableElts; /* column definitions
list of ColumnDef */
List *inhRelnames; /* relations to inherit from
list of Value (string) */
ArchType archiveType; /* archive mode (ARCH_NONE if none */
int location; /* smgrid (-1 if none) */
int archiveLoc; /* smgrid (-1 if none) */
} CreateStmt;
/* ----------------------
* Create Version Statement
* ----------------------
*/
typedef struct VersionStmt {
NodeTag type;
char *relname; /* the new relation */
int direction; /* FORWARD | BACKWARD */
char *fromRelname; /* relation to create a version */
char *date; /* date of the snapshot */
} VersionStmt;
/* ----------------------
* Create {Operator|Type|Aggregate} Statement
* ----------------------
*/
typedef struct DefineStmt {
NodeTag type;
int defType; /* OPERATOR|P_TYPE|AGGREGATE*/
char *defname;
List *definition; /* a list of DefElem */
} DefineStmt;
/* ----------------------
* Drop Table Statement
* ----------------------
*/
typedef struct DestroyStmt {
NodeTag type;
List *relNames; /* relations to be dropped */
} DestroyStmt;
/* ----------------------
* Extend Index Statement
* ----------------------
*/
typedef struct ExtendStmt {
NodeTag type;
char *idxname; /* name of the index */
Node *whereClause; /* qualifications */
List *rangetable; /* range table, filled in
by transformStmt() */
} ExtendStmt;
/* ----------------------
* Begin Recipe Statement
* ----------------------
*/
typedef struct RecipeStmt {
NodeTag type;
char *recipeName; /* name of the recipe*/
} RecipeStmt;
/* ----------------------
* Fetch Statement
* ----------------------
*/
typedef struct FetchStmt {
NodeTag type;
int direction; /* FORWARD or BACKWARD */
int howMany; /* amount to fetch ("ALL" --> 0) */
char *portalname; /* name of portal (cursor) */
} FetchStmt;
/* ----------------------
* Create Index Statement
* ----------------------
*/
typedef struct IndexStmt {
NodeTag type;
char *idxname; /* name of the index */
char *relname; /* name of relation to index on */
char *accessMethod; /* name of acess methood (eg. btree) */
List *indexParams; /* a list of IndexElem */
List *withClause; /* a list of ParamString */
Node *whereClause; /* qualifications */
List *rangetable; /* range table, filled in
by transformStmt() */
} IndexStmt;
/* ----------------------
* Move Statement (Not implemented)
* ----------------------
*/
typedef struct MoveStmt {
NodeTag type;
int direction; /* FORWARD or BACKWARD */
bool to;
int where;
char *portalname;
} MoveStmt;
/* ----------------------
* Create Function Statement
* ----------------------
*/
typedef struct ProcedureStmt {
NodeTag type;
char *funcname; /* name of function to create */
List *defArgs; /* list of definitions
a list of strings (as Value *) */
Node *returnType; /* the return type (as a string or
a TypeName (ie.setof) */
List *withClause; /* a list of ParamString */
char *as; /* the SQL statement or filename */
char *language; /* C or SQL */
} ProcedureStmt;
/* ----------------------
* Purge Statement
* ----------------------
*/
typedef struct PurgeStmt {
NodeTag type;
char *relname; /* relation to purge */
char *beforeDate; /* purge before this date */
char *afterDate; /* purge after this date */
} PurgeStmt;
/* ----------------------
* Drop Function Statement
* ----------------------
*/
typedef struct RemoveFuncStmt {
NodeTag type;
char *funcname; /* function to drop */
List *args; /* types of the arguments */
} RemoveFuncStmt;
/* ----------------------
* Drop Operator Statement
* ----------------------
*/
typedef struct RemoveOperStmt {
NodeTag type;
char *opname; /* operator to drop */
List *args; /* types of the arguments */
} RemoveOperStmt;
/* ----------------------
* Drop {Aggregate|Type|Index|Rule|View} Statement
* ----------------------
*/
typedef struct RemoveStmt {
NodeTag type;
int removeType; /* AGGREGATE|P_TYPE|INDEX|RULE|VIEW */
char *name; /* name to drop */
} RemoveStmt;
/* ----------------------
* Alter Table Statement
* ----------------------
*/
typedef struct RenameStmt {
NodeTag type;
char *relname; /* relation to be altered */
bool inh; /* recursively alter children? */
char *column; /* if NULL, rename the relation name
to the new name. Otherwise, rename
this column name. */
char *newname; /* the new name */
} RenameStmt;
/* ----------------------
* Create Rule Statement
* ----------------------
*/
typedef struct RuleStmt {
NodeTag type;
char *rulename; /* name of the rule */
Node *whereClause; /* qualifications */
CmdType event; /* RETRIEVE */
struct Attr *object; /* object affected */
bool instead; /* is a 'do instead'? */
List *actions; /* the action statements */
} RuleStmt;
/* ----------------------
* Notify Statement
* ----------------------
*/
typedef struct NotifyStmt {
NodeTag type;
char *relname; /* relation to notify */
} NotifyStmt;
/* ----------------------
* Listen Statement
* ----------------------
*/
typedef struct ListenStmt {
NodeTag type;
char *relname; /* relation to listen on */
} ListenStmt;
/* ----------------------
* {Begin|Abort|End} Transaction Statement
* ----------------------
*/
typedef struct TransactionStmt {
NodeTag type;
int command; /* BEGIN|END|ABORT */
} TransactionStmt;
/* ----------------------
* Create View Statement
* ----------------------
*/
typedef struct ViewStmt {
NodeTag type;
char *viewname; /* name of the view */
Query *query; /* the SQL statement */
} ViewStmt;
/* ----------------------
* Load Statement
* ----------------------
*/
typedef struct LoadStmt {
NodeTag type;
char *filename; /* file to load */
} LoadStmt;
/* ----------------------
* Createdb Statement
* ----------------------
*/
typedef struct CreatedbStmt {
NodeTag type;
char *dbname; /* database to create */
} CreatedbStmt;
/* ----------------------
* Destroydb Statement
* ----------------------
*/
typedef struct DestroydbStmt {
NodeTag type;
char *dbname; /* database to drop */
} DestroydbStmt;
/* ----------------------
* Cluster Statement (support pbrown's cluster index implementation)
* ----------------------
*/
typedef struct ClusterStmt {
NodeTag type;
char *relname; /* relation being indexed */
char *indexname; /* original index defined */
} ClusterStmt;
/* ----------------------
* Vacuum Statement
* ----------------------
*/
typedef struct VacuumStmt {
NodeTag type;
char *vacrel; /* table to vacuum */
} VacuumStmt;
/* ----------------------
* Explain Statement
* ----------------------
*/
typedef struct ExplainStmt {
NodeTag type;
Query *query; /* the query */
List *options;
} ExplainStmt;
/*****************************************************************************
* Optimizable Statements
*****************************************************************************/
/* ----------------------
* Insert Statement
* ----------------------
*/
typedef struct AppendStmt {
NodeTag type;
char *relname; /* relation to insert into */
List *cols; /* names of the columns */
List *exprs; /* the expressions (same order as
the columns) */
List *fromClause; /* the from clause */
Node *whereClause; /* qualifications */
} AppendStmt;
/* ----------------------
* Delete Statement
* ----------------------
*/
typedef struct DeleteStmt {
NodeTag type;
char *relname; /* relation to delete from */
Node *whereClause; /* qualifications */
} DeleteStmt;
/* ----------------------
* Update Statement
* ----------------------
*/
typedef struct ReplaceStmt {
NodeTag type;
char *relname; /* relation to update */
List *targetList; /* the target list (of ResTarget) */
Node *whereClause; /* qualifications */
List *fromClause; /* the from clause */
} ReplaceStmt;
/* ----------------------
* Create Cursor Statement
* ----------------------
*/
typedef struct CursorStmt {
NodeTag type;
char *portalname; /* the portal (cursor) to create */
bool binary; /* a binary (internal) portal? */
char *unique; /* NULL, "*", or unique attribute name */
List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the from clause */
Node *whereClause; /* qualifications */
List *orderClause; /* sort clause (a list of SortBy's) */
} CursorStmt;
/* ----------------------
* Select Statement
* ----------------------
*/
typedef struct RetrieveStmt {
NodeTag type;
char *unique; /* NULL, '*', or unique attribute name */
char *into; /* name of table (for select into
table) */
List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the from clause */
Node *whereClause; /* qualifications */
List *groupClause; /* group by clause */
Node *havingClause; /* having conditional-expression */
List *orderClause; /* sort clause (a list of SortBy's) */
} RetrieveStmt;
/****************************************************************************
* Supporting data structures for Parse Trees
****************************************************************************/
/*
* TypeName - specifies a type in definitions
*/
typedef struct TypeName {
NodeTag type;
char *name; /* name of the type */
bool setof; /* is a set? */
List *arrayBounds; /* array bounds */
int typlen; /* length for char() and varchar() */
} TypeName;
/*
* ParamNo - specifies a parameter reference
*/
typedef struct ParamNo {
NodeTag type;
int number; /* the number of the parameter */
TypeName *typename; /* the typecast */
} ParamNo;
/*
* A_Expr - binary expressions
*/
typedef struct A_Expr {
NodeTag type;
int oper; /* type of operation
{OP,OR,AND,NOT,ISNULL,NOTNULL} */
char *opname; /* name of operator/function */
Node *lexpr; /* left argument */
Node *rexpr; /* right argument */
} A_Expr;
/*
* Attr -
* specifies an Attribute (ie. a Column); could have nested dots or
* array references.
*
*/
typedef struct Attr {
NodeTag type;
char *relname; /* name of relation (can be "*") */
ParamNo *paramNo; /* or a parameter */
List *attrs; /* attributes (possibly nested);
list of Values (strings) */
List *indirection; /* array refs (list of A_Indices') */
} Attr;
/*
* A_Const - a constant expression
*/
typedef struct A_Const {
NodeTag type;
Value val; /* the value (with the tag) */
TypeName *typename; /* typecast */
} A_Const;
/*
* ColumnDef - column definition (used in various creates)
*/
typedef struct ColumnDef {
NodeTag type;
char *colname; /* name of column */
TypeName *typename; /* type of column */
} ColumnDef;
/*
* Ident -
* an identifier (could be an attribute or a relation name). Depending
* on the context at transformStmt time, the identifier is treated as
* either a relation name (in which case, isRel will be set) or an
* attribute (in which case, it will be transformed into an Attr).
*/
typedef struct Ident {
NodeTag type;
char *name; /* its name */
List *indirection; /* array references */
bool isRel; /* is a relation - filled in by
transformExpr() */
} Ident;
/*
* FuncCall - a function/aggregate invocation
*/
typedef struct FuncCall {
NodeTag type;
char *funcname; /* name of function */
List *args; /* the arguments (list of exprs) */
} FuncCall;
/*
* A_Indices - array reference or bounds ([lidx:uidx] or [uidx])
*/
typedef struct A_Indices {
NodeTag type;
Node *lidx; /* could be NULL */
Node *uidx;
} A_Indices;
/*
* ResTarget -
* result target (used in target list of pre-transformed Parse trees)
*/
typedef struct ResTarget {
NodeTag type;
char *name; /* name of the result column */
List *indirection; /* array references */
Node *val; /* the value of the result
(A_Expr or Attr) */
} ResTarget;
/*
* ParamString - used in with clauses
*/
typedef struct ParamString {
NodeTag type;
char *name;
char *val;
} ParamString;
/*
* TimeRange - specifies a time range
*/
typedef struct TimeRange {
NodeTag type;
char *startDate;
char *endDate; /* snapshot if NULL */
} TimeRange;
/*
* RelExpr - relation expressions
*/
typedef struct RelExpr {
NodeTag type;
char *relname; /* the relation name */
bool inh; /* inheritance query */
TimeRange *timeRange; /* the time range */
} RelExpr;
/*
* Sortby - for order by clause
*/
typedef struct SortBy {
NodeTag type;
char *name; /* name of column to sort on */
char *useOp; /* operator to use */
} SortBy;
/*
* RangeVar - range variable, used in from clauses
*/
typedef struct RangeVar {
NodeTag type;
RelExpr *relExpr; /* the relation expression */
char *name; /* the name to be referenced
(optional) */
} RangeVar;
/*
* IndexElem - index parameters (used in create index)
*/
typedef struct IndexElem {
NodeTag type;
char *name; /* name of index */
List *args; /* if not NULL, function index */
char *class;
} IndexElem;
/*
* DefElem -
* a definition (used in definition lists in the form of defname = arg)
*/
typedef struct DefElem {
NodeTag type;
char *defname;
Node *arg; /* a (Value *) or a (TypeName *) */
} DefElem;
/****************************************************************************
* Nodes for a Query tree
****************************************************************************/
/*
* TargetEntry -
* a target entry (used in the transformed target list)
*
* one of resdom or fjoin is not NULL. a target list is
* ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
*/
typedef struct TargetEntry {
NodeTag type;
Resdom *resdom; /* fjoin overload this to be a list??*/
Fjoin *fjoin;
Node *expr; /* can be a list too */
} TargetEntry;
/*
* RangeTblEntry -
* used in range tables. Some of the following are only used in one of
* the parsing, optimizing, execution stages.
*
* inFromCl marks those range variables that are listed in the from clause.
* In SQL, the targetlist can only refer to range variables listed in the
* from clause but POSTQUEL allows you to refer to tables not specified, in
* which case a range table entry will be generated. We use POSTQUEL
* semantics which is more powerful. However, we need SQL semantics in
* some cases (eg. when expanding a '*')
*/
typedef struct RangeTblEntry {
NodeTag type;
char *relname; /* real name of the relation */
TimeRange *timeRange; /* time range */
char *refname; /* the reference name (specified in
the from clause) */
Oid relid;
bool inh; /* inheritance? */
bool archive; /* filled in by plan_archive */
bool inFromCl; /* comes from From Clause */
TimeQual timeQual; /* filled in by pg_plan */
} RangeTblEntry;
/*
* SortClause -
* used in the sort clause for retrieves and cursors
*/
typedef struct SortClause {
NodeTag type;
Resdom *resdom; /* attributes in tlist to be sorted */
Oid opoid; /* sort operators */
} SortClause;
/*
* GroupClause -
* used in the GROUP BY clause
*/
typedef struct GroupClause {
NodeTag type;
Var *grpAttr; /* attributes to group on */
Oid grpOpoid; /* the sort operator to use */
} GroupClause;
#endif /* PARSENODES_H */

112
src/backend/nodes/pg_list.h Normal file
View File

@ -0,0 +1,112 @@
/*-------------------------------------------------------------------------
*
* pg_list.h--
* POSTGRES generic list package
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_list.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PG_LIST_H
#define PG_LIST_H
#include <stdio.h>
#include "c.h"
#include "nodes/nodes.h"
/* ----------------------------------------------------------------
* node definitions
* ----------------------------------------------------------------
*/
/*----------------------
* Value node
*----------------------
*/
typedef struct Value {
NodeTag type; /* tag appropriately (eg. T_String) */
union ValUnion {
char *str; /* string */
long ival;
double dval;
} val;
} Value;
#define intVal(v) (((Value *)v)->val.ival)
#define floatVal(v) (((Value *)v)->val.dval)
#define strVal(v) (((Value *)v)->val.str)
/*----------------------
* List node
*----------------------
*/
typedef struct List {
NodeTag type;
void *elem;
struct List *next;
} List;
#define NIL ((List *) NULL)
/* ----------------
* accessor macros
* ----------------
*/
#define lfirst(l) ((l)->elem)
#define lnext(l) ((l)->next)
#define lsecond(l) (lfirst(lnext(l)))
/*
* foreach -
* a convenience macro which loops through the list
*/
#define foreach(_elt_,_list_) \
for(_elt_=_list_; _elt_!=NIL;_elt_=lnext(_elt_))
/*
* function prototypes in nodes/list.c
*/
extern int length(List *list);
extern List *append(List *list1, List *list2);
extern List *nconc(List *list1, List *list2);
extern List *lcons(void *datum, List *list);
extern bool member(void *foo, List *bar);
extern Value *makeInteger(long i);
extern Value *makeFloat(double d);
extern Value *makeString(char *str);
extern List *makeList(void *elem, ...);
extern List *lappend(List *list, void *obj);
extern List *lremove(void *elem, List *list);
extern void freeList(List *list);
extern void *nth(int n, List *l);
extern void set_nth(List *l, int n, void *elem);
/* hack for now */
#define lconsi(i,l) lcons((void*)i,l)
#define lfirsti(l) ((int)lfirst(l))
#define lappendi(l,i) lappend(l,(void*)i)
extern bool intMember(int, List *);
extern List *intAppend(List *list1, List *list2);
extern List *nreverse(List *);
extern List *set_difference(List *, List *);
extern List *set_differencei(List *, List *);
extern List *LispRemove(void *, List *);
extern List *intLispRemove(int, List *);
extern List *LispUnion(List *foo, List *bar);
extern List *LispUnioni(List *foo, List *bar);
extern bool same(List *foo, List *bar);
/* should be in nodes.h but needs List */
extern bool equali(List *a, List *b);
/* in copyfuncs.c */
extern List *listCopy(List *);
#endif /* PG_LIST_H */

View File

@ -0,0 +1,330 @@
/*-------------------------------------------------------------------------
*
* plannodes.h--
* definitions for query plan nodes
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: plannodes.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PLANNODES_H
#define PLANNODES_H
#include "postgres.h"
#include "nodes/nodes.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
/* ----------------------------------------------------------------
* Executor State types are used in the plannode structures
* so we have to include their definitions too.
*
* Node Type node information used by executor
*
* control nodes
*
* Existential ExistentialState exstate;
* Result ResultState resstate;
* Append AppendState unionstate;
*
* scan nodes
*
* Scan *** CommonScanState scanstate;
* IndexScan IndexScanState indxstate;
*
* (*** nodes which inherit Scan also inherit scanstate)
*
* join nodes
*
* NestLoop NestLoopState nlstate;
* MergeJoin MergeJoinState mergestate;
* HashJoin HashJoinState hashjoinstate;
*
* materialize nodes
*
* Material MaterialState matstate;
* Sort SortState sortstate;
* Unique UniqueState uniquestate;
* Hash HashState hashstate;
*
* ----------------------------------------------------------------
*/
#include "nodes/execnodes.h" /* XXX move executor types elsewhere */
/* ----------------------------------------------------------------
* node definitions
* ----------------------------------------------------------------
*/
/* ----------------
* Plan node
* ----------------
*/
typedef struct Plan {
NodeTag type;
Cost cost;
int plan_size;
int plan_width;
int plan_tupperpage;
EState *state; /* at execution time, state's of individual
nodes point to one EState for the
whole top-level plan */
List *targetlist;
List *qual; /* Node* or List* ?? */
struct Plan *lefttree;
struct Plan *righttree;
} Plan;
/* ----------------
* these are are defined to avoid confusion problems with "left"
* and "right" and "inner" and "outer". The convention is that
* the "left" plan is the "outer" plan and the "right" plan is
* the inner plan, but these make the code more readable.
* ----------------
*/
#define innerPlan(node) (((Plan *)(node))->righttree)
#define outerPlan(node) (((Plan *)(node))->lefttree)
/*
* ===============
* Top-level nodes
* ===============
*/
/* all plan nodes "derive" from the Plan structure by having the
Plan structure as the first field. This ensures that everything works
when nodes are cast to Plan's. (node pointers are frequently cast to Plan*
when passed around generically in the executor */
/* ----------------
* existential node
* ----------------
*/
typedef Plan Existential;
/* ----------------
* result node -
* returns tuples from outer plan that satisfy the qualifications
* ----------------
*/
typedef struct Result {
Plan plan;
Node *resconstantqual;
ResultState *resstate;
} Result;
/* ----------------
* append node
* ----------------
*/
typedef struct Append {
Plan plan;
List *unionplans;
Index unionrelid;
List *unionrtentries;
AppendState *unionstate;
} Append;
/*
* ==========
* Scan nodes
* ==========
*/
typedef struct Scan {
Plan plan;
Index scanrelid; /* relid is index into the range table */
CommonScanState *scanstate;
} Scan;
/* ----------------
* sequential scan node
* ----------------
*/
typedef Scan SeqScan;
/* ----------------
* index scan node
* ----------------
*/
typedef struct IndexScan {
Scan scan;
List *indxid;
List *indxqual;
IndexScanState *indxstate;
} IndexScan;
/*
* ==========
* Join nodes
* ==========
*/
/* ----------------
* Join node
* ----------------
*/
typedef Plan Join;
/* ----------------
* nest loop join node
* ----------------
*/
typedef struct NestLoop {
Join join;
NestLoopState *nlstate;
} NestLoop;
/* ----------------
* merge join node
* ----------------
*/
typedef struct MergeJoin {
Join join;
List *mergeclauses;
Oid mergesortop;
Oid *mergerightorder; /* inner sort operator */
Oid *mergeleftorder; /* outer sort operator */
MergeJoinState *mergestate;
} MergeJoin;
/* ----------------
* hash join (probe) node
* ----------------
*/
typedef struct HashJoin {
Join join;
List *hashclauses;
Oid hashjoinop;
HashJoinState *hashjoinstate;
HashJoinTable hashjointable;
IpcMemoryKey hashjointablekey;
int hashjointablesize;
bool hashdone;
} HashJoin;
/* ---------------
* aggregate node
* ---------------
*/
typedef struct Agg {
Plan plan;
int numAgg;
Aggreg **aggs;
AggState *aggstate;
} Agg;
/* ---------------
* group node -
* use for queries with GROUP BY specified.
*
* If tuplePerGroup is true, one tuple (with group columns only) is
* returned for each group and NULL is returned when there are no more
* groups. Otherwise, all the tuples of a group are returned with a
* NULL returned at the end of each group. (see nodeGroup.c for details)
* ---------------
*/
typedef struct Group {
Plan plan;
bool tuplePerGroup; /* what tuples to return (see above) */
int numCols; /* number of group columns */
AttrNumber *grpColIdx; /* index into the target list */
GroupState *grpstate;
} Group;
/*
* ==========
* Temp nodes
* ==========
*/
typedef struct Temp {
Plan plan;
Oid tempid;
int keycount;
} Temp;
/* ----------------
* materialization node
* ----------------
*/
typedef struct Material {
Plan plan; /* temp node flattened out */
Oid tempid;
int keycount;
MaterialState *matstate;
} Material;
/* ----------------
* sort node
* ----------------
*/
typedef struct Sort {
Plan plan; /* temp node flattened out */
Oid tempid;
int keycount;
SortState *sortstate;
} Sort;
/* ----------------
* unique node
* ----------------
*/
typedef struct Unique {
Plan plan; /* temp node flattened out */
Oid tempid;
int keycount;
char *uniqueAttr; /* NULL if all attrs,
or unique attribute name */
AttrNumber uniqueAttrNum; /* attribute number of attribute
to select distinct on */
UniqueState *uniquestate;
} Unique;
/* ----------------
* hash build node
* ----------------
*/
typedef struct Hash {
Plan plan;
Var *hashkey;
HashState *hashstate;
HashJoinTable hashtable;
IpcMemoryKey hashtablekey;
int hashtablesize;
} Hash;
/* ---------------------
* choose node
* ---------------------
*/
typedef struct Choose {
Plan plan;
List *chooseplanlist;
} Choose;
/* -------------------
* Tee node information
*
* leftParent : the left parent of this node
* rightParent: the right parent of this node
* -------------------
*/
typedef struct Tee {
Plan plan;
Plan* leftParent;
Plan* rightParent;
TeeState *teestate;
char *teeTableName; /* the name of the table to materialize
the tee into */
List *rtentries; /* the range table for the plan below the Tee
may be different than the parent plans */
} Tee;
#endif /* PLANNODES_H */

View File

@ -0,0 +1,318 @@
/*-------------------------------------------------------------------------
*
* primnodes.h--
* Definitions for parse tree/query tree ("primitive") nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: primnodes.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PRIMNODES_H
#define PRIMNODES_H
#include "postgres.h"
#include "access/attnum.h"
#include "storage/buf.h"
#include "utils/rel.h"
#include "utils/fcache.h"
#include "nodes/params.h"
#include "nodes/nodes.h"
#include "nodes/pg_list.h"
/* ----------------------------------------------------------------
* node definitions
* ----------------------------------------------------------------
*/
/* ----------------
* Resdom (Result Domain)
* resno - attribute number
* restype - type of the resdom
* reslen - length (in bytes) of the result
* resname - name of the resdom (could be NULL)
* reskey - order of key in a sort (for those > 0)
* reskeyop - sort operator Oid
* resjunk - set to nonzero to eliminate the attribute
* from final target list e.g., ctid for replace
* and delete
*
* ----------------
*/
typedef struct Resdom {
NodeTag type;
AttrNumber resno;
Oid restype;
int reslen;
char *resname;
Index reskey;
Oid reskeyop;
int resjunk;
} Resdom;
/* -------------
* Fjoin
* initialized - true if the Fjoin has already been initialized for
* the current target list evaluation
* nNodes - The number of Iter nodes returning sets that the
* node will flatten
* outerList - 1 or more Iter nodes
* inner - exactly one Iter node. We eval every node in the
* outerList once then eval the inner node to completion
* pair the outerList result vector with each inner
* result to form the full result. When the inner has
* been exhausted, we get the next outer result vector
* and reset the inner.
* results - The complete (flattened) result vector
* alwaysNull - a null vector to indicate sets with a cardinality of
* 0, we treat them as the set {NULL}.
*/
typedef struct Fjoin {
NodeTag type;
bool fj_initialized;
int fj_nNodes;
List *fj_innerNode;
DatumPtr fj_results;
BoolPtr fj_alwaysDone;
} Fjoin;
/* ----------------
* Expr
* typeOid - oid of the type of this expression
* opType - type of this expression
* oper - the Oper node if it is an OPER_EXPR or the
* Func node if it is a FUNC_EXPR
* args - arguments to this expression
* ----------------
*/
typedef enum OpType {
OP_EXPR, FUNC_EXPR, OR_EXPR, AND_EXPR, NOT_EXPR
} OpType;
typedef struct Expr {
NodeTag type;
Oid typeOid; /* oid of the type of this expr */
OpType opType; /* type of the op */
Node *oper; /* could be Oper or Func */
List *args; /* list of argument nodes */
} Expr;
/* ----------------
* Var
* varno - index of this var's relation in the range table
* (could be INNER or OUTER)
* varattno - attribute number of this var
* vartype - pg_type tuple oid for the type of this var
* varnoold - keep varno around in case it got changed to INNER/
* OUTER (see match_varid)
* varoattno - attribute number of this var
* [ '(varnoold varoattno) was varid -ay 2/95]
* ----------------
*/
#define INNER 65000
#define OUTER 65001
#define PRS2_CURRENT_VARNO 1
#define PRS2_NEW_VARNO 2
typedef struct Var {
NodeTag type;
Index varno;
AttrNumber varattno;
Oid vartype;
Index varnoold; /* only used by optimizer */
AttrNumber varoattno; /* only used by optimizer */
} Var;
/* ----------------
* Oper
* opno - PG_OPERATOR OID of the operator
* opid - PG_PROC OID for the operator
* opresulttype - PG_TYPE OID of the operator's return value
* opsize - size of return result (cached by executor)
* op_fcache - XXX comment me.
*
* ----
* NOTE: in the good old days 'opno' used to be both (or either, or
* neither) the pg_operator oid, and/or the pg_proc oid depending
* on the postgres module in question (parser->pg_operator,
* executor->pg_proc, planner->both), the mood of the programmer,
* and the phase of the moon (rumors that it was also depending on the day
* of the week are probably false). To make things even more postgres-like
* (i.e. a mess) some comments were referring to 'opno' using the name
* 'opid'. Anyway, now we have two separate fields, and of course that
* immediately removes all bugs from the code... [ sp :-) ].
* ----------------
*/
typedef struct Oper {
NodeTag type;
Oid opno;
Oid opid;
Oid opresulttype;
int opsize;
FunctionCachePtr op_fcache;
} Oper;
/* ----------------
* Const
* consttype - PG_TYPE OID of the constant's value
* constlen - length in bytes of the constant's value
* constvalue - the constant's value
* constisnull - whether the constant is null
* (if true, the other fields are undefined)
* constbyval - whether the information in constvalue
* if passed by value. If true, then all the information
* is stored in the datum. If false, then the datum
* contains a pointer to the information.
* constisset - whether the const represents a set. The const
* value corresponding will be the query that defines
* the set.
* ----------------
*/
typedef struct Const {
NodeTag type;
Oid consttype;
Size constlen;
Datum constvalue;
bool constisnull;
bool constbyval;
bool constisset;
} Const;
/* ----------------
* Param
* paramkind - specifies the kind of parameter. The possible values
* for this field are specified in "params.h", and they are:
*
* PARAM_NAMED: The parameter has a name, i.e. something
* like `$.salary' or `$.foobar'.
* In this case field `paramname' must be a valid Name.
*
* PARAM_NUM: The parameter has only a numeric identifier,
* i.e. something like `$1', `$2' etc.
* The number is contained in the `paramid' field.
*
* PARAM_NEW: Used in PRS2 rule, similar to PARAM_NAMED.
* The `paramname' and `paramid' refer to the "NEW" tuple
* The `pramname' is the attribute name and `paramid'
* is the attribute number.
*
* PARAM_OLD: Same as PARAM_NEW, but in this case we refer to
* the "OLD" tuple.
*
* paramid - numeric identifier for literal-constant parameters ("$1")
* paramname - attribute name for tuple-substitution parameters ("$.foo")
* paramtype - PG_TYPE OID of the parameter's value
* param_tlist - allows for projection in a param node.
* ----------------
*/
typedef struct Param {
NodeTag type;
int paramkind;
AttrNumber paramid;
char *paramname;
Oid paramtype;
List *param_tlist;
} Param;
/* ----------------
* Func
* funcid - PG_FUNCTION OID of the function
* functype - PG_TYPE OID of the function's return value
* funcisindex - the function can be evaluated by scanning an index
* (set during query optimization)
* funcsize - size of return result (cached by executor)
* func_fcache - runtime state while running this function. Where
* we are in the execution of the function if it
* returns more than one value, etc.
* See utils/fcache.h
* func_tlist - projection of functions returning tuples
* func_planlist - result of planning this func, if it's a PQ func
* ----------------
*/
typedef struct Func {
NodeTag type;
Oid funcid;
Oid functype;
bool funcisindex;
int funcsize;
FunctionCachePtr func_fcache;
List *func_tlist;
List *func_planlist;
} Func;
/* ----------------
* Aggreg
* aggname - name of the aggregate
* basetype - base type Oid of the aggregate
* aggtype - type Oid of final result of the aggregate
* query - XXX comment me
* target - XXX comment me
* ----------------
*/
typedef struct Aggreg {
NodeTag type;
char *aggname;
Oid basetype; /* base type of the aggregate */
Oid aggtype; /* type of final result */
Node *target; /* attribute to aggreg on */
int aggno; /* index to ecxt_values */
} Aggreg;
/* ----------------
* Array
* arrayelemtype - base type of the array's elements (homogenous!)
* arrayelemlength - length of that type
* arrayelembyval - can you pass this element by value?
* arrayndim - number of dimensions of the array
* arraylow - base for array indexing
* arrayhigh - limit for array indexing
* arraylen -
* ----------------
*
* memo from mao: the array support we inherited from 3.1 is just
* wrong. when time exists, we should redesign this stuff to get
* around a bunch of unfortunate implementation decisions made there.
*/
typedef struct Array {
NodeTag type;
Oid arrayelemtype;
int arrayelemlength;
bool arrayelembyval;
int arrayndim;
IntArray arraylow;
IntArray arrayhigh;
int arraylen;
} Array;
/* ----------------
* ArrayRef:
* refelemtype - type of the element referenced here
* refelemlength - length of that type
* refelembyval - can you pass this element type by value?
* refupperindexpr - expressions that evaluate to upper array index
* reflowerexpr- the expressions that evaluate to a lower array index
* refexpr - the expression that evaluates to an array
* refassignexpr- the expression that evaluates to the new value
* to be assigned to the array in case of replace.
* ----------------
*/
typedef struct ArrayRef {
NodeTag type;
int refattrlength;
int refelemlength;
Oid refelemtype;
bool refelembyval;
List *refupperindexpr;
List *reflowerindexpr;
Node *refexpr;
Node *refassgnexpr;
} ArrayRef;
#endif /* PRIMNODES_H */

377
src/backend/nodes/print.c Normal file
View File

@ -0,0 +1,377 @@
/*-------------------------------------------------------------------------
*
* print.c--
* various print routines (used mostly for debugging)
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Oct 26, 1994 file creation
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include "postgres.h"
#include "access/printtup.h"
#include "nodes/pg_list.h"
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "parser/parsetree.h"
#include "parser/catalog_utils.h"
#include "access/heapam.h"
#include "utils/lsyscache.h"
#include "nodes/nodes.h"
#include "nodes/plannodes.h"
#include "optimizer/clauses.h"
/*
* print--
* print contents of Node to stdout
*/
void
print(void *obj)
{
char *s;
s = nodeToString(obj);
printf("%s\n", s);
fflush(stdout);
return;
}
/*
* pretty print hack extraordinaire. -ay 10/94
*/
void
pprint(void *obj)
{
char *s;
int i;
char line[80];
int indentLev;
int j;
s = nodeToString(obj);
indentLev = 0;
i = 0;
for(;;) {
for(j=0; j<indentLev*3; j++) {
line[j] = ' ';
}
for( ; j<75 && s[i]!='\0'; i++, j++) {
line[j] = s[i];
switch (line[j]) {
case '}':
if (j != indentLev*3) {
line[j] = '\0';
printf("%s\n",line);
line[indentLev*3] = '\0';
printf("%s}\n",line);
}else {
line[j] = '\0';
printf("%s}\n",line);
}
indentLev--;
j = indentLev*3-1; /* print the line before : and resets */
break;
case ')':
line[j+1] = '\0';
printf("%s\n", line);
j = indentLev*3-1;
break;
case '{':
indentLev++;
/* !!! FALLS THROUGH */
case ':':
if (j != 0) {
line[j] = '\0';
printf("%s\n",line);
/* print the line before : and resets */
for(j=0; j<indentLev*3; j++) {
line[j] = ' ';
}
}
line[j] = s[i];
break;
}
}
line[j] = '\0';
if (s[i]=='\0')
break;
printf("%s\n", line);
}
if (j!=0) {
printf("%s\n", line);
}
fflush(stdout);
return;
}
/*
* print_rt--
* print contents of range table
*/
void
print_rt(List *rtable)
{
List *l;
int i=1;
printf("resno\trelname(refname)\trelid\tinFromCl\n");
printf("-----\t----------------\t-----\t--------\n");
foreach(l, rtable) {
RangeTblEntry *rte = lfirst(l);
printf("%d\t%s(%s)\t%d\t%d\t%s\n",
i,rte->relname,rte->refname,rte->relid,
rte->inFromCl,
(rte->inh?"inh":""));
i++;
}
}
/*
* print_expr--
* print an expression
*/
void
print_expr(Node *expr, List *rtable)
{
if (expr==NULL) {
printf("nil");
return;
}
if (IsA(expr,Var)) {
Var *var = (Var*)expr;
RangeTblEntry *rt;
char *relname, *attname;
switch (var->varno) {
case INNER:
relname = "INNER";
attname = "?";
break;
case OUTER:
relname = "OUTER";
attname = "?";
break;
default:
{
Relation r;
rt = rt_fetch(var->varno, rtable);
relname = rt->relname;
r = heap_openr(relname);
if (rt->refname)
relname = rt->refname; /* table renamed */
attname = getAttrName(r, var->varattno);
heap_close(r);
}
break;
}
printf("%s.%s",relname,attname);
} else if (IsA(expr,Expr)) {
Expr *e = (Expr*)expr;
if (is_opclause(expr)) {
char *opname;
print_expr((Node*)get_leftop(e), rtable);
opname = get_opname(((Oper*)e->oper)->opno);
printf(" %s ", opname);
print_expr((Node*)get_rightop(e), rtable);
} else {
printf("an expr");
}
} else {
printf("not an expr");
}
}
/*
* print_keys -
* temporary here. where is keys list of list??
*/
void
print_keys(List *keys, List *rtable)
{
List *k;
printf("(");
foreach(k, keys) {
Node *var = lfirst((List*)lfirst(k));
print_expr(var, rtable);
if (lnext(k)) printf(", ");
}
printf(")\n");
}
/*
* print_tl --
* print targetlist in a more legible way.
*/
void
print_tl(List *tlist, List *rtable)
{
List *tl;
printf("(\n");
foreach(tl, tlist) {
TargetEntry *tle = lfirst(tl);
printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
if (tle->resdom->reskey!=0) {
printf("(%d):\t", tle->resdom->reskey);
} else {
printf(" :\t");
}
print_expr(tle->expr, rtable);
printf("\n");
}
printf(")\n");
}
/*
* print_slot--
* print out the tuple with the given TupleTableSlot
*/
void
print_slot(TupleTableSlot *slot)
{
if (!slot->val) {
printf("tuple is null.\n");
return;
}
if (!slot->ttc_tupleDescriptor) {
printf("no tuple descriptor.\n");
return;
}
debugtup(slot->val, slot->ttc_tupleDescriptor);
}
char*
plannode_type (Plan* p)
{
switch(nodeTag(p)) {
case T_Plan:
return "PLAN";
break;
case T_Existential:
return "EXISTENTIAL";
break;
case T_Result:
return "RESULT";
break;
case T_Append:
return "APPEND";
break;
case T_Scan:
return "SCAN";
break;
case T_SeqScan:
return "SEQSCAN";
break;
case T_IndexScan:
return "INDEXSCAN";
break;
case T_Join:
return "JOIN";
break;
case T_NestLoop:
return "NESTLOOP";
break;
case T_MergeJoin:
return "MERGEJOIN";
break;
case T_HashJoin:
return "HASHJOIN";
break;
case T_Temp:
return "TEMP";
break;
case T_Material:
return "MATERIAL";
break;
case T_Sort:
return "SORT";
break;
case T_Agg:
return "AGG";
break;
case T_Unique:
return "UNIQUE";
break;
case T_Hash:
return "HASH";
break;
case T_Tee:
return "TEE";
break;
case T_Choose:
return "CHOOSE";
break;
case T_Group:
return "GROUP";
break;
default:
return "UNKNOWN";
break;
}
}
/*
prints the ascii description of the plan nodes
does this recursively by doing a depth-first traversal of the
plan tree. for SeqScan and IndexScan, the name of the table is also
printed out
*/
void
print_plan_recursive (Plan* p, Query *parsetree, int indentLevel, char* label)
{
int i;
char extraInfo[100];
if (!p)
return;
for (i=0;i<indentLevel;i++)
printf(" ");
printf("%s%s :c=%.4f :s=%d :w=%d ",label, plannode_type(p),
p->cost, p->plan_size, p->plan_width);
if (IsA(p,Scan) || IsA(p,SeqScan)) {
RangeTblEntry *rte;
rte = rt_fetch(((Scan*)p)->scanrelid, parsetree->rtable);
strncpy(extraInfo, rte->relname, NAMEDATALEN);
extraInfo[NAMEDATALEN] = '\0';
} else
if (IsA(p,IndexScan)) {
strncpy(extraInfo,
((RangeTblEntry*)(nth(((IndexScan*)p)->scan.scanrelid - 1,
parsetree->rtable)))->relname,
NAMEDATALEN);
extraInfo[NAMEDATALEN] = '\0';
} else
extraInfo[0] = '\0';
if (extraInfo[0] != '\0')
printf(" ( %s )\n", extraInfo);
else
printf("\n");
print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
}
/* print_plan
prints just the plan node types */
void
print_plan (Plan* p, Query* parsetree)
{
print_plan_recursive(p, parsetree, 0, "");
}

270
src/backend/nodes/read.c Normal file
View File

@ -0,0 +1,270 @@
/*-------------------------------------------------------------------------
*
* read.c--
* routines to convert a string (legal ascii representation of node) back
* to nodes
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
* Andrew Yu Nov 2, 1994 file creation
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "postgres.h"
#include "nodes/pg_list.h"
#include "nodes/readfuncs.h"
#include "utils/elog.h"
/*
* stringToNode -
* returns a Node with a given legal ascii representation
*/
void *
stringToNode(char *str)
{
void *retval;
(void) lsptok(str, NULL); /* set the string used in lsptok */
retval = nodeRead(true); /* start reading */
return retval;
}
/*****************************************************************************
*
* the lisp token parser
*
*****************************************************************************/
#define RIGHT_PAREN (1000000 + 1)
#define LEFT_PAREN (1000000 + 2)
#define PLAN_SYM (1000000 + 3)
#define AT_SYMBOL (1000000 + 4)
#define ATOM_TOKEN (1000000 + 5)
/*
* nodeTokenType -
* returns the type of the node token contained in token.
* It returns one of the following valid NodeTags:
* T_Integer, T_Float, T_String
* and some of its own:
* RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN
*
* Assumption: the ascii representation is legal
*/
static NodeTag
nodeTokenType(char *token, int length)
{
NodeTag retval;
/*
* Check if the token is a number (decimal or integer,
* positive or negative
*/
if (isdigit(*token) ||
(length>=2 && *token=='-' && isdigit(*(token+1)) ))
{
/*
* skip the optional '-' (i.e. negative number)
*/
if (*token == '-') {
token++;
}
/*
* See if there is a decimal point
*/
for (; length && *token != '.'; token++, length--);
/*
* if there isn't, token's an int, otherwise it's a float.
*/
retval = (*token != '.') ? T_Integer : T_Float;
}
else if (isalpha(*token))
retval = ATOM_TOKEN;
else if (*token == '(')
retval = LEFT_PAREN;
else if (*token == ')')
retval = RIGHT_PAREN;
else if (*token == '@')
retval = AT_SYMBOL;
else if (*token == '\"')
retval = T_String;
else if (*token == '{')
retval = PLAN_SYM;
return(retval);
}
/*
* Works kinda like strtok, except it doesn't put nulls into string.
*
* Returns the length in length instead. The string can be set without
* returning a token by calling lsptok with length == NULL.
*
*/
char *
lsptok(char *string, int *length)
{
static char *local_str;
char *ret_string;
if (string != NULL) {
local_str = string;
if (length == NULL) {
return(NULL);
}
}
for (; *local_str == ' '
|| *local_str == '\n'
|| *local_str == '\t'; local_str++);
/*
* Now pointing at next token.
*/
ret_string = local_str;
if (*local_str == '\0') return(NULL);
*length = 1;
if (*local_str == '\"') {
for (local_str++; *local_str != '\"'; (*length)++, local_str++);
(*length)++; local_str++;
}else if (*local_str == ')' || *local_str == '(' ||
*local_str == '}' || *local_str == '{') {
local_str++;
}else {
for (; *local_str != ' '
&& *local_str != '\n'
&& *local_str != '\t'
&& *local_str != '{'
&& *local_str != '}'
&& *local_str != '('
&& *local_str != ')'; local_str++, (*length)++);
(*length)--;
}
return(ret_string);
}
/*
* This guy does all the reading.
*
* Secrets: He assumes that lsptok already has the string (see below).
* Any callers should set read_car_only to true.
*/
void *
nodeRead(bool read_car_only)
{
char *token;
NodeTag type;
Node *this_value, *return_value;
int tok_len;
char tmp;
bool make_dotted_pair_cell = false;
token = lsptok(NULL, &tok_len);
if (token == NULL) return(NULL);
type = nodeTokenType(token, tok_len);
switch(type) {
case PLAN_SYM:
this_value = parsePlanString();
token = lsptok(NULL, &tok_len);
if (token[0] != '}') return(NULL);
if (!read_car_only)
make_dotted_pair_cell = true;
else
make_dotted_pair_cell = false;
break;
case LEFT_PAREN:
if (!read_car_only) {
List *l = makeNode(List);
lfirst(l) = nodeRead(false);
lnext(l) = nodeRead(false);
this_value = (Node*)l;
}else {
this_value = nodeRead(false);
}
break;
case RIGHT_PAREN:
this_value = NULL;
break;
case AT_SYMBOL:
break;
case ATOM_TOKEN:
if (!strncmp(token, "nil", 3)) {
this_value = NULL;
/*
* It might be "nil" but it is an atom!
*/
if (read_car_only) {
make_dotted_pair_cell = false;
} else {
make_dotted_pair_cell = true;
}
}else {
tmp = token[tok_len];
token[tok_len] = '\0';
this_value = (Node*)pstrdup(token); /* !attention! not a Node.
use with caution */
token[tok_len] = tmp;
make_dotted_pair_cell = true;
}
break;
case T_Float:
tmp = token[tok_len];
token[tok_len] = '\0';
this_value = (Node*)makeFloat(atof(token));
token[tok_len] = tmp;
make_dotted_pair_cell = true;
break;
case T_Integer:
tmp = token[tok_len];
token[tok_len] = '\0';
this_value = (Node*)makeInteger(atoi(token));
token[tok_len] = tmp;
make_dotted_pair_cell = true;
break;
case T_String:
tmp = token[tok_len - 1];
token[tok_len - 1] = '\0';
token++;
this_value = (Node*)makeString(token); /* !! not strdup'd */
token[tok_len - 2] = tmp;
make_dotted_pair_cell = true;
break;
default:
elog(WARN, "nodeRead: Bad type %d", type);
break;
}
if (make_dotted_pair_cell) {
List *l = makeNode(List);
lfirst(l) = this_value;
if (!read_car_only) {
lnext(l) = nodeRead(false);
}else {
lnext(l) = NULL;
}
return_value = (Node*)l;
}else {
return_value = this_value;
}
return(return_value);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
/*-------------------------------------------------------------------------
*
* readfuncs.h--
* header file for read.c and readfuncs.c. These functions are internal
* to the stringToNode interface and should not be used by anyone else.
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: readfuncs.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef READFUNCS_H
#define READFUNCS_H
/*
* prototypes for functions in read.c (the lisp token parser)
*/
extern char *lsptok(char *string, int *length);
extern void *nodeRead(bool read_car_only);
/*
* prototypes for functions in readfuncs.c
*/
extern Node *parsePlanString();
#endif /* READFUNCS_H */

View File

@ -0,0 +1,279 @@
/*-------------------------------------------------------------------------
*
* relation.h--
* Definitions for internal planner nodes.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: relation.h,v 1.1.1.1 1996/07/09 06:21:33 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RELATION_H
#define RELATION_H
#include "c.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/nodes.h"
/*
* Relid
* List of relation identifiers (indexes into the rangetable).
*/
typedef List *Relid;
/*
* Rel
* Per-base-relation information
*
* Parts of this data structure are specific to various scan and join
* mechanisms. It didn't seem worth creating new node types for them.
*
* relids - List of relation indentifiers
* indexed - true if the relation has secondary indices
* pages - number of pages in the relation
* tuples - number of tuples in the relation
* size - number of tuples in the relation after restrictions clauses
* have been applied
* width - number of bytes per tuple in the relation after the
* appropriate projections have been done
* targetlist - List of TargetList nodes
* pathlist - List of Path nodes, one for each possible method of
* generating the relation
* unorderedpath - a Path node generating this relation whose resulting
* tuples are unordered (this isn't necessarily a
* sequential scan path, e.g., scanning with a hash index
* leaves the tuples unordered)
* cheapestpath - least expensive Path (regardless of final order)
* pruneable - flag to let the planner know whether it can prune the plan
* space of this Rel or not. -- JMH, 11/11/92
*
* * If the relation is a (secondary) index it will have the following
* three fields:
*
* classlist - List of PG_AMOPCLASS OIDs for the index
* indexkeys - List of base-relation attribute numbers that are index keys
* ordering - List of PG_OPERATOR OIDs which order the indexscan result
* relam - the OID of the pg_am of the index
*
* * The presence of the remaining fields depends on the restrictions
* and joins which the relation participates in:
*
* clauseinfo - List of ClauseInfo nodes, containing info about each
* qualification clause in which this relation participates
* joininfo - List of JoinInfo nodes, containing info about each join
* clause in which this relation participates
* innerjoin - List of Path nodes that represent indices that may be used
* as inner paths of nestloop joins
*
* NB. the last element of the arrays classlist, indexkeys and ordering
* is always 0. 2/95 - ay
*/
typedef struct Rel {
NodeTag type;
/* all relations: */
Relid relids;
/* catalog statistics information */
bool indexed;
int pages;
int tuples;
int size;
int width;
/* materialization information */
List *targetlist;
List *pathlist;
struct Path *unorderedpath;
struct Path *cheapestpath;
bool pruneable;
/* used solely by indices: */
Oid *classlist; /* classes of AM operators */
int *indexkeys; /* keys over which we're indexing */
Oid relam; /* OID of the access method (in pg_am) */
Oid indproc;
List *indpred;
/* used by various scans and joins: */
Oid *ordering; /* OID of operators in sort order */
List *clauseinfo; /* restriction clauses */
List *joininfo; /* join clauses */
List *innerjoin;
List *superrels;
} Rel;
extern Var *get_expr(TargetEntry *foo);
typedef struct MergeOrder {
NodeTag type;
Oid join_operator;
Oid left_operator;
Oid right_operator;
Oid left_type;
Oid right_type;
} MergeOrder;
typedef enum OrderType {
MERGE_ORDER, SORTOP_ORDER
} OrderType;
typedef struct PathOrder {
OrderType ordtype;
union {
Oid *sortop;
MergeOrder *merge;
} ord;
} PathOrder;
typedef struct Path {
NodeTag type;
Rel *parent;
Cost path_cost;
NodeTag pathtype;
PathOrder p_ordering;
List *keys;
Cost outerjoincost;
Relid joinid;
List *locclauseinfo;
} Path;
typedef struct IndexPath {
Path path;
List *indexid;
List *indexqual;
} IndexPath;
typedef struct JoinPath {
Path path;
List *pathclauseinfo;
Path *outerjoinpath;
Path *innerjoinpath;
} JoinPath;
typedef struct MergePath {
JoinPath jpath;
List *path_mergeclauses;
List *outersortkeys;
List *innersortkeys;
} MergePath;
typedef struct HashPath {
JoinPath jpath;
List *path_hashclauses;
List *outerhashkeys;
List *innerhashkeys;
} HashPath;
/******
* Keys
******/
typedef struct OrderKey {
NodeTag type;
int attribute_number;
Index array_index;
} OrderKey;
typedef struct JoinKey {
NodeTag type;
Var *outer;
Var *inner;
} JoinKey;
/*******
* clause info
*******/
typedef struct CInfo {
NodeTag type;
Expr *clause; /* should be an OP clause */
Cost selectivity;
bool notclause;
List *indexids;
/* mergesort only */
MergeOrder *mergesortorder;
/* hashjoin only */
Oid hashjoinoperator;
Relid cinfojoinid;
} CInfo;
typedef struct JoinMethod {
NodeTag type;
List *jmkeys;
List *clauses;
} JoinMethod;
typedef struct HInfo {
JoinMethod jmethod;
Oid hashop;
} HInfo;
typedef struct MInfo {
JoinMethod jmethod;
MergeOrder *m_ordering;
} MInfo;
typedef struct JInfo {
NodeTag type;
List *otherrels;
List *jinfoclauseinfo;
bool mergesortable;
bool hashjoinable;
bool inactive;
} JInfo;
typedef struct Iter {
NodeTag type;
Node *iterexpr;
Oid itertype; /* type of the iter expr (use for type
checking) */
} Iter;
/*
** Stream:
** A stream represents a root-to-leaf path in a plan tree (i.e. a tree of
** JoinPaths and Paths). The stream includes pointers to all Path nodes,
** as well as to any clauses that reside above Path nodes. This structure
** is used to make Path nodes and clauses look similar, so that Predicate
** Migration can run.
**
** pathptr -- pointer to the current path node
** cinfo -- if NULL, this stream node referes to the path node.
** Otherwise this is a pointer to the current clause.
** clausetype -- whether cinfo is in locclauseinfo or pathclauseinfo in the
** path node
** upstream -- linked list pointer upwards
** downstream -- ditto, downwards
** groupup -- whether or not this node is in a group with the node upstream
** groupcost -- total cost of the group that node is in
** groupsel -- total selectivity of the group that node is in
*/
typedef struct Stream *StreamPtr;
typedef struct Stream {
NodeTag type;
Path *pathptr;
CInfo *cinfo;
int *clausetype;
struct Stream *upstream;
struct Stream *downstream;
bool groupup;
Cost groupcost;
Cost groupsel;
} Stream;
#endif /* RELATION_H */