mirror of
https://github.com/postgres/postgres.git
synced 2025-05-20 00:03:14 -04:00
Fix UNION/INTERSECT/EXCEPT so that when two inputs being merged have
same data type and same typmod, we show that typmod as the output typmod, rather than generic -1. This responds to several complaints over the past few years about UNIONs unexpectedly dropping length or precision info.
This commit is contained in:
parent
e860e746e1
commit
0ee26100b6
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.345 2006/08/02 01:59:45 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.346 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1793,6 +1793,7 @@ _copySetOperationStmt(SetOperationStmt *from)
|
|||||||
COPY_NODE_FIELD(larg);
|
COPY_NODE_FIELD(larg);
|
||||||
COPY_NODE_FIELD(rarg);
|
COPY_NODE_FIELD(rarg);
|
||||||
COPY_NODE_FIELD(colTypes);
|
COPY_NODE_FIELD(colTypes);
|
||||||
|
COPY_NODE_FIELD(colTypmods);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.279 2006/08/02 01:59:45 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.280 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -743,6 +743,7 @@ _equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
|
|||||||
COMPARE_NODE_FIELD(larg);
|
COMPARE_NODE_FIELD(larg);
|
||||||
COMPARE_NODE_FIELD(rarg);
|
COMPARE_NODE_FIELD(rarg);
|
||||||
COMPARE_NODE_FIELD(colTypes);
|
COMPARE_NODE_FIELD(colTypes);
|
||||||
|
COMPARE_NODE_FIELD(colTypmods);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.280 2006/08/02 01:59:45 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.281 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -1574,6 +1574,7 @@ _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
|
|||||||
WRITE_NODE_FIELD(larg);
|
WRITE_NODE_FIELD(larg);
|
||||||
WRITE_NODE_FIELD(rarg);
|
WRITE_NODE_FIELD(rarg);
|
||||||
WRITE_NODE_FIELD(colTypes);
|
WRITE_NODE_FIELD(colTypes);
|
||||||
|
WRITE_NODE_FIELD(colTypmods);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.193 2006/08/02 01:59:45 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.194 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Path and Plan nodes do not have any readfuncs support, because we
|
* Path and Plan nodes do not have any readfuncs support, because we
|
||||||
@ -245,6 +245,7 @@ _readSetOperationStmt(void)
|
|||||||
READ_NODE_FIELD(larg);
|
READ_NODE_FIELD(larg);
|
||||||
READ_NODE_FIELD(rarg);
|
READ_NODE_FIELD(rarg);
|
||||||
READ_NODE_FIELD(colTypes);
|
READ_NODE_FIELD(colTypes);
|
||||||
|
READ_NODE_FIELD(colTypmods);
|
||||||
|
|
||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.150 2006/08/02 01:59:45 joe Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.151 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -813,6 +813,10 @@ recurse_pushdown_safe(Node *setOp, Query *topquery,
|
|||||||
* Compare tlist's datatypes against the list of set-operation result types.
|
* Compare tlist's datatypes against the list of set-operation result types.
|
||||||
* For any items that are different, mark the appropriate element of
|
* For any items that are different, mark the appropriate element of
|
||||||
* differentTypes[] to show that this column will have type conversions.
|
* differentTypes[] to show that this column will have type conversions.
|
||||||
|
*
|
||||||
|
* We don't have to care about typmods here: the only allowed difference
|
||||||
|
* between set-op input and output typmods is input is a specific typmod
|
||||||
|
* and output is -1, and that does not require a coercion.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
compare_tlist_datatypes(List *tlist, List *colTypes,
|
compare_tlist_datatypes(List *tlist, List *colTypes,
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.39 2006/07/14 14:52:21 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.40 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -716,6 +716,7 @@ is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
|
|||||||
Assert(subquery != NULL);
|
Assert(subquery != NULL);
|
||||||
|
|
||||||
/* Leaf nodes are OK if they match the toplevel column types */
|
/* Leaf nodes are OK if they match the toplevel column types */
|
||||||
|
/* We don't have to compare typmods here */
|
||||||
return tlist_same_datatypes(subquery->targetList, colTypes, true);
|
return tlist_same_datatypes(subquery->targetList, colTypes, true);
|
||||||
}
|
}
|
||||||
else if (IsA(setOp, SetOperationStmt))
|
else if (IsA(setOp, SetOperationStmt))
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.132 2006/04/30 18:30:39 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.133 2006/08/10 02:36:28 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -152,6 +152,10 @@ plan_set_operations(PlannerInfo *root, double tuple_fraction,
|
|||||||
* flag: if >= 0, add a resjunk output column indicating value of flag
|
* flag: if >= 0, add a resjunk output column indicating value of flag
|
||||||
* refnames_tlist: targetlist to take column names from
|
* refnames_tlist: targetlist to take column names from
|
||||||
* *sortClauses: receives list of SortClauses for result plan, if any
|
* *sortClauses: receives list of SortClauses for result plan, if any
|
||||||
|
*
|
||||||
|
* We don't have to care about typmods here: the only allowed difference
|
||||||
|
* between set-op input and output typmods is input is a specific typmod
|
||||||
|
* and output is -1, and that does not require a coercion.
|
||||||
*/
|
*/
|
||||||
static Plan *
|
static Plan *
|
||||||
recurse_set_operations(Node *setOp, PlannerInfo *root,
|
recurse_set_operations(Node *setOp, PlannerInfo *root,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.72 2006/03/05 15:58:32 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.73 2006/08/10 02:36:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -174,6 +174,8 @@ get_sortgrouplist_exprs(List *sortClauses, List *targetList)
|
|||||||
*
|
*
|
||||||
* Resjunk columns are ignored if junkOK is true; otherwise presence of
|
* Resjunk columns are ignored if junkOK is true; otherwise presence of
|
||||||
* a resjunk column will always cause a 'false' result.
|
* a resjunk column will always cause a 'false' result.
|
||||||
|
*
|
||||||
|
* Note: currently no callers care about comparing typmods.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
|
tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.343 2006/08/02 14:14:22 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.344 2006/08/10 02:36:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -131,7 +131,8 @@ static void transformFKConstraints(ParseState *pstate,
|
|||||||
bool skipValidation,
|
bool skipValidation,
|
||||||
bool isAddConstraint);
|
bool isAddConstraint);
|
||||||
static void applyColumnNames(List *dst, List *src);
|
static void applyColumnNames(List *dst, List *src);
|
||||||
static List *getSetColTypes(ParseState *pstate, Node *node);
|
static void getSetColTypes(ParseState *pstate, Node *node,
|
||||||
|
List **colTypes, List **colTypmods);
|
||||||
static void transformLockingClause(Query *qry, LockingClause *lc);
|
static void transformLockingClause(Query *qry, LockingClause *lc);
|
||||||
static void transformConstraintAttrs(List *constraintList);
|
static void transformConstraintAttrs(List *constraintList);
|
||||||
static void transformColumnType(ParseState *pstate, ColumnDef *column);
|
static void transformColumnType(ParseState *pstate, ColumnDef *column);
|
||||||
@ -2312,7 +2313,8 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
|||||||
List *lockingClause;
|
List *lockingClause;
|
||||||
Node *node;
|
Node *node;
|
||||||
ListCell *left_tlist,
|
ListCell *left_tlist,
|
||||||
*dtlist,
|
*lct,
|
||||||
|
*lcm,
|
||||||
*l;
|
*l;
|
||||||
List *targetvars,
|
List *targetvars,
|
||||||
*targetnames,
|
*targetnames,
|
||||||
@ -2395,9 +2397,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
|||||||
targetnames = NIL;
|
targetnames = NIL;
|
||||||
left_tlist = list_head(leftmostQuery->targetList);
|
left_tlist = list_head(leftmostQuery->targetList);
|
||||||
|
|
||||||
foreach(dtlist, sostmt->colTypes)
|
forboth(lct, sostmt->colTypes, lcm, sostmt->colTypmods)
|
||||||
{
|
{
|
||||||
Oid colType = lfirst_oid(dtlist);
|
Oid colType = lfirst_oid(lct);
|
||||||
|
int32 colTypmod = lfirst_int(lcm);
|
||||||
TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
|
TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
|
||||||
char *colName;
|
char *colName;
|
||||||
TargetEntry *tle;
|
TargetEntry *tle;
|
||||||
@ -2408,7 +2411,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
|||||||
expr = (Expr *) makeVar(leftmostRTI,
|
expr = (Expr *) makeVar(leftmostRTI,
|
||||||
lefttle->resno,
|
lefttle->resno,
|
||||||
colType,
|
colType,
|
||||||
-1,
|
colTypmod,
|
||||||
0);
|
0);
|
||||||
tle = makeTargetEntry(expr,
|
tle = makeTargetEntry(expr,
|
||||||
(AttrNumber) pstate->p_next_resno++,
|
(AttrNumber) pstate->p_next_resno++,
|
||||||
@ -2609,8 +2612,12 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
|
|||||||
SetOperationStmt *op = makeNode(SetOperationStmt);
|
SetOperationStmt *op = makeNode(SetOperationStmt);
|
||||||
List *lcoltypes;
|
List *lcoltypes;
|
||||||
List *rcoltypes;
|
List *rcoltypes;
|
||||||
ListCell *l;
|
List *lcoltypmods;
|
||||||
ListCell *r;
|
List *rcoltypmods;
|
||||||
|
ListCell *lct;
|
||||||
|
ListCell *rct;
|
||||||
|
ListCell *lcm;
|
||||||
|
ListCell *rcm;
|
||||||
const char *context;
|
const char *context;
|
||||||
|
|
||||||
context = (stmt->op == SETOP_UNION ? "UNION" :
|
context = (stmt->op == SETOP_UNION ? "UNION" :
|
||||||
@ -2630,24 +2637,43 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
|
|||||||
* Verify that the two children have the same number of non-junk
|
* Verify that the two children have the same number of non-junk
|
||||||
* columns, and determine the types of the merged output columns.
|
* columns, and determine the types of the merged output columns.
|
||||||
*/
|
*/
|
||||||
lcoltypes = getSetColTypes(pstate, op->larg);
|
getSetColTypes(pstate, op->larg, &lcoltypes, &lcoltypmods);
|
||||||
rcoltypes = getSetColTypes(pstate, op->rarg);
|
getSetColTypes(pstate, op->rarg, &rcoltypes, &rcoltypmods);
|
||||||
if (list_length(lcoltypes) != list_length(rcoltypes))
|
if (list_length(lcoltypes) != list_length(rcoltypes))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("each %s query must have the same number of columns",
|
errmsg("each %s query must have the same number of columns",
|
||||||
context)));
|
context)));
|
||||||
|
Assert(list_length(lcoltypes) == list_length(lcoltypmods));
|
||||||
|
Assert(list_length(rcoltypes) == list_length(rcoltypmods));
|
||||||
|
|
||||||
op->colTypes = NIL;
|
op->colTypes = NIL;
|
||||||
forboth(l, lcoltypes, r, rcoltypes)
|
op->colTypmods = NIL;
|
||||||
|
/* don't have a "foreach4", so chase two of the lists by hand */
|
||||||
|
lcm = list_head(lcoltypmods);
|
||||||
|
rcm = list_head(rcoltypmods);
|
||||||
|
forboth(lct, lcoltypes, rct, rcoltypes)
|
||||||
{
|
{
|
||||||
Oid lcoltype = lfirst_oid(l);
|
Oid lcoltype = lfirst_oid(lct);
|
||||||
Oid rcoltype = lfirst_oid(r);
|
Oid rcoltype = lfirst_oid(rct);
|
||||||
|
int32 lcoltypmod = lfirst_int(lcm);
|
||||||
|
int32 rcoltypmod = lfirst_int(rcm);
|
||||||
Oid rescoltype;
|
Oid rescoltype;
|
||||||
|
int32 rescoltypmod;
|
||||||
|
|
||||||
|
/* select common type, same as CASE et al */
|
||||||
rescoltype = select_common_type(list_make2_oid(lcoltype, rcoltype),
|
rescoltype = select_common_type(list_make2_oid(lcoltype, rcoltype),
|
||||||
context);
|
context);
|
||||||
|
/* if same type and same typmod, use typmod; else default */
|
||||||
|
if (lcoltype == rcoltype && lcoltypmod == rcoltypmod)
|
||||||
|
rescoltypmod = lcoltypmod;
|
||||||
|
else
|
||||||
|
rescoltypmod = -1;
|
||||||
op->colTypes = lappend_oid(op->colTypes, rescoltype);
|
op->colTypes = lappend_oid(op->colTypes, rescoltype);
|
||||||
|
op->colTypmods = lappend_int(op->colTypmods, rescoltypmod);
|
||||||
|
|
||||||
|
lcm = lnext(lcm);
|
||||||
|
rcm = lnext(rcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Node *) op;
|
return (Node *) op;
|
||||||
@ -2656,17 +2682,19 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* getSetColTypes
|
* getSetColTypes
|
||||||
* Get output column types of an (already transformed) set-op node
|
* Get output column types/typmods of an (already transformed) set-op node
|
||||||
*/
|
*/
|
||||||
static List *
|
static void
|
||||||
getSetColTypes(ParseState *pstate, Node *node)
|
getSetColTypes(ParseState *pstate, Node *node,
|
||||||
|
List **colTypes, List **colTypmods)
|
||||||
{
|
{
|
||||||
|
*colTypes = NIL;
|
||||||
|
*colTypmods = NIL;
|
||||||
if (IsA(node, RangeTblRef))
|
if (IsA(node, RangeTblRef))
|
||||||
{
|
{
|
||||||
RangeTblRef *rtr = (RangeTblRef *) node;
|
RangeTblRef *rtr = (RangeTblRef *) node;
|
||||||
RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
|
RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
|
||||||
Query *selectQuery = rte->subquery;
|
Query *selectQuery = rte->subquery;
|
||||||
List *result = NIL;
|
|
||||||
ListCell *tl;
|
ListCell *tl;
|
||||||
|
|
||||||
Assert(selectQuery != NULL);
|
Assert(selectQuery != NULL);
|
||||||
@ -2677,9 +2705,11 @@ getSetColTypes(ParseState *pstate, Node *node)
|
|||||||
|
|
||||||
if (tle->resjunk)
|
if (tle->resjunk)
|
||||||
continue;
|
continue;
|
||||||
result = lappend_oid(result, exprType((Node *) tle->expr));
|
*colTypes = lappend_oid(*colTypes,
|
||||||
|
exprType((Node *) tle->expr));
|
||||||
|
*colTypmods = lappend_int(*colTypmods,
|
||||||
|
exprTypmod((Node *) tle->expr));
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
else if (IsA(node, SetOperationStmt))
|
else if (IsA(node, SetOperationStmt))
|
||||||
{
|
{
|
||||||
@ -2687,13 +2717,11 @@ getSetColTypes(ParseState *pstate, Node *node)
|
|||||||
|
|
||||||
/* Result already computed during transformation of node */
|
/* Result already computed during transformation of node */
|
||||||
Assert(op->colTypes != NIL);
|
Assert(op->colTypes != NIL);
|
||||||
return op->colTypes;
|
*colTypes = op->colTypes;
|
||||||
|
*colTypmods = op->colTypmods;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
|
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
|
||||||
return NIL; /* keep compiler quiet */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attach column names from a ColumnDef list to a TargetEntry list */
|
/* Attach column names from a ColumnDef list to a TargetEntry list */
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.347 2006/08/06 03:53:44 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.348 2006/08/10 02:36:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200608051
|
#define CATALOG_VERSION_NO 200608091
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.320 2006/08/02 01:59:47 joe Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.321 2006/08/10 02:36:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -769,7 +769,8 @@ typedef struct SetOperationStmt
|
|||||||
/* Eventually add fields for CORRESPONDING spec here */
|
/* Eventually add fields for CORRESPONDING spec here */
|
||||||
|
|
||||||
/* Fields derived during parse analysis: */
|
/* Fields derived during parse analysis: */
|
||||||
List *colTypes; /* list of OIDs of output column types */
|
List *colTypes; /* OID list of output column type OIDs */
|
||||||
|
List *colTypmods; /* integer list of output column typmods */
|
||||||
} SetOperationStmt;
|
} SetOperationStmt;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user