mirror of
https://github.com/postgres/postgres.git
synced 2025-08-22 21:53:06 +03:00
Get rid of long-since-vestigial Iter node type, in favor of adding a
returns-set boolean field in Func and Oper nodes. This allows cleaner, more reliable tests for expressions returning sets in the planner and parser. For example, a WHERE clause returning a set is now detected and complained of in the parser, not only at runtime.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.183 2002/05/12 20:10:02 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.184 2002/05/12 23:43:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -764,6 +764,7 @@ _copyOper(Oper *from)
|
||||
newnode->opno = from->opno;
|
||||
newnode->opid = from->opid;
|
||||
newnode->opresulttype = from->opresulttype;
|
||||
newnode->opretset = from->opretset;
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->op_fcache = NULL;
|
||||
|
||||
@@ -852,7 +853,8 @@ _copyFunc(Func *from)
|
||||
* copy remainder of node
|
||||
*/
|
||||
newnode->funcid = from->funcid;
|
||||
newnode->functype = from->functype;
|
||||
newnode->funcresulttype = from->funcresulttype;
|
||||
newnode->funcretset = from->funcretset;
|
||||
/* Do not copy the run-time state, if any */
|
||||
newnode->func_fcache = NULL;
|
||||
|
||||
@@ -1433,17 +1435,6 @@ _copyJoinInfo(JoinInfo *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static Iter *
|
||||
_copyIter(Iter *from)
|
||||
{
|
||||
Iter *newnode = makeNode(Iter);
|
||||
|
||||
Node_Copy(from, newnode, iterexpr);
|
||||
newnode->itertype = from->itertype;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static Stream *
|
||||
_copyStream(Stream *from)
|
||||
{
|
||||
@@ -2729,9 +2720,6 @@ copyObject(void *from)
|
||||
case T_ArrayRef:
|
||||
retval = _copyArrayRef(from);
|
||||
break;
|
||||
case T_Iter:
|
||||
retval = _copyIter(from);
|
||||
break;
|
||||
case T_FieldSelect:
|
||||
retval = _copyFieldSelect(from);
|
||||
break;
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.131 2002/05/12 20:10:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.132 2002/05/12 23:43:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -130,6 +130,8 @@ _equalOper(Oper *a, Oper *b)
|
||||
return false;
|
||||
if (a->opresulttype != b->opresulttype)
|
||||
return false;
|
||||
if (a->opretset != b->opretset)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* We do not examine opid or op_fcache, since these are logically
|
||||
@@ -139,7 +141,8 @@ _equalOper(Oper *a, Oper *b)
|
||||
* (Besides, op_fcache is executor state, which we don't check --- see
|
||||
* notes at head of file.)
|
||||
*
|
||||
* It's probably not really necessary to check opresulttype either...
|
||||
* It's probably not really necessary to check opresulttype or opretset,
|
||||
* either...
|
||||
*/
|
||||
|
||||
return true;
|
||||
@@ -210,7 +213,9 @@ _equalFunc(Func *a, Func *b)
|
||||
{
|
||||
if (a->funcid != b->funcid)
|
||||
return false;
|
||||
if (a->functype != b->functype)
|
||||
if (a->funcresulttype != b->funcresulttype)
|
||||
return false;
|
||||
if (a->funcretset != b->funcretset)
|
||||
return false;
|
||||
/* Note we do not look at func_fcache; see notes for _equalOper */
|
||||
|
||||
@@ -538,12 +543,6 @@ _equalJoinInfo(JoinInfo *a, JoinInfo *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalIter(Iter *a, Iter *b)
|
||||
{
|
||||
return equal(a->iterexpr, b->iterexpr);
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalStream(Stream *a, Stream *b)
|
||||
{
|
||||
@@ -1884,9 +1883,6 @@ equal(void *a, void *b)
|
||||
case T_ArrayRef:
|
||||
retval = _equalArrayRef(a, b);
|
||||
break;
|
||||
case T_Iter:
|
||||
retval = _equalIter(a, b);
|
||||
break;
|
||||
case T_RelabelType:
|
||||
retval = _equalRelabelType(a, b);
|
||||
break;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.31 2002/04/16 23:08:10 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.32 2002/05/12 23:43:02 tgl Exp $
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
@@ -56,13 +56,15 @@ makeSimpleA_Expr(int oper, const char *name,
|
||||
Oper *
|
||||
makeOper(Oid opno,
|
||||
Oid opid,
|
||||
Oid opresulttype)
|
||||
Oid opresulttype,
|
||||
bool opretset)
|
||||
{
|
||||
Oper *oper = makeNode(Oper);
|
||||
|
||||
oper->opno = opno;
|
||||
oper->opid = opid;
|
||||
oper->opresulttype = opresulttype;
|
||||
oper->opretset = opretset;
|
||||
oper->op_fcache = NULL;
|
||||
return oper;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.158 2002/05/12 20:10:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.159 2002/05/12 23:43:02 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every (plan) node in POSTGRES has an associated "out" routine which
|
||||
@@ -850,9 +850,11 @@ _outArrayRef(StringInfo str, ArrayRef *node)
|
||||
static void
|
||||
_outFunc(StringInfo str, Func *node)
|
||||
{
|
||||
appendStringInfo(str, " FUNC :funcid %u :functype %u ",
|
||||
appendStringInfo(str,
|
||||
" FUNC :funcid %u :funcresulttype %u :funcretset %s ",
|
||||
node->funcid,
|
||||
node->functype);
|
||||
node->funcresulttype,
|
||||
booltostr(node->funcretset));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -862,10 +864,11 @@ static void
|
||||
_outOper(StringInfo str, Oper *node)
|
||||
{
|
||||
appendStringInfo(str,
|
||||
" OPER :opno %u :opid %u :opresulttype %u ",
|
||||
" OPER :opno %u :opid %u :opresulttype %u :opretset %s ",
|
||||
node->opno,
|
||||
node->opid,
|
||||
node->opresulttype);
|
||||
node->opresulttype,
|
||||
booltostr(node->opretset));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1246,13 +1249,6 @@ _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_outIter(StringInfo str, Iter *node)
|
||||
{
|
||||
appendStringInfo(str, " ITER :iterexpr ");
|
||||
_outNode(str, node->iterexpr);
|
||||
}
|
||||
|
||||
static void
|
||||
_outStream(StringInfo str, Stream *node)
|
||||
{
|
||||
@@ -1731,9 +1727,6 @@ _outNode(StringInfo str, void *obj)
|
||||
case T_JoinInfo:
|
||||
_outJoinInfo(str, obj);
|
||||
break;
|
||||
case T_Iter:
|
||||
_outIter(str, obj);
|
||||
break;
|
||||
case T_Stream:
|
||||
_outStream(str, obj);
|
||||
break;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.121 2002/05/12 20:10:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.122 2002/05/12 23:43:02 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Most of the read functions for plan nodes are tested. (In fact, they
|
||||
@@ -1083,9 +1083,13 @@ _readFunc(void)
|
||||
token = pg_strtok(&length); /* now read it */
|
||||
local_node->funcid = atooid(token);
|
||||
|
||||
token = pg_strtok(&length); /* get :functype */
|
||||
token = pg_strtok(&length); /* get :funcresulttype */
|
||||
token = pg_strtok(&length); /* now read it */
|
||||
local_node->functype = atooid(token);
|
||||
local_node->funcresulttype = atooid(token);
|
||||
|
||||
token = pg_strtok(&length); /* get :funcretset */
|
||||
token = pg_strtok(&length); /* now read it */
|
||||
local_node->funcretset = strtobool(token);
|
||||
|
||||
local_node->func_fcache = NULL;
|
||||
|
||||
@@ -1119,6 +1123,10 @@ _readOper(void)
|
||||
token = pg_strtok(&length); /* now read it */
|
||||
local_node->opresulttype = atooid(token);
|
||||
|
||||
token = pg_strtok(&length); /* get :opretset */
|
||||
token = pg_strtok(&length); /* now read it */
|
||||
local_node->opretset = strtobool(token);
|
||||
|
||||
local_node->op_fcache = NULL;
|
||||
|
||||
return local_node;
|
||||
@@ -1991,26 +1999,6 @@ _readJoinInfo(void)
|
||||
return local_node;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* _readIter()
|
||||
*
|
||||
* ----------------
|
||||
*/
|
||||
static Iter *
|
||||
_readIter(void)
|
||||
{
|
||||
Iter *local_node;
|
||||
char *token;
|
||||
int length;
|
||||
|
||||
local_node = makeNode(Iter);
|
||||
|
||||
token = pg_strtok(&length); /* eat :iterexpr */
|
||||
local_node->iterexpr = nodeRead(true); /* now read it */
|
||||
|
||||
return local_node;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------
|
||||
* parsePlanString
|
||||
@@ -2124,8 +2112,6 @@ parsePlanString(void)
|
||||
return_value = _readRestrictInfo();
|
||||
else if (length == 8 && strncmp(token, "JOININFO", length) == 0)
|
||||
return_value = _readJoinInfo();
|
||||
else if (length == 4 && strncmp(token, "ITER", length) == 0)
|
||||
return_value = _readIter();
|
||||
else if (length == 5 && strncmp(token, "QUERY", length) == 0)
|
||||
return_value = _readQuery();
|
||||
else if (length == 6 && strncmp(token, "NOTIFY", length) == 0)
|
||||
|
Reference in New Issue
Block a user