mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Major planner/optimizer revision: get rid of PathOrder node type,
store all ordering information in pathkeys lists (which are now lists of lists of PathKeyItem nodes, not just lists of lists of vars). This was a big win --- the code is smaller and IMHO more understandable than it was, even though it handles more cases. I believe the node changes will not force an initdb for anyone; planner nodes don't show up in stored rules.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.90 1999/08/09 06:20:23 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.91 1999/08/16 02:17:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1030,10 +1030,6 @@ _copyRelOptInfo(RelOptInfo *from)
|
||||
newnode->indexkeys[len] = 0;
|
||||
}
|
||||
|
||||
newnode->relam = from->relam;
|
||||
newnode->indproc = from->indproc;
|
||||
Node_Copy(from, newnode, indpred);
|
||||
|
||||
if (from->ordering)
|
||||
{
|
||||
for (len = 0; from->ordering[len] != 0; len++)
|
||||
@ -1044,6 +1040,10 @@ _copyRelOptInfo(RelOptInfo *from)
|
||||
newnode->ordering[len] = 0;
|
||||
}
|
||||
|
||||
newnode->relam = from->relam;
|
||||
newnode->indproc = from->indproc;
|
||||
Node_Copy(from, newnode, indpred);
|
||||
|
||||
Node_Copy(from, newnode, restrictinfo);
|
||||
Node_Copy(from, newnode, joininfo);
|
||||
Node_Copy(from, newnode, innerjoin);
|
||||
@ -1061,8 +1061,6 @@ _copyRelOptInfo(RelOptInfo *from)
|
||||
static void
|
||||
CopyPathFields(Path *from, Path *newnode)
|
||||
{
|
||||
newnode->pathtype = from->pathtype;
|
||||
|
||||
/*
|
||||
* Modify the next line, since it causes the copying to cycle (i.e.
|
||||
* the parent points right back here! -- JMH, 7/7/92. Old version:
|
||||
@ -1072,32 +1070,9 @@ CopyPathFields(Path *from, Path *newnode)
|
||||
|
||||
newnode->path_cost = from->path_cost;
|
||||
|
||||
newnode->pathorder = makeNode(PathOrder);
|
||||
newnode->pathorder->ordtype = from->pathorder->ordtype;
|
||||
if (from->pathorder->ordtype == SORTOP_ORDER)
|
||||
{
|
||||
int len,
|
||||
i;
|
||||
Oid *ordering = from->pathorder->ord.sortop;
|
||||
|
||||
if (ordering)
|
||||
{
|
||||
for (len = 0; ordering[len] != 0; len++)
|
||||
;
|
||||
newnode->pathorder->ord.sortop = (Oid *) palloc(sizeof(Oid) * (len + 1));
|
||||
for (i = 0; i < len; i++)
|
||||
newnode->pathorder->ord.sortop[i] = ordering[i];
|
||||
newnode->pathorder->ord.sortop[len] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
Node_Copy(from, newnode, pathorder->ord.merge);
|
||||
newnode->pathtype = from->pathtype;
|
||||
|
||||
Node_Copy(from, newnode, pathkeys);
|
||||
|
||||
newnode->outerjoincost = from->outerjoincost;
|
||||
|
||||
newnode->joinid = listCopy(from->joinid);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
@ -1135,32 +1110,20 @@ _copyIndexPath(IndexPath *from)
|
||||
*/
|
||||
newnode->indexid = listCopy(from->indexid);
|
||||
Node_Copy(from, newnode, indexqual);
|
||||
|
||||
if (from->indexkeys)
|
||||
{
|
||||
int i,
|
||||
len;
|
||||
|
||||
for (len = 0; from->indexkeys[len] != 0; len++)
|
||||
;
|
||||
newnode->indexkeys = (int *) palloc(sizeof(int) * (len + 1));
|
||||
for (i = 0; i < len; i++)
|
||||
newnode->indexkeys[i] = from->indexkeys[i];
|
||||
newnode->indexkeys[len] = 0;
|
||||
}
|
||||
newnode->joinrelids = listCopy(from->joinrelids);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* CopyNestPathFields
|
||||
* CopyJoinPathFields
|
||||
*
|
||||
* This function copies the fields of the NestPath node. It is used by
|
||||
* all the copy functions for classes which inherit from NestPath.
|
||||
* This function copies the fields of the JoinPath node. It is used by
|
||||
* all the copy functions for classes which inherit from JoinPath.
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
CopyNestPathFields(NestPath *from, NestPath *newnode)
|
||||
CopyJoinPathFields(JoinPath *from, JoinPath *newnode)
|
||||
{
|
||||
Node_Copy(from, newnode, pathinfo);
|
||||
Node_Copy(from, newnode, outerjoinpath);
|
||||
@ -1181,7 +1144,7 @@ _copyNestPath(NestPath *from)
|
||||
* ----------------
|
||||
*/
|
||||
CopyPathFields((Path *) from, (Path *) newnode);
|
||||
CopyNestPathFields(from, newnode);
|
||||
CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@ -1200,7 +1163,7 @@ _copyMergePath(MergePath *from)
|
||||
* ----------------
|
||||
*/
|
||||
CopyPathFields((Path *) from, (Path *) newnode);
|
||||
CopyNestPathFields((NestPath *) from, (NestPath *) newnode);
|
||||
CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
|
||||
|
||||
/* ----------------
|
||||
* copy the remainder of the node
|
||||
@ -1227,76 +1190,32 @@ _copyHashPath(HashPath *from)
|
||||
* ----------------
|
||||
*/
|
||||
CopyPathFields((Path *) from, (Path *) newnode);
|
||||
CopyNestPathFields((NestPath *) from, (NestPath *) newnode);
|
||||
CopyJoinPathFields((JoinPath *) from, (JoinPath *) newnode);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
Node_Copy(from, newnode, path_hashclauses);
|
||||
Node_Copy(from, newnode, outerhashkeys);
|
||||
Node_Copy(from, newnode, innerhashkeys);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyOrderKey
|
||||
* _copyPathKeyItem
|
||||
* ----------------
|
||||
*/
|
||||
static OrderKey *
|
||||
_copyOrderKey(OrderKey *from)
|
||||
static PathKeyItem *
|
||||
_copyPathKeyItem(PathKeyItem *from)
|
||||
{
|
||||
OrderKey *newnode = makeNode(OrderKey);
|
||||
PathKeyItem *newnode = makeNode(PathKeyItem);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
newnode->attribute_number = from->attribute_number;
|
||||
newnode->array_index = from->array_index;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------
|
||||
* _copyJoinKey
|
||||
* ----------------
|
||||
*/
|
||||
static JoinKey *
|
||||
_copyJoinKey(JoinKey *from)
|
||||
{
|
||||
JoinKey *newnode = makeNode(JoinKey);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
Node_Copy(from, newnode, outer);
|
||||
Node_Copy(from, newnode, inner);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyMergeOrder
|
||||
* ----------------
|
||||
*/
|
||||
static MergeOrder *
|
||||
_copyMergeOrder(MergeOrder *from)
|
||||
{
|
||||
MergeOrder *newnode = makeNode(MergeOrder);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
newnode->join_operator = from->join_operator;
|
||||
newnode->left_operator = from->left_operator;
|
||||
newnode->right_operator = from->right_operator;
|
||||
newnode->left_type = from->left_type;
|
||||
newnode->right_type = from->right_type;
|
||||
Node_Copy(from, newnode, key);
|
||||
newnode->sortop = from->sortop;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@ -1315,83 +1234,16 @@ _copyRestrictInfo(RestrictInfo *from)
|
||||
* ----------------
|
||||
*/
|
||||
Node_Copy(from, newnode, clause);
|
||||
|
||||
newnode->selectivity = from->selectivity;
|
||||
|
||||
Node_Copy(from, newnode, indexids);
|
||||
Node_Copy(from, newnode, mergejoinorder);
|
||||
Node_Copy(from, newnode, subclauseindices);
|
||||
newnode->mergejoinoperator = from->mergejoinoperator;
|
||||
newnode->left_sortop = from->left_sortop;
|
||||
newnode->right_sortop = from->right_sortop;
|
||||
newnode->hashjoinoperator = from->hashjoinoperator;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* CopyJoinMethodFields
|
||||
*
|
||||
* This function copies the fields of the JoinMethod node. It is used by
|
||||
* all the copy functions for classes which inherit from JoinMethod.
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
CopyJoinMethodFields(JoinMethod *from, JoinMethod *newnode)
|
||||
{
|
||||
Node_Copy(from, newnode, jmkeys);
|
||||
Node_Copy(from, newnode, clauses);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyJoinMethod
|
||||
* ----------------
|
||||
*/
|
||||
static JoinMethod *
|
||||
_copyJoinMethod(JoinMethod *from)
|
||||
{
|
||||
JoinMethod *newnode = makeNode(JoinMethod);
|
||||
|
||||
CopyJoinMethodFields(from, newnode);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyHashInfo
|
||||
* ----------------
|
||||
*/
|
||||
static HashInfo *
|
||||
_copyHashInfo(HashInfo *from)
|
||||
{
|
||||
HashInfo *newnode = makeNode(HashInfo);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
|
||||
newnode->hashop = from->hashop;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyMergeInfo
|
||||
* ----------------
|
||||
*/
|
||||
static MergeInfo *
|
||||
_copyMergeInfo(MergeInfo *from)
|
||||
{
|
||||
MergeInfo *newnode = makeNode(MergeInfo);
|
||||
|
||||
/* ----------------
|
||||
* copy remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
CopyJoinMethodFields((JoinMethod *) from, (JoinMethod *) newnode);
|
||||
Node_Copy(from, newnode, m_ordering);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _copyJoinInfo
|
||||
* ----------------
|
||||
@ -1408,9 +1260,6 @@ _copyJoinInfo(JoinInfo *from)
|
||||
newnode->unjoined_relids = listCopy(from->unjoined_relids);
|
||||
Node_Copy(from, newnode, jinfo_restrictinfo);
|
||||
|
||||
newnode->mergejoinable = from->mergejoinable;
|
||||
newnode->hashjoinable = from->hashjoinable;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
@ -1756,27 +1605,12 @@ copyObject(void *from)
|
||||
case T_HashPath:
|
||||
retval = _copyHashPath(from);
|
||||
break;
|
||||
case T_OrderKey:
|
||||
retval = _copyOrderKey(from);
|
||||
break;
|
||||
case T_JoinKey:
|
||||
retval = _copyJoinKey(from);
|
||||
break;
|
||||
case T_MergeOrder:
|
||||
retval = _copyMergeOrder(from);
|
||||
case T_PathKeyItem:
|
||||
retval = _copyPathKeyItem(from);
|
||||
break;
|
||||
case T_RestrictInfo:
|
||||
retval = _copyRestrictInfo(from);
|
||||
break;
|
||||
case T_JoinMethod:
|
||||
retval = _copyJoinMethod(from);
|
||||
break;
|
||||
case T_HashInfo:
|
||||
retval = _copyHashInfo(from);
|
||||
break;
|
||||
case T_MergeInfo:
|
||||
retval = _copyMergeInfo(from);
|
||||
break;
|
||||
case T_JoinInfo:
|
||||
retval = _copyJoinInfo(from);
|
||||
break;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.46 1999/08/09 06:20:24 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.47 1999/08/16 02:17:41 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -264,15 +264,15 @@ _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
|
||||
/* We treat RelOptInfos as equal if they refer to the same base rels
|
||||
* joined in the same order. Is this sufficient?
|
||||
*/
|
||||
return equal(a->relids, b->relids);
|
||||
return equali(a->relids, b->relids);
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalJoinMethod(JoinMethod *a, JoinMethod *b)
|
||||
_equalPathKeyItem(PathKeyItem *a, PathKeyItem *b)
|
||||
{
|
||||
if (!equal(a->jmkeys, b->jmkeys))
|
||||
if (a->sortop != b->sortop)
|
||||
return false;
|
||||
if (!equal(a->clauses, b->clauses))
|
||||
if (!equal(a->key, b->key))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -282,48 +282,13 @@ _equalPath(Path *a, Path *b)
|
||||
{
|
||||
if (a->pathtype != b->pathtype)
|
||||
return false;
|
||||
if (a->parent != b->parent) /* should this use equal() ? */
|
||||
if (!equal(a->parent, b->parent))
|
||||
return false;
|
||||
/* do not check path_cost, since it may not be set yet, and being
|
||||
* a float there are roundoff error issues anyway...
|
||||
*/
|
||||
|
||||
/* XXX this should probably be in an _equalPathOrder function... */
|
||||
if (a->pathorder->ordtype != b->pathorder->ordtype)
|
||||
return false;
|
||||
if (a->pathorder->ordtype == SORTOP_ORDER)
|
||||
{
|
||||
if (a->pathorder->ord.sortop == NULL ||
|
||||
b->pathorder->ord.sortop == NULL)
|
||||
{
|
||||
if (a->pathorder->ord.sortop != b->pathorder->ord.sortop)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (a->pathorder->ord.sortop[i] != 0)
|
||||
{
|
||||
if (a->pathorder->ord.sortop[i] != b->pathorder->ord.sortop[i])
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
if (b->pathorder->ord.sortop[i] != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!equal(a->pathorder->ord.merge, b->pathorder->ord.merge))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!equal(a->pathkeys, b->pathkeys))
|
||||
return false;
|
||||
/* do not check outerjoincost either */
|
||||
if (!equali(a->joinid, b->joinid))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -336,12 +301,13 @@ _equalIndexPath(IndexPath *a, IndexPath *b)
|
||||
return false;
|
||||
if (!equal(a->indexqual, b->indexqual))
|
||||
return false;
|
||||
/* We do not need to check indexkeys */
|
||||
if (!equali(a->joinrelids, b->joinrelids))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalNestPath(NestPath *a, NestPath *b)
|
||||
_equalJoinPath(JoinPath *a, JoinPath *b)
|
||||
{
|
||||
if (!_equalPath((Path *) a, (Path *) b))
|
||||
return false;
|
||||
@ -354,10 +320,18 @@ _equalNestPath(NestPath *a, NestPath *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalNestPath(NestPath *a, NestPath *b)
|
||||
{
|
||||
if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalMergePath(MergePath *a, MergePath *b)
|
||||
{
|
||||
if (!_equalNestPath((NestPath *) a, (NestPath *) b))
|
||||
if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
|
||||
return false;
|
||||
if (!equal(a->path_mergeclauses, b->path_mergeclauses))
|
||||
return false;
|
||||
@ -371,50 +345,10 @@ _equalMergePath(MergePath *a, MergePath *b)
|
||||
static bool
|
||||
_equalHashPath(HashPath *a, HashPath *b)
|
||||
{
|
||||
if (!_equalNestPath((NestPath *) a, (NestPath *) b))
|
||||
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)
|
||||
{
|
||||
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->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
|
||||
_equalHashInfo(HashInfo *a, HashInfo *b)
|
||||
{
|
||||
if (!_equalJoinMethod((JoinMethod *) a, (JoinMethod *) b))
|
||||
return false;
|
||||
if (a->hashop != b->hashop)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -457,31 +391,33 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalJoinInfo(JoinInfo *a, JoinInfo *b)
|
||||
{
|
||||
if (!equal(a->unjoined_relids, b->unjoined_relids))
|
||||
return false;
|
||||
if (!equal(a->jinfo_restrictinfo, b->jinfo_restrictinfo))
|
||||
return false;
|
||||
if (a->mergejoinable != b->mergejoinable)
|
||||
return false;
|
||||
if (a->hashjoinable != b->hashjoinable)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
|
||||
{
|
||||
if (!equal(a->clause, b->clause))
|
||||
return false;
|
||||
/* do not check selectivity because of roundoff error worries */
|
||||
if (!equal(a->mergejoinorder, b->mergejoinorder))
|
||||
if (!equal(a->subclauseindices, b->subclauseindices))
|
||||
return false;
|
||||
if (a->mergejoinoperator != b->mergejoinoperator)
|
||||
return false;
|
||||
if (a->left_sortop != b->left_sortop)
|
||||
return false;
|
||||
if (a->right_sortop != b->right_sortop)
|
||||
return false;
|
||||
if (a->hashjoinoperator != b->hashjoinoperator)
|
||||
return false;
|
||||
return equal(a->indexids, b->indexids);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalJoinInfo(JoinInfo *a, JoinInfo *b)
|
||||
{
|
||||
if (!equali(a->unjoined_relids, b->unjoined_relids))
|
||||
return false;
|
||||
if (!equal(a->jinfo_restrictinfo, b->jinfo_restrictinfo))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -778,8 +714,8 @@ equal(void *a, void *b)
|
||||
case T_RelOptInfo:
|
||||
retval = _equalRelOptInfo(a, b);
|
||||
break;
|
||||
case T_JoinMethod:
|
||||
retval = _equalJoinMethod(a, b);
|
||||
case T_PathKeyItem:
|
||||
retval = _equalPathKeyItem(a, b);
|
||||
break;
|
||||
case T_Path:
|
||||
retval = _equalPath(a, b);
|
||||
@ -796,15 +732,6 @@ equal(void *a, void *b)
|
||||
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_HashInfo:
|
||||
retval = _equalHashInfo(a, b);
|
||||
break;
|
||||
case T_IndexScan:
|
||||
retval = _equalIndexScan(a, b);
|
||||
break;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.24 1999/07/27 03:51:08 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.25 1999/08/16 02:17:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -706,6 +706,9 @@ _freeRelOptInfo(RelOptInfo *node)
|
||||
|
||||
freeObject(node->targetlist);
|
||||
freeObject(node->pathlist);
|
||||
/* is this right? cheapestpath will typically be a pointer into
|
||||
* pathlist, won't it?
|
||||
*/
|
||||
freeObject(node->cheapestpath);
|
||||
|
||||
if (node->classlist)
|
||||
@ -714,11 +717,11 @@ _freeRelOptInfo(RelOptInfo *node)
|
||||
if (node->indexkeys)
|
||||
pfree(node->indexkeys);
|
||||
|
||||
freeObject(node->indpred);
|
||||
|
||||
if (node->ordering)
|
||||
pfree(node->ordering);
|
||||
|
||||
freeObject(node->indpred);
|
||||
|
||||
freeObject(node->restrictinfo);
|
||||
freeObject(node->joininfo);
|
||||
freeObject(node->innerjoin);
|
||||
@ -736,20 +739,9 @@ _freeRelOptInfo(RelOptInfo *node)
|
||||
static void
|
||||
FreePathFields(Path *node)
|
||||
{
|
||||
if (node->pathorder->ordtype == SORTOP_ORDER)
|
||||
{
|
||||
if (node->pathorder->ord.sortop)
|
||||
pfree(node->pathorder->ord.sortop);
|
||||
}
|
||||
else
|
||||
freeObject(node->pathorder->ord.merge);
|
||||
|
||||
pfree(node->pathorder); /* is it an object, but we don't have
|
||||
* separate free for it */
|
||||
/* we do NOT free the parent; it doesn't belong to the Path */
|
||||
|
||||
freeObject(node->pathkeys);
|
||||
|
||||
freeList(node->joinid);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
@ -783,22 +775,20 @@ _freeIndexPath(IndexPath *node)
|
||||
*/
|
||||
freeList(node->indexid);
|
||||
freeObject(node->indexqual);
|
||||
|
||||
if (node->indexkeys)
|
||||
pfree(node->indexkeys);
|
||||
freeList(node->joinrelids);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* FreeNestPathFields
|
||||
* FreeJoinPathFields
|
||||
*
|
||||
* This function frees the fields of the NestPath node. It is used by
|
||||
* all the free functions for classes which inherit node NestPath.
|
||||
* This function frees the fields of the JoinPath node. It is used by
|
||||
* all the free functions for classes which inherit node JoinPath.
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
FreeNestPathFields(NestPath *node)
|
||||
FreeJoinPathFields(JoinPath *node)
|
||||
{
|
||||
freeObject(node->pathinfo);
|
||||
freeObject(node->outerjoinpath);
|
||||
@ -817,7 +807,7 @@ _freeNestPath(NestPath *node)
|
||||
* ----------------
|
||||
*/
|
||||
FreePathFields((Path *) node);
|
||||
FreeNestPathFields(node);
|
||||
FreeJoinPathFields((JoinPath *) node);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
@ -834,7 +824,7 @@ _freeMergePath(MergePath *node)
|
||||
* ----------------
|
||||
*/
|
||||
FreePathFields((Path *) node);
|
||||
FreeNestPathFields((NestPath *) node);
|
||||
FreeJoinPathFields((JoinPath *) node);
|
||||
|
||||
/* ----------------
|
||||
* free the remainder of the node
|
||||
@ -859,60 +849,33 @@ _freeHashPath(HashPath *node)
|
||||
* ----------------
|
||||
*/
|
||||
FreePathFields((Path *) node);
|
||||
FreeNestPathFields((NestPath *) node);
|
||||
FreeJoinPathFields((JoinPath *) node);
|
||||
|
||||
/* ----------------
|
||||
* free remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
freeObject(node->path_hashclauses);
|
||||
freeObject(node->outerhashkeys);
|
||||
freeObject(node->innerhashkeys);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeOrderKey
|
||||
* _freePathKeyItem
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeOrderKey(OrderKey *node)
|
||||
{
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------
|
||||
* _freeJoinKey
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeJoinKey(JoinKey *node)
|
||||
_freePathKeyItem(PathKeyItem *node)
|
||||
{
|
||||
/* ----------------
|
||||
* free remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
freeObject(node->outer);
|
||||
freeObject(node->inner);
|
||||
freeObject(node->key);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeMergeOrder
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeMergeOrder(MergeOrder *node)
|
||||
{
|
||||
/* ----------------
|
||||
* free remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeRestrictInfo
|
||||
@ -926,68 +889,10 @@ _freeRestrictInfo(RestrictInfo *node)
|
||||
* ----------------
|
||||
*/
|
||||
freeObject(node->clause);
|
||||
freeObject(node->indexids);
|
||||
freeObject(node->mergejoinorder);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* FreeJoinMethodFields
|
||||
*
|
||||
* This function frees the fields of the JoinMethod node. It is used by
|
||||
* all the free functions for classes which inherit node JoinMethod.
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
FreeJoinMethodFields(JoinMethod *node)
|
||||
{
|
||||
freeObject(node->jmkeys);
|
||||
freeObject(node->clauses);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeJoinMethod
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeJoinMethod(JoinMethod *node)
|
||||
{
|
||||
FreeJoinMethodFields(node);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeHInfo
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeHashInfo(HashInfo *node)
|
||||
{
|
||||
/* ----------------
|
||||
* free remainder of node
|
||||
* ----------------
|
||||
/* this is certainly wrong? index RelOptInfos don't belong to
|
||||
* RestrictInfo...
|
||||
*/
|
||||
FreeJoinMethodFields((JoinMethod *) node);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _freeMInfo
|
||||
* ----------------
|
||||
*/
|
||||
static void
|
||||
_freeMergeInfo(MergeInfo *node)
|
||||
{
|
||||
/* ----------------
|
||||
* free remainder of node
|
||||
* ----------------
|
||||
*/
|
||||
FreeJoinMethodFields((JoinMethod *) node);
|
||||
freeObject(node->m_ordering);
|
||||
freeObject(node->subclauseindices);
|
||||
|
||||
pfree(node);
|
||||
}
|
||||
@ -1279,27 +1184,12 @@ freeObject(void *node)
|
||||
case T_HashPath:
|
||||
_freeHashPath(node);
|
||||
break;
|
||||
case T_OrderKey:
|
||||
_freeOrderKey(node);
|
||||
break;
|
||||
case T_JoinKey:
|
||||
_freeJoinKey(node);
|
||||
break;
|
||||
case T_MergeOrder:
|
||||
_freeMergeOrder(node);
|
||||
case T_PathKeyItem:
|
||||
_freePathKeyItem(node);
|
||||
break;
|
||||
case T_RestrictInfo:
|
||||
_freeRestrictInfo(node);
|
||||
break;
|
||||
case T_JoinMethod:
|
||||
_freeJoinMethod(node);
|
||||
break;
|
||||
case T_HashInfo:
|
||||
_freeHashInfo(node);
|
||||
break;
|
||||
case T_MergeInfo:
|
||||
_freeMergeInfo(node);
|
||||
break;
|
||||
case T_JoinInfo:
|
||||
_freeJoinInfo(node);
|
||||
break;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.26 1999/08/14 19:29:35 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.27 1999/08/16 02:17:42 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* XXX a few of the following functions are duplicated to handle
|
||||
@ -447,6 +447,31 @@ intLispRemove(int elem, List *list)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ltruncate
|
||||
* Truncate a list to n elements.
|
||||
* Does nothing if n >= length(list).
|
||||
* NB: the list is modified in-place!
|
||||
*/
|
||||
List *
|
||||
ltruncate(int n, List *list)
|
||||
{
|
||||
List *ptr;
|
||||
|
||||
if (n <= 0)
|
||||
return NIL; /* truncate to zero length */
|
||||
|
||||
foreach(ptr, list)
|
||||
{
|
||||
if (--n == 0)
|
||||
{
|
||||
lnext(ptr) = NIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* set_difference
|
||||
*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.10 1999/07/17 20:17:07 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/nodes.c,v 1.11 1999/08/16 02:17:42 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* Andrew Yu Oct 20, 1994 file creation
|
||||
@ -32,7 +32,7 @@ newNode(Size size, NodeTag tag)
|
||||
{
|
||||
Node *newNode;
|
||||
|
||||
Assert(size >= 4); /* need the tag, at least */
|
||||
Assert(size >= sizeof(Node)); /* need the tag, at least */
|
||||
|
||||
newNode = (Node *) palloc(size);
|
||||
MemSet((char *) newNode, 0, size);
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: outfuncs.c,v 1.92 1999/08/09 06:20:24 momjian Exp $
|
||||
* $Id: outfuncs.c,v 1.93 1999/08/16 02:17:42 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every (plan) node in POSTGRES has an associated "out" routine which
|
||||
@ -880,35 +880,6 @@ _outRowMark(StringInfo str, RowMark *node)
|
||||
appendStringInfo(str, " ROWMARK :rti %u :info %u", node->rti, node->info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Path is a subclass of Node.
|
||||
*/
|
||||
static void
|
||||
_outPathOrder(StringInfo str, PathOrder *node)
|
||||
{
|
||||
appendStringInfo(str, " PATHORDER :ordtype %d ",
|
||||
node->ordtype);
|
||||
if (node->ordtype == SORTOP_ORDER)
|
||||
{
|
||||
int i;
|
||||
|
||||
appendStringInfo(str, " :sortop ");
|
||||
if (node->ord.sortop == NULL)
|
||||
appendStringInfo(str, "<>");
|
||||
else
|
||||
{
|
||||
for (i = 0; node->ord.sortop[i] != 0; i++)
|
||||
appendStringInfo(str, " %d ", node->ord.sortop[i]);
|
||||
appendStringInfo(str, " %d ", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(str, " :merge ");
|
||||
_outNode(str, node->ord.merge);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Path is a subclass of Node.
|
||||
*/
|
||||
@ -919,9 +890,6 @@ _outPath(StringInfo str, Path *node)
|
||||
node->pathtype,
|
||||
node->path_cost);
|
||||
_outNode(str, node->pathkeys);
|
||||
|
||||
appendStringInfo(str, " :pathorder ");
|
||||
_outNode(str, node->pathorder);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -936,14 +904,14 @@ _outIndexPath(StringInfo str, IndexPath *node)
|
||||
node->path.path_cost);
|
||||
_outNode(str, node->path.pathkeys);
|
||||
|
||||
appendStringInfo(str, " :pathorder ");
|
||||
_outNode(str, node->path.pathorder);
|
||||
|
||||
appendStringInfo(str, " :indexid ");
|
||||
_outIntList(str, node->indexid);
|
||||
|
||||
appendStringInfo(str, " :indexqual ");
|
||||
_outNode(str, node->indexqual);
|
||||
|
||||
appendStringInfo(str, " :joinrelids ");
|
||||
_outIntList(str, node->joinrelids);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -958,9 +926,6 @@ _outNestPath(StringInfo str, NestPath *node)
|
||||
node->path.path_cost);
|
||||
_outNode(str, node->path.pathkeys);
|
||||
|
||||
appendStringInfo(str, " :pathorder ");
|
||||
_outNode(str, node->path.pathorder);
|
||||
|
||||
appendStringInfo(str, " :pathinfo ");
|
||||
_outNode(str, node->pathinfo);
|
||||
|
||||
@ -970,11 +935,9 @@ _outNestPath(StringInfo str, NestPath *node)
|
||||
*/
|
||||
|
||||
appendStringInfo(str,
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x :outjoincost %f :joinid ",
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x ",
|
||||
(int) node->outerjoinpath,
|
||||
(int) node->innerjoinpath,
|
||||
node->path.outerjoincost);
|
||||
_outIntList(str, node->path.joinid);
|
||||
(int) node->innerjoinpath);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -989,9 +952,6 @@ _outMergePath(StringInfo str, MergePath *node)
|
||||
node->jpath.path.path_cost);
|
||||
_outNode(str, node->jpath.path.pathkeys);
|
||||
|
||||
appendStringInfo(str, " :pathorder ");
|
||||
_outNode(str, node->jpath.path.pathorder);
|
||||
|
||||
appendStringInfo(str, " :pathinfo ");
|
||||
_outNode(str, node->jpath.pathinfo);
|
||||
|
||||
@ -1001,11 +961,9 @@ _outMergePath(StringInfo str, MergePath *node)
|
||||
*/
|
||||
|
||||
appendStringInfo(str,
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x :outerjoincost %f :joinid ",
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x ",
|
||||
(int) node->jpath.outerjoinpath,
|
||||
(int) node->jpath.innerjoinpath,
|
||||
(int) node->jpath.path.outerjoincost);
|
||||
_outIntList(str, node->jpath.path.joinid);
|
||||
(int) node->jpath.innerjoinpath);
|
||||
|
||||
appendStringInfo(str, " :path_mergeclauses ");
|
||||
_outNode(str, node->path_mergeclauses);
|
||||
@ -1029,9 +987,6 @@ _outHashPath(StringInfo str, HashPath *node)
|
||||
node->jpath.path.path_cost);
|
||||
_outNode(str, node->jpath.path.pathkeys);
|
||||
|
||||
appendStringInfo(str, " :pathorder ");
|
||||
_outNode(str, node->jpath.path.pathorder);
|
||||
|
||||
appendStringInfo(str, " :pathinfo ");
|
||||
_outNode(str, node->jpath.pathinfo);
|
||||
|
||||
@ -1041,64 +996,23 @@ _outHashPath(StringInfo str, HashPath *node)
|
||||
*/
|
||||
|
||||
appendStringInfo(str,
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x :outerjoincost %f :joinid ",
|
||||
" :outerjoinpath @ 0x%x :innerjoinpath @ 0x%x ",
|
||||
(int) node->jpath.outerjoinpath,
|
||||
(int) node->jpath.innerjoinpath,
|
||||
node->jpath.path.outerjoincost);
|
||||
_outIntList(str, node->jpath.path.joinid);
|
||||
(int) node->jpath.innerjoinpath);
|
||||
|
||||
appendStringInfo(str, " :path_hashclauses ");
|
||||
_outNode(str, node->path_hashclauses);
|
||||
|
||||
appendStringInfo(str, " :outerhashkeys ");
|
||||
_outNode(str, node->outerhashkeys);
|
||||
|
||||
appendStringInfo(str, " :innerhashkeys ");
|
||||
_outNode(str, node->innerhashkeys);
|
||||
}
|
||||
|
||||
/*
|
||||
* OrderKey is a subclass of Node.
|
||||
* PathKeyItem is a subclass of Node.
|
||||
*/
|
||||
static void
|
||||
_outOrderKey(StringInfo str, OrderKey *node)
|
||||
_outPathKeyItem(StringInfo str, PathKeyItem *node)
|
||||
{
|
||||
appendStringInfo(str,
|
||||
" ORDERKEY :attribute_number %d :array_index %d ",
|
||||
node->attribute_number,
|
||||
node->array_index);
|
||||
}
|
||||
|
||||
/*
|
||||
* JoinKey is a subclass of Node.
|
||||
*/
|
||||
static void
|
||||
_outJoinKey(StringInfo str, JoinKey *node)
|
||||
{
|
||||
appendStringInfo(str, " JOINKEY :outer ");
|
||||
_outNode(str, node->outer);
|
||||
|
||||
appendStringInfo(str, " :inner ");
|
||||
_outNode(str, node->inner);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* MergeOrder is a subclass of Node.
|
||||
*/
|
||||
static void
|
||||
_outMergeOrder(StringInfo str, MergeOrder *node)
|
||||
{
|
||||
appendStringInfo(str,
|
||||
" MERGEORDER :join_operator %u :left_operator %u :right_operator %u ",
|
||||
node->join_operator,
|
||||
node->left_operator,
|
||||
node->right_operator);
|
||||
|
||||
appendStringInfo(str,
|
||||
" :left_type %u :right_type %u ",
|
||||
node->left_type,
|
||||
node->right_type);
|
||||
appendStringInfo(str, " PATHKEYITEM :sortop %u :key ",
|
||||
node->sortop);
|
||||
_outNode(str, node->key);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1111,41 +1025,14 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node)
|
||||
_outNode(str, node->clause);
|
||||
|
||||
appendStringInfo(str,
|
||||
" :selectivity %f :indexids ",
|
||||
" :selectivity %f :subclauseindices ",
|
||||
node->selectivity);
|
||||
_outNode(str, node->indexids);
|
||||
|
||||
appendStringInfo(str, " :mergejoinorder ");
|
||||
_outNode(str, node->mergejoinorder);
|
||||
_outNode(str, node->subclauseindices);
|
||||
|
||||
appendStringInfo(str, " :mergejoinoperator %u ", node->mergejoinoperator);
|
||||
appendStringInfo(str, " :left_sortop %u ", node->left_sortop);
|
||||
appendStringInfo(str, " :right_sortop %u ", node->right_sortop);
|
||||
appendStringInfo(str, " :hashjoinoperator %u ", node->hashjoinoperator);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* JoinMethod is a subclass of Node.
|
||||
*/
|
||||
static void
|
||||
_outJoinMethod(StringInfo str, JoinMethod *node)
|
||||
{
|
||||
appendStringInfo(str, " JOINMETHOD :jmkeys ");
|
||||
_outNode(str, node->jmkeys);
|
||||
|
||||
appendStringInfo(str, " :clauses ");
|
||||
_outNode(str, node->clauses);
|
||||
}
|
||||
|
||||
/*
|
||||
* HashInfo is a subclass of JoinMethod.
|
||||
*/
|
||||
static void
|
||||
_outHashInfo(StringInfo str, HashInfo *node)
|
||||
{
|
||||
appendStringInfo(str, " HASHINFO :hashop %u :jmkeys ", node->hashop);
|
||||
_outNode(str, node->jmethod.jmkeys);
|
||||
|
||||
appendStringInfo(str, " :clauses ");
|
||||
_outNode(str, node->jmethod.clauses);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1159,10 +1046,6 @@ _outJoinInfo(StringInfo str, JoinInfo *node)
|
||||
|
||||
appendStringInfo(str, " :jinfo_restrictinfo ");
|
||||
_outNode(str, node->jinfo_restrictinfo);
|
||||
|
||||
appendStringInfo(str, " :mergejoinable %s :hashjoinable %s ",
|
||||
node->mergejoinable ? "true" : "false",
|
||||
node->hashjoinable ? "true" : "false");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1541,9 +1424,6 @@ _outNode(StringInfo str, void *obj)
|
||||
case T_RowMark:
|
||||
_outRowMark(str, obj);
|
||||
break;
|
||||
case T_PathOrder:
|
||||
_outPathOrder(str, obj);
|
||||
break;
|
||||
case T_Path:
|
||||
_outPath(str, obj);
|
||||
break;
|
||||
@ -1559,24 +1439,12 @@ _outNode(StringInfo str, void *obj)
|
||||
case T_HashPath:
|
||||
_outHashPath(str, obj);
|
||||
break;
|
||||
case T_OrderKey:
|
||||
_outOrderKey(str, obj);
|
||||
break;
|
||||
case T_JoinKey:
|
||||
_outJoinKey(str, obj);
|
||||
break;
|
||||
case T_MergeOrder:
|
||||
_outMergeOrder(str, obj);
|
||||
case T_PathKeyItem:
|
||||
_outPathKeyItem(str, obj);
|
||||
break;
|
||||
case T_RestrictInfo:
|
||||
_outRestrictInfo(str, obj);
|
||||
break;
|
||||
case T_JoinMethod:
|
||||
_outJoinMethod(str, obj);
|
||||
break;
|
||||
case T_HashInfo:
|
||||
_outHashInfo(str, obj);
|
||||
break;
|
||||
case T_JoinInfo:
|
||||
_outJoinInfo(str, obj);
|
||||
break;
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.31 1999/07/17 20:17:08 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.32 1999/08/16 02:17:43 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -204,7 +204,7 @@ print_expr(Node *expr, List *rtable)
|
||||
|
||||
/*
|
||||
* print_pathkeys -
|
||||
* pathkeys list of list of Var's
|
||||
* pathkeys list of list of PathKeyItems
|
||||
*/
|
||||
void
|
||||
print_pathkeys(List *pathkeys, List *rtable)
|
||||
@ -220,9 +220,9 @@ print_pathkeys(List *pathkeys, List *rtable)
|
||||
printf("(");
|
||||
foreach(k, pathkey)
|
||||
{
|
||||
Node *var = lfirst(k);
|
||||
PathKeyItem *item = lfirst(k);
|
||||
|
||||
print_expr(var, rtable);
|
||||
print_expr(item->key, rtable);
|
||||
if (lnext(k))
|
||||
printf(", ");
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.71 1999/08/09 06:20:24 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.72 1999/08/16 02:17:43 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Most of the read functions for plan nodes are tested. (In fact, they
|
||||
@ -1413,55 +1413,6 @@ _readRowMark()
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readPathOrder
|
||||
*
|
||||
* PathOrder is part of Path and it's subclasses.
|
||||
* ----------------
|
||||
*/
|
||||
static PathOrder *
|
||||
_readPathOrder()
|
||||
{
|
||||
PathOrder *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(PathOrder);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :ordtype */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->ordtype = atol(token);
|
||||
|
||||
if (local_node->ordtype == SORTOP_ORDER)
|
||||
{
|
||||
token = lsptok(NULL, &length); /* get :sortop */
|
||||
|
||||
if (length == 0)
|
||||
local_node->ord.sortop = NULL;
|
||||
else
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
local_node->ord.sortop = palloc(sizeof(Oid) * (INDEX_MAX_KEYS + 1));
|
||||
|
||||
do
|
||||
{
|
||||
i++;
|
||||
Assert(i <= INDEX_MAX_KEYS);
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->ord.sortop[i] = strtoul(token, NULL, 10);
|
||||
} while (local_node->ord.sortop[i] != 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token = lsptok(NULL, &length); /* get :merge */
|
||||
local_node->ord.merge = nodeRead(true); /* now read it */
|
||||
}
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readPath
|
||||
*
|
||||
@ -1485,9 +1436,6 @@ _readPath()
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->path_cost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathorder */
|
||||
local_node->pathorder = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathkeys */
|
||||
local_node->pathkeys = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1517,9 +1465,6 @@ _readIndexPath()
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->path.path_cost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathorder */
|
||||
local_node->path.pathorder = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathkeys */
|
||||
local_node->path.pathkeys = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1529,6 +1474,9 @@ _readIndexPath()
|
||||
token = lsptok(NULL, &length); /* get :indexqual */
|
||||
local_node->indexqual = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :joinrelids */
|
||||
local_node->joinrelids = toIntList(nodeRead(true));
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
@ -1545,7 +1493,6 @@ _readNestPath()
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
|
||||
local_node = makeNode(NestPath);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathtype */
|
||||
@ -1556,9 +1503,6 @@ _readNestPath()
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->path.path_cost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathorder */
|
||||
local_node->path.pathorder = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathkeys */
|
||||
local_node->path.pathkeys = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1585,14 +1529,6 @@ _readNestPath()
|
||||
|
||||
local_node->innerjoinpath = NULL;
|
||||
|
||||
token = lsptok(NULL, &length); /* get :outerjoincost */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->path.outerjoincost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :joinid */
|
||||
local_node->path.joinid = toIntList(nodeRead(true)); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
@ -1621,9 +1557,6 @@ _readMergePath()
|
||||
|
||||
local_node->jpath.path.path_cost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathorder */
|
||||
local_node->jpath.path.pathorder = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathkeys */
|
||||
local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1650,14 +1583,6 @@ _readMergePath()
|
||||
|
||||
local_node->jpath.innerjoinpath = NULL;
|
||||
|
||||
token = lsptok(NULL, &length); /* get :outerjoincost */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->jpath.path.outerjoincost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :joinid */
|
||||
local_node->jpath.path.joinid = toIntList(nodeRead(true)); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :path_mergeclauses */
|
||||
local_node->path_mergeclauses = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1695,9 +1620,6 @@ _readHashPath()
|
||||
|
||||
local_node->jpath.path.path_cost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathorder */
|
||||
local_node->jpath.path.pathorder = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :pathkeys */
|
||||
local_node->jpath.path.pathkeys = nodeRead(true); /* now read it */
|
||||
|
||||
@ -1724,116 +1646,34 @@ _readHashPath()
|
||||
|
||||
local_node->jpath.innerjoinpath = NULL;
|
||||
|
||||
token = lsptok(NULL, &length); /* get :outerjoincost */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->jpath.path.outerjoincost = (Cost) atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :joinid */
|
||||
local_node->jpath.path.joinid = toIntList(nodeRead(true)); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :path_hashclauses */
|
||||
local_node->path_hashclauses = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :outerhashkeys */
|
||||
local_node->outerhashkeys = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :innerhashkeys */
|
||||
local_node->innerhashkeys = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readOrderKey
|
||||
* _readPathKeyItem
|
||||
*
|
||||
* OrderKey is a subclass of Node.
|
||||
* PathKeyItem is a subclass of Node.
|
||||
* ----------------
|
||||
*/
|
||||
static OrderKey *
|
||||
_readOrderKey()
|
||||
static PathKeyItem *
|
||||
_readPathKeyItem()
|
||||
{
|
||||
OrderKey *local_node;
|
||||
PathKeyItem *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(OrderKey);
|
||||
local_node = makeNode(PathKeyItem);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :attribute_number */
|
||||
token = lsptok(NULL, &length); /* get :sortop */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->attribute_number = atoi(token);
|
||||
local_node->sortop = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :array_index */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->array_index = strtoul(token, NULL, 10);
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readJoinKey
|
||||
*
|
||||
* JoinKey is a subclass of Node.
|
||||
* ----------------
|
||||
*/
|
||||
static JoinKey *
|
||||
_readJoinKey()
|
||||
{
|
||||
JoinKey *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(JoinKey);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :outer */
|
||||
local_node->outer = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :inner */
|
||||
local_node->inner = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readMergeOrder
|
||||
*
|
||||
* MergeOrder is a subclass of Node.
|
||||
* ----------------
|
||||
*/
|
||||
static MergeOrder *
|
||||
_readMergeOrder()
|
||||
{
|
||||
MergeOrder *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(MergeOrder);
|
||||
token = lsptok(NULL, &length); /* get :join_operator */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->join_operator = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :left_operator */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->left_operator = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :right_operator */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->right_operator = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :left_type */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->left_type = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :right_type */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->right_type = atol(token);
|
||||
token = lsptok(NULL, &length); /* get :key */
|
||||
local_node->key = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
@ -1858,76 +1698,30 @@ _readRestrictInfo()
|
||||
|
||||
token = lsptok(NULL, &length); /* get :selectivity */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->selectivity = atof(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :indexids */
|
||||
local_node->indexids = nodeRead(true); /* now read it */
|
||||
token = lsptok(NULL, &length); /* get :subclauseindices */
|
||||
local_node->subclauseindices = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :mergejoinorder */
|
||||
local_node->mergejoinorder = (MergeOrder *) nodeRead(true);
|
||||
token = lsptok(NULL, &length); /* get :mergejoinoperator */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->mergejoinoperator = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :left_sortop */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->left_sortop = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :right_sortop */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
local_node->right_sortop = atol(token);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :hashjoinoperator */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->hashjoinoperator = atol(token);
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readJoinMethod
|
||||
*
|
||||
* JoinMethod is a subclass of Node.
|
||||
* ----------------
|
||||
*/
|
||||
static JoinMethod *
|
||||
_readJoinMethod()
|
||||
{
|
||||
JoinMethod *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(JoinMethod);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :jmkeys */
|
||||
local_node->jmkeys = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :clauses */
|
||||
local_node->clauses = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readHashInfo
|
||||
*
|
||||
* HashInfo is a subclass of JoinMethod.
|
||||
* ----------------
|
||||
*/
|
||||
static HashInfo *
|
||||
_readHashInfo()
|
||||
{
|
||||
HashInfo *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(HashInfo);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :hashop */
|
||||
token = lsptok(NULL, &length); /* now read it */
|
||||
|
||||
local_node->hashop = strtoul(token, NULL, 10);
|
||||
|
||||
token = lsptok(NULL, &length); /* get :jmkeys */
|
||||
local_node->jmethod.jmkeys = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :clauses */
|
||||
local_node->jmethod.clauses = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readJoinInfo()
|
||||
*
|
||||
@ -1949,20 +1743,6 @@ _readJoinInfo()
|
||||
token = lsptok(NULL, &length); /* get :jinfo_restrictinfo */
|
||||
local_node->jinfo_restrictinfo = nodeRead(true); /* now read it */
|
||||
|
||||
token = lsptok(NULL, &length); /* get :mergejoinable */
|
||||
|
||||
if (!strncmp(token, "true", 4))
|
||||
local_node->mergejoinable = true;
|
||||
else
|
||||
local_node->mergejoinable = false;
|
||||
|
||||
token = lsptok(NULL, &length); /* get :hashjoinable */
|
||||
|
||||
if (!strncmp(token, "true", 4))
|
||||
local_node->hashjoinable = true;
|
||||
else
|
||||
local_node->hashjoinable = false;
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
@ -2065,8 +1845,6 @@ parsePlanString(void)
|
||||
return_value = _readTargetEntry();
|
||||
else if (!strncmp(token, "RTE", length))
|
||||
return_value = _readRangeTblEntry();
|
||||
else if (!strncmp(token, "PATHORDER", length))
|
||||
return_value = _readPathOrder();
|
||||
else if (!strncmp(token, "PATH", length))
|
||||
return_value = _readPath();
|
||||
else if (!strncmp(token, "INDEXPATH", length))
|
||||
@ -2077,20 +1855,12 @@ parsePlanString(void)
|
||||
return_value = _readMergePath();
|
||||
else if (!strncmp(token, "HASHPATH", length))
|
||||
return_value = _readHashPath();
|
||||
else if (!strncmp(token, "ORDERKEY", length))
|
||||
return_value = _readOrderKey();
|
||||
else if (!strncmp(token, "JOINKEY", length))
|
||||
return_value = _readJoinKey();
|
||||
else if (!strncmp(token, "MERGEORDER", length))
|
||||
return_value = _readMergeOrder();
|
||||
else if (!strncmp(token, "RETRICTINFO", length))
|
||||
else if (!strncmp(token, "PATHKEYITEM", length))
|
||||
return_value = _readPathKeyItem();
|
||||
else if (!strncmp(token, "RESTRICTINFO", length))
|
||||
return_value = _readRestrictInfo();
|
||||
else if (!strncmp(token, "JOINMETHOD", length))
|
||||
return_value = _readJoinMethod();
|
||||
else if (!strncmp(token, "JOININFO", length))
|
||||
return_value = _readJoinInfo();
|
||||
else if (!strncmp(token, "HASHINFO", length))
|
||||
return_value = _readHashInfo();
|
||||
else if (!strncmp(token, "ITER", length))
|
||||
return_value = _readIter();
|
||||
else if (!strncmp(token, "QUERY", length))
|
||||
|
Reference in New Issue
Block a user