Commit a2794623 authored by Tom Lane's avatar Tom Lane

Extend the parser location infrastructure to include a location field in

most node types used in expression trees (both before and after parse
analysis).  This allows us to place an error cursor in many situations
where we formerly could not, because the information wasn't available
beyond the very first level of parse analysis.  There's a fair amount
of work still to be done to persuade individual ereport() calls to actually
include an error location, but this gets the initdb-forcing part of the
work out of the way; and the situation is already markedly better than
before for complaints about unimplementable implicit casts, such as
CASE and UNION constructs with incompatible alternative data types.
Per my proposal of a few days ago.
parent 6734182c
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.338 2008/08/25 22:42:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.339 2008/08/28 23:09:45 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -2121,7 +2121,8 @@ cookDefault(ParseState *pstate, ...@@ -2121,7 +2121,8 @@ cookDefault(ParseState *pstate,
expr = coerce_to_target_type(pstate, expr, type_id, expr = coerce_to_target_type(pstate, expr, type_id,
atttypid, atttypmod, atttypid, atttypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (expr == NULL) if (expr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Copyright (c) 2002-2008, PostgreSQL Global Development Group * Copyright (c) 2002-2008, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.90 2008/08/25 22:42:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.91 2008/08/28 23:09:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -353,7 +353,8 @@ EvaluateParams(PreparedStatement *pstmt, List *params, ...@@ -353,7 +353,8 @@ EvaluateParams(PreparedStatement *pstmt, List *params,
expr = coerce_to_target_type(pstate, expr, given_type_id, expr = coerce_to_target_type(pstate, expr, given_type_id,
expected_type_id, -1, expected_type_id, -1,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (expr == NULL) if (expr == NULL)
ereport(ERROR, ereport(ERROR,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.263 2008/08/25 22:42:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.264 2008/08/28 23:09:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3649,7 +3649,8 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, ...@@ -3649,7 +3649,8 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
typeOid, typeOid,
typmod, typmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (defval == NULL) /* should not happen */ if (defval == NULL) /* should not happen */
elog(ERROR, "failed to coerce base type to domain"); elog(ERROR, "failed to coerce base type to domain");
} }
...@@ -5509,7 +5510,8 @@ ATPrepAlterColumnType(List **wqueue, ...@@ -5509,7 +5510,8 @@ ATPrepAlterColumnType(List **wqueue,
transform, exprType(transform), transform, exprType(transform),
targettype, targettypmod, targettype, targettypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (transform == NULL) if (transform == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
...@@ -5607,7 +5609,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -5607,7 +5609,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
defaultexpr, exprType(defaultexpr), defaultexpr, exprType(defaultexpr),
targettype, targettypmod, targettype, targettypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (defaultexpr == NULL) if (defaultexpr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.122 2008/07/31 16:27:16 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.123 2008/08/28 23:09:45 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -2135,6 +2135,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, ...@@ -2135,6 +2135,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
domVal = makeNode(CoerceToDomainValue); domVal = makeNode(CoerceToDomainValue);
domVal->typeId = baseTypeOid; domVal->typeId = baseTypeOid;
domVal->typeMod = typMod; domVal->typeMod = typMod;
domVal->location = -1; /* will be set when/if used */
pstate->p_value_substitute = (Node *) domVal; pstate->p_value_substitute = (Node *) domVal;
......
...@@ -15,7 +15,7 @@ ...@@ -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.401 2008/08/22 00:16:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.402 2008/08/28 23:09:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -58,6 +58,10 @@ ...@@ -58,6 +58,10 @@
memcpy(newnode->fldname, from->fldname, _size); \ memcpy(newnode->fldname, from->fldname, _size); \
} while (0) } while (0)
/* Copy a parse location field (for Copy, this is same as scalar case) */
#define COPY_LOCATION_FIELD(fldname) \
(newnode->fldname = from->fldname)
/* **************************************************************** /* ****************************************************************
* plannodes.h copy functions * plannodes.h copy functions
...@@ -761,6 +765,7 @@ _copyVar(Var *from) ...@@ -761,6 +765,7 @@ _copyVar(Var *from)
COPY_SCALAR_FIELD(varlevelsup); COPY_SCALAR_FIELD(varlevelsup);
COPY_SCALAR_FIELD(varnoold); COPY_SCALAR_FIELD(varnoold);
COPY_SCALAR_FIELD(varoattno); COPY_SCALAR_FIELD(varoattno);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -797,6 +802,7 @@ _copyConst(Const *from) ...@@ -797,6 +802,7 @@ _copyConst(Const *from)
COPY_SCALAR_FIELD(constisnull); COPY_SCALAR_FIELD(constisnull);
COPY_SCALAR_FIELD(constbyval); COPY_SCALAR_FIELD(constbyval);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -813,6 +819,7 @@ _copyParam(Param *from) ...@@ -813,6 +819,7 @@ _copyParam(Param *from)
COPY_SCALAR_FIELD(paramid); COPY_SCALAR_FIELD(paramid);
COPY_SCALAR_FIELD(paramtype); COPY_SCALAR_FIELD(paramtype);
COPY_SCALAR_FIELD(paramtypmod); COPY_SCALAR_FIELD(paramtypmod);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -831,6 +838,7 @@ _copyAggref(Aggref *from) ...@@ -831,6 +838,7 @@ _copyAggref(Aggref *from)
COPY_SCALAR_FIELD(agglevelsup); COPY_SCALAR_FIELD(agglevelsup);
COPY_SCALAR_FIELD(aggstar); COPY_SCALAR_FIELD(aggstar);
COPY_SCALAR_FIELD(aggdistinct); COPY_SCALAR_FIELD(aggdistinct);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -867,6 +875,7 @@ _copyFuncExpr(FuncExpr *from) ...@@ -867,6 +875,7 @@ _copyFuncExpr(FuncExpr *from)
COPY_SCALAR_FIELD(funcretset); COPY_SCALAR_FIELD(funcretset);
COPY_SCALAR_FIELD(funcformat); COPY_SCALAR_FIELD(funcformat);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -884,6 +893,7 @@ _copyOpExpr(OpExpr *from) ...@@ -884,6 +893,7 @@ _copyOpExpr(OpExpr *from)
COPY_SCALAR_FIELD(opresulttype); COPY_SCALAR_FIELD(opresulttype);
COPY_SCALAR_FIELD(opretset); COPY_SCALAR_FIELD(opretset);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -901,6 +911,7 @@ _copyDistinctExpr(DistinctExpr *from) ...@@ -901,6 +911,7 @@ _copyDistinctExpr(DistinctExpr *from)
COPY_SCALAR_FIELD(opresulttype); COPY_SCALAR_FIELD(opresulttype);
COPY_SCALAR_FIELD(opretset); COPY_SCALAR_FIELD(opretset);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -917,6 +928,7 @@ _copyScalarArrayOpExpr(ScalarArrayOpExpr *from) ...@@ -917,6 +928,7 @@ _copyScalarArrayOpExpr(ScalarArrayOpExpr *from)
COPY_SCALAR_FIELD(opfuncid); COPY_SCALAR_FIELD(opfuncid);
COPY_SCALAR_FIELD(useOr); COPY_SCALAR_FIELD(useOr);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -931,6 +943,7 @@ _copyBoolExpr(BoolExpr *from) ...@@ -931,6 +943,7 @@ _copyBoolExpr(BoolExpr *from)
COPY_SCALAR_FIELD(boolop); COPY_SCALAR_FIELD(boolop);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -947,6 +960,7 @@ _copySubLink(SubLink *from) ...@@ -947,6 +960,7 @@ _copySubLink(SubLink *from)
COPY_NODE_FIELD(testexpr); COPY_NODE_FIELD(testexpr);
COPY_NODE_FIELD(operName); COPY_NODE_FIELD(operName);
COPY_NODE_FIELD(subselect); COPY_NODE_FIELD(subselect);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1032,6 +1046,7 @@ _copyRelabelType(RelabelType *from) ...@@ -1032,6 +1046,7 @@ _copyRelabelType(RelabelType *from)
COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttype);
COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resulttypmod);
COPY_SCALAR_FIELD(relabelformat); COPY_SCALAR_FIELD(relabelformat);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1047,6 +1062,7 @@ _copyCoerceViaIO(CoerceViaIO *from) ...@@ -1047,6 +1062,7 @@ _copyCoerceViaIO(CoerceViaIO *from)
COPY_NODE_FIELD(arg); COPY_NODE_FIELD(arg);
COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttype);
COPY_SCALAR_FIELD(coerceformat); COPY_SCALAR_FIELD(coerceformat);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1065,6 +1081,7 @@ _copyArrayCoerceExpr(ArrayCoerceExpr *from) ...@@ -1065,6 +1081,7 @@ _copyArrayCoerceExpr(ArrayCoerceExpr *from)
COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resulttypmod);
COPY_SCALAR_FIELD(isExplicit); COPY_SCALAR_FIELD(isExplicit);
COPY_SCALAR_FIELD(coerceformat); COPY_SCALAR_FIELD(coerceformat);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1080,6 +1097,7 @@ _copyConvertRowtypeExpr(ConvertRowtypeExpr *from) ...@@ -1080,6 +1097,7 @@ _copyConvertRowtypeExpr(ConvertRowtypeExpr *from)
COPY_NODE_FIELD(arg); COPY_NODE_FIELD(arg);
COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttype);
COPY_SCALAR_FIELD(convertformat); COPY_SCALAR_FIELD(convertformat);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1096,6 +1114,7 @@ _copyCaseExpr(CaseExpr *from) ...@@ -1096,6 +1114,7 @@ _copyCaseExpr(CaseExpr *from)
COPY_NODE_FIELD(arg); COPY_NODE_FIELD(arg);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_NODE_FIELD(defresult); COPY_NODE_FIELD(defresult);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1110,6 +1129,7 @@ _copyCaseWhen(CaseWhen *from) ...@@ -1110,6 +1129,7 @@ _copyCaseWhen(CaseWhen *from)
COPY_NODE_FIELD(expr); COPY_NODE_FIELD(expr);
COPY_NODE_FIELD(result); COPY_NODE_FIELD(result);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1140,6 +1160,7 @@ _copyArrayExpr(ArrayExpr *from) ...@@ -1140,6 +1160,7 @@ _copyArrayExpr(ArrayExpr *from)
COPY_SCALAR_FIELD(element_typeid); COPY_SCALAR_FIELD(element_typeid);
COPY_NODE_FIELD(elements); COPY_NODE_FIELD(elements);
COPY_SCALAR_FIELD(multidims); COPY_SCALAR_FIELD(multidims);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1155,6 +1176,7 @@ _copyRowExpr(RowExpr *from) ...@@ -1155,6 +1176,7 @@ _copyRowExpr(RowExpr *from)
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(row_typeid); COPY_SCALAR_FIELD(row_typeid);
COPY_SCALAR_FIELD(row_format); COPY_SCALAR_FIELD(row_format);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1186,6 +1208,7 @@ _copyCoalesceExpr(CoalesceExpr *from) ...@@ -1186,6 +1208,7 @@ _copyCoalesceExpr(CoalesceExpr *from)
COPY_SCALAR_FIELD(coalescetype); COPY_SCALAR_FIELD(coalescetype);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1201,6 +1224,7 @@ _copyMinMaxExpr(MinMaxExpr *from) ...@@ -1201,6 +1224,7 @@ _copyMinMaxExpr(MinMaxExpr *from)
COPY_SCALAR_FIELD(minmaxtype); COPY_SCALAR_FIELD(minmaxtype);
COPY_SCALAR_FIELD(op); COPY_SCALAR_FIELD(op);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1221,6 +1245,7 @@ _copyXmlExpr(XmlExpr *from) ...@@ -1221,6 +1245,7 @@ _copyXmlExpr(XmlExpr *from)
COPY_SCALAR_FIELD(xmloption); COPY_SCALAR_FIELD(xmloption);
COPY_SCALAR_FIELD(type); COPY_SCALAR_FIELD(type);
COPY_SCALAR_FIELD(typmod); COPY_SCALAR_FIELD(typmod);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1238,6 +1263,7 @@ _copyNullIfExpr(NullIfExpr *from) ...@@ -1238,6 +1263,7 @@ _copyNullIfExpr(NullIfExpr *from)
COPY_SCALAR_FIELD(opresulttype); COPY_SCALAR_FIELD(opresulttype);
COPY_SCALAR_FIELD(opretset); COPY_SCALAR_FIELD(opretset);
COPY_NODE_FIELD(args); COPY_NODE_FIELD(args);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1282,6 +1308,7 @@ _copyCoerceToDomain(CoerceToDomain *from) ...@@ -1282,6 +1308,7 @@ _copyCoerceToDomain(CoerceToDomain *from)
COPY_SCALAR_FIELD(resulttype); COPY_SCALAR_FIELD(resulttype);
COPY_SCALAR_FIELD(resulttypmod); COPY_SCALAR_FIELD(resulttypmod);
COPY_SCALAR_FIELD(coercionformat); COPY_SCALAR_FIELD(coercionformat);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1296,6 +1323,7 @@ _copyCoerceToDomainValue(CoerceToDomainValue *from) ...@@ -1296,6 +1323,7 @@ _copyCoerceToDomainValue(CoerceToDomainValue *from)
COPY_SCALAR_FIELD(typeId); COPY_SCALAR_FIELD(typeId);
COPY_SCALAR_FIELD(typeMod); COPY_SCALAR_FIELD(typeMod);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1310,6 +1338,7 @@ _copySetToDefault(SetToDefault *from) ...@@ -1310,6 +1338,7 @@ _copySetToDefault(SetToDefault *from)
COPY_SCALAR_FIELD(typeId); COPY_SCALAR_FIELD(typeId);
COPY_SCALAR_FIELD(typeMod); COPY_SCALAR_FIELD(typeMod);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1595,7 +1624,7 @@ _copyAExpr(A_Expr *from) ...@@ -1595,7 +1624,7 @@ _copyAExpr(A_Expr *from)
COPY_NODE_FIELD(name); COPY_NODE_FIELD(name);
COPY_NODE_FIELD(lexpr); COPY_NODE_FIELD(lexpr);
COPY_NODE_FIELD(rexpr); COPY_NODE_FIELD(rexpr);
COPY_SCALAR_FIELD(location); COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1606,7 +1635,7 @@ _copyColumnRef(ColumnRef *from) ...@@ -1606,7 +1635,7 @@ _copyColumnRef(ColumnRef *from)
ColumnRef *newnode = makeNode(ColumnRef); ColumnRef *newnode = makeNode(ColumnRef);
COPY_NODE_FIELD(fields); COPY_NODE_FIELD(fields);
COPY_SCALAR_FIELD(location); COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1617,6 +1646,7 @@ _copyParamRef(ParamRef *from) ...@@ -1617,6 +1646,7 @@ _copyParamRef(ParamRef *from)
ParamRef *newnode = makeNode(ParamRef); ParamRef *newnode = makeNode(ParamRef);
COPY_SCALAR_FIELD(number); COPY_SCALAR_FIELD(number);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1647,6 +1677,8 @@ _copyAConst(A_Const *from) ...@@ -1647,6 +1677,8 @@ _copyAConst(A_Const *from)
break; break;
} }
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1660,7 +1692,7 @@ _copyFuncCall(FuncCall *from) ...@@ -1660,7 +1692,7 @@ _copyFuncCall(FuncCall *from)
COPY_SCALAR_FIELD(agg_star); COPY_SCALAR_FIELD(agg_star);
COPY_SCALAR_FIELD(agg_distinct); COPY_SCALAR_FIELD(agg_distinct);
COPY_SCALAR_FIELD(func_variadic); COPY_SCALAR_FIELD(func_variadic);
COPY_SCALAR_FIELD(location); COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1693,6 +1725,7 @@ _copyA_ArrayExpr(A_ArrayExpr *from) ...@@ -1693,6 +1725,7 @@ _copyA_ArrayExpr(A_ArrayExpr *from)
A_ArrayExpr *newnode = makeNode(A_ArrayExpr); A_ArrayExpr *newnode = makeNode(A_ArrayExpr);
COPY_NODE_FIELD(elements); COPY_NODE_FIELD(elements);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1705,7 +1738,7 @@ _copyResTarget(ResTarget *from) ...@@ -1705,7 +1738,7 @@ _copyResTarget(ResTarget *from)
COPY_STRING_FIELD(name); COPY_STRING_FIELD(name);
COPY_NODE_FIELD(indirection); COPY_NODE_FIELD(indirection);
COPY_NODE_FIELD(val); COPY_NODE_FIELD(val);
COPY_SCALAR_FIELD(location); COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1722,7 +1755,7 @@ _copyTypeName(TypeName *from) ...@@ -1722,7 +1755,7 @@ _copyTypeName(TypeName *from)
COPY_NODE_FIELD(typmods); COPY_NODE_FIELD(typmods);
COPY_SCALAR_FIELD(typemod); COPY_SCALAR_FIELD(typemod);
COPY_NODE_FIELD(arrayBounds); COPY_NODE_FIELD(arrayBounds);
COPY_SCALAR_FIELD(location); COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1770,6 +1803,7 @@ _copyTypeCast(TypeCast *from) ...@@ -1770,6 +1803,7 @@ _copyTypeCast(TypeCast *from)
COPY_NODE_FIELD(arg); COPY_NODE_FIELD(arg);
COPY_NODE_FIELD(typename); COPY_NODE_FIELD(typename);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
...@@ -1852,6 +1886,7 @@ _copyXmlSerialize(XmlSerialize *from) ...@@ -1852,6 +1886,7 @@ _copyXmlSerialize(XmlSerialize *from)
COPY_SCALAR_FIELD(xmloption); COPY_SCALAR_FIELD(xmloption);
COPY_NODE_FIELD(expr); COPY_NODE_FIELD(expr);
COPY_NODE_FIELD(typename); COPY_NODE_FIELD(typename);
COPY_LOCATION_FIELD(location);
return newnode; return newnode;
} }
......
...@@ -13,12 +13,16 @@ ...@@ -13,12 +13,16 @@
* Currently, in fact, equal() doesn't know how to compare Plan trees * Currently, in fact, equal() doesn't know how to compare Plan trees
* either. This might need to be fixed someday. * either. This might need to be fixed someday.
* *
* NOTE: it is intentional that parse location fields (in nodes that have
* one) are not compared. This is because we want, for example, a variable
* "x" to be considered equal() to another reference to "x" in the query.
*
* *
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* 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.328 2008/08/22 00:16:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.329 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -75,6 +79,10 @@ ...@@ -75,6 +79,10 @@
return false; \ return false; \
} while (0) } while (0)
/* Compare a parse location field (this is a no-op, per note above) */
#define COMPARE_LOCATION_FIELD(fldname) \
((void) 0)
/* /*
* Stuff from primnodes.h * Stuff from primnodes.h
...@@ -131,6 +139,7 @@ _equalVar(Var *a, Var *b) ...@@ -131,6 +139,7 @@ _equalVar(Var *a, Var *b)
COMPARE_SCALAR_FIELD(varlevelsup); COMPARE_SCALAR_FIELD(varlevelsup);
COMPARE_SCALAR_FIELD(varnoold); COMPARE_SCALAR_FIELD(varnoold);
COMPARE_SCALAR_FIELD(varoattno); COMPARE_SCALAR_FIELD(varoattno);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -143,6 +152,7 @@ _equalConst(Const *a, Const *b) ...@@ -143,6 +152,7 @@ _equalConst(Const *a, Const *b)
COMPARE_SCALAR_FIELD(constlen); COMPARE_SCALAR_FIELD(constlen);
COMPARE_SCALAR_FIELD(constisnull); COMPARE_SCALAR_FIELD(constisnull);
COMPARE_SCALAR_FIELD(constbyval); COMPARE_SCALAR_FIELD(constbyval);
COMPARE_LOCATION_FIELD(location);
/* /*
* We treat all NULL constants of the same type as equal. Someday this * We treat all NULL constants of the same type as equal. Someday this
...@@ -161,6 +171,7 @@ _equalParam(Param *a, Param *b) ...@@ -161,6 +171,7 @@ _equalParam(Param *a, Param *b)
COMPARE_SCALAR_FIELD(paramid); COMPARE_SCALAR_FIELD(paramid);
COMPARE_SCALAR_FIELD(paramtype); COMPARE_SCALAR_FIELD(paramtype);
COMPARE_SCALAR_FIELD(paramtypmod); COMPARE_SCALAR_FIELD(paramtypmod);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -174,6 +185,7 @@ _equalAggref(Aggref *a, Aggref *b) ...@@ -174,6 +185,7 @@ _equalAggref(Aggref *a, Aggref *b)
COMPARE_SCALAR_FIELD(agglevelsup); COMPARE_SCALAR_FIELD(agglevelsup);
COMPARE_SCALAR_FIELD(aggstar); COMPARE_SCALAR_FIELD(aggstar);
COMPARE_SCALAR_FIELD(aggdistinct); COMPARE_SCALAR_FIELD(aggdistinct);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -209,6 +221,7 @@ _equalFuncExpr(FuncExpr *a, FuncExpr *b) ...@@ -209,6 +221,7 @@ _equalFuncExpr(FuncExpr *a, FuncExpr *b)
return false; return false;
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -232,6 +245,7 @@ _equalOpExpr(OpExpr *a, OpExpr *b) ...@@ -232,6 +245,7 @@ _equalOpExpr(OpExpr *a, OpExpr *b)
COMPARE_SCALAR_FIELD(opresulttype); COMPARE_SCALAR_FIELD(opresulttype);
COMPARE_SCALAR_FIELD(opretset); COMPARE_SCALAR_FIELD(opretset);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -255,6 +269,7 @@ _equalDistinctExpr(DistinctExpr *a, DistinctExpr *b) ...@@ -255,6 +269,7 @@ _equalDistinctExpr(DistinctExpr *a, DistinctExpr *b)
COMPARE_SCALAR_FIELD(opresulttype); COMPARE_SCALAR_FIELD(opresulttype);
COMPARE_SCALAR_FIELD(opretset); COMPARE_SCALAR_FIELD(opretset);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -277,6 +292,7 @@ _equalScalarArrayOpExpr(ScalarArrayOpExpr *a, ScalarArrayOpExpr *b) ...@@ -277,6 +292,7 @@ _equalScalarArrayOpExpr(ScalarArrayOpExpr *a, ScalarArrayOpExpr *b)
COMPARE_SCALAR_FIELD(useOr); COMPARE_SCALAR_FIELD(useOr);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -286,6 +302,7 @@ _equalBoolExpr(BoolExpr *a, BoolExpr *b) ...@@ -286,6 +302,7 @@ _equalBoolExpr(BoolExpr *a, BoolExpr *b)
{ {
COMPARE_SCALAR_FIELD(boolop); COMPARE_SCALAR_FIELD(boolop);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -297,6 +314,7 @@ _equalSubLink(SubLink *a, SubLink *b) ...@@ -297,6 +314,7 @@ _equalSubLink(SubLink *a, SubLink *b)
COMPARE_NODE_FIELD(testexpr); COMPARE_NODE_FIELD(testexpr);
COMPARE_NODE_FIELD(operName); COMPARE_NODE_FIELD(operName);
COMPARE_NODE_FIELD(subselect); COMPARE_NODE_FIELD(subselect);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -366,6 +384,8 @@ _equalRelabelType(RelabelType *a, RelabelType *b) ...@@ -366,6 +384,8 @@ _equalRelabelType(RelabelType *a, RelabelType *b)
b->relabelformat != COERCE_DONTCARE) b->relabelformat != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -384,6 +404,8 @@ _equalCoerceViaIO(CoerceViaIO *a, CoerceViaIO *b) ...@@ -384,6 +404,8 @@ _equalCoerceViaIO(CoerceViaIO *a, CoerceViaIO *b)
b->coerceformat != COERCE_DONTCARE) b->coerceformat != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -405,6 +427,8 @@ _equalArrayCoerceExpr(ArrayCoerceExpr *a, ArrayCoerceExpr *b) ...@@ -405,6 +427,8 @@ _equalArrayCoerceExpr(ArrayCoerceExpr *a, ArrayCoerceExpr *b)
b->coerceformat != COERCE_DONTCARE) b->coerceformat != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -423,6 +447,8 @@ _equalConvertRowtypeExpr(ConvertRowtypeExpr *a, ConvertRowtypeExpr *b) ...@@ -423,6 +447,8 @@ _equalConvertRowtypeExpr(ConvertRowtypeExpr *a, ConvertRowtypeExpr *b)
b->convertformat != COERCE_DONTCARE) b->convertformat != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -433,6 +459,7 @@ _equalCaseExpr(CaseExpr *a, CaseExpr *b) ...@@ -433,6 +459,7 @@ _equalCaseExpr(CaseExpr *a, CaseExpr *b)
COMPARE_NODE_FIELD(arg); COMPARE_NODE_FIELD(arg);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_NODE_FIELD(defresult); COMPARE_NODE_FIELD(defresult);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -442,6 +469,7 @@ _equalCaseWhen(CaseWhen *a, CaseWhen *b) ...@@ -442,6 +469,7 @@ _equalCaseWhen(CaseWhen *a, CaseWhen *b)
{ {
COMPARE_NODE_FIELD(expr); COMPARE_NODE_FIELD(expr);
COMPARE_NODE_FIELD(result); COMPARE_NODE_FIELD(result);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -462,6 +490,7 @@ _equalArrayExpr(ArrayExpr *a, ArrayExpr *b) ...@@ -462,6 +490,7 @@ _equalArrayExpr(ArrayExpr *a, ArrayExpr *b)
COMPARE_SCALAR_FIELD(element_typeid); COMPARE_SCALAR_FIELD(element_typeid);
COMPARE_NODE_FIELD(elements); COMPARE_NODE_FIELD(elements);
COMPARE_SCALAR_FIELD(multidims); COMPARE_SCALAR_FIELD(multidims);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -481,6 +510,8 @@ _equalRowExpr(RowExpr *a, RowExpr *b) ...@@ -481,6 +510,8 @@ _equalRowExpr(RowExpr *a, RowExpr *b)
b->row_format != COERCE_DONTCARE) b->row_format != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -501,6 +532,7 @@ _equalCoalesceExpr(CoalesceExpr *a, CoalesceExpr *b) ...@@ -501,6 +532,7 @@ _equalCoalesceExpr(CoalesceExpr *a, CoalesceExpr *b)
{ {
COMPARE_SCALAR_FIELD(coalescetype); COMPARE_SCALAR_FIELD(coalescetype);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -511,6 +543,7 @@ _equalMinMaxExpr(MinMaxExpr *a, MinMaxExpr *b) ...@@ -511,6 +543,7 @@ _equalMinMaxExpr(MinMaxExpr *a, MinMaxExpr *b)
COMPARE_SCALAR_FIELD(minmaxtype); COMPARE_SCALAR_FIELD(minmaxtype);
COMPARE_SCALAR_FIELD(op); COMPARE_SCALAR_FIELD(op);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -526,6 +559,7 @@ _equalXmlExpr(XmlExpr *a, XmlExpr *b) ...@@ -526,6 +559,7 @@ _equalXmlExpr(XmlExpr *a, XmlExpr *b)
COMPARE_SCALAR_FIELD(xmloption); COMPARE_SCALAR_FIELD(xmloption);
COMPARE_SCALAR_FIELD(type); COMPARE_SCALAR_FIELD(type);
COMPARE_SCALAR_FIELD(typmod); COMPARE_SCALAR_FIELD(typmod);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -549,6 +583,7 @@ _equalNullIfExpr(NullIfExpr *a, NullIfExpr *b) ...@@ -549,6 +583,7 @@ _equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
COMPARE_SCALAR_FIELD(opresulttype); COMPARE_SCALAR_FIELD(opresulttype);
COMPARE_SCALAR_FIELD(opretset); COMPARE_SCALAR_FIELD(opretset);
COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(args);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -587,6 +622,8 @@ _equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b) ...@@ -587,6 +622,8 @@ _equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
b->coercionformat != COERCE_DONTCARE) b->coercionformat != COERCE_DONTCARE)
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -595,6 +632,7 @@ _equalCoerceToDomainValue(CoerceToDomainValue *a, CoerceToDomainValue *b) ...@@ -595,6 +632,7 @@ _equalCoerceToDomainValue(CoerceToDomainValue *a, CoerceToDomainValue *b)
{ {
COMPARE_SCALAR_FIELD(typeId); COMPARE_SCALAR_FIELD(typeId);
COMPARE_SCALAR_FIELD(typeMod); COMPARE_SCALAR_FIELD(typeMod);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -604,6 +642,7 @@ _equalSetToDefault(SetToDefault *a, SetToDefault *b) ...@@ -604,6 +642,7 @@ _equalSetToDefault(SetToDefault *a, SetToDefault *b)
{ {
COMPARE_SCALAR_FIELD(typeId); COMPARE_SCALAR_FIELD(typeId);
COMPARE_SCALAR_FIELD(typeMod); COMPARE_SCALAR_FIELD(typeMod);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1680,7 +1719,7 @@ _equalAExpr(A_Expr *a, A_Expr *b) ...@@ -1680,7 +1719,7 @@ _equalAExpr(A_Expr *a, A_Expr *b)
COMPARE_NODE_FIELD(name); COMPARE_NODE_FIELD(name);
COMPARE_NODE_FIELD(lexpr); COMPARE_NODE_FIELD(lexpr);
COMPARE_NODE_FIELD(rexpr); COMPARE_NODE_FIELD(rexpr);
COMPARE_SCALAR_FIELD(location); COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1689,7 +1728,7 @@ static bool ...@@ -1689,7 +1728,7 @@ static bool
_equalColumnRef(ColumnRef *a, ColumnRef *b) _equalColumnRef(ColumnRef *a, ColumnRef *b)
{ {
COMPARE_NODE_FIELD(fields); COMPARE_NODE_FIELD(fields);
COMPARE_SCALAR_FIELD(location); COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1698,6 +1737,7 @@ static bool ...@@ -1698,6 +1737,7 @@ static bool
_equalParamRef(ParamRef *a, ParamRef *b) _equalParamRef(ParamRef *a, ParamRef *b)
{ {
COMPARE_SCALAR_FIELD(number); COMPARE_SCALAR_FIELD(number);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1707,6 +1747,7 @@ _equalAConst(A_Const *a, A_Const *b) ...@@ -1707,6 +1747,7 @@ _equalAConst(A_Const *a, A_Const *b)
{ {
if (!equal(&a->val, &b->val)) /* hack for in-line Value field */ if (!equal(&a->val, &b->val)) /* hack for in-line Value field */
return false; return false;
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1719,7 +1760,7 @@ _equalFuncCall(FuncCall *a, FuncCall *b) ...@@ -1719,7 +1760,7 @@ _equalFuncCall(FuncCall *a, FuncCall *b)
COMPARE_SCALAR_FIELD(agg_star); COMPARE_SCALAR_FIELD(agg_star);
COMPARE_SCALAR_FIELD(agg_distinct); COMPARE_SCALAR_FIELD(agg_distinct);
COMPARE_SCALAR_FIELD(func_variadic); COMPARE_SCALAR_FIELD(func_variadic);
COMPARE_SCALAR_FIELD(location); COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1746,6 +1787,7 @@ static bool ...@@ -1746,6 +1787,7 @@ static bool
_equalA_ArrayExpr(A_ArrayExpr *a, A_ArrayExpr *b) _equalA_ArrayExpr(A_ArrayExpr *a, A_ArrayExpr *b)
{ {
COMPARE_NODE_FIELD(elements); COMPARE_NODE_FIELD(elements);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1756,7 +1798,7 @@ _equalResTarget(ResTarget *a, ResTarget *b) ...@@ -1756,7 +1798,7 @@ _equalResTarget(ResTarget *a, ResTarget *b)
COMPARE_STRING_FIELD(name); COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(indirection); COMPARE_NODE_FIELD(indirection);
COMPARE_NODE_FIELD(val); COMPARE_NODE_FIELD(val);
COMPARE_SCALAR_FIELD(location); COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1771,7 +1813,7 @@ _equalTypeName(TypeName *a, TypeName *b) ...@@ -1771,7 +1813,7 @@ _equalTypeName(TypeName *a, TypeName *b)
COMPARE_NODE_FIELD(typmods); COMPARE_NODE_FIELD(typmods);
COMPARE_SCALAR_FIELD(typemod); COMPARE_SCALAR_FIELD(typemod);
COMPARE_NODE_FIELD(arrayBounds); COMPARE_NODE_FIELD(arrayBounds);
COMPARE_SCALAR_FIELD(location); COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1781,6 +1823,7 @@ _equalTypeCast(TypeCast *a, TypeCast *b) ...@@ -1781,6 +1823,7 @@ _equalTypeCast(TypeCast *a, TypeCast *b)
{ {
COMPARE_NODE_FIELD(arg); COMPARE_NODE_FIELD(arg);
COMPARE_NODE_FIELD(typename); COMPARE_NODE_FIELD(typename);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
...@@ -1941,6 +1984,7 @@ _equalXmlSerialize(XmlSerialize *a, XmlSerialize *b) ...@@ -1941,6 +1984,7 @@ _equalXmlSerialize(XmlSerialize *a, XmlSerialize *b)
COMPARE_SCALAR_FIELD(xmloption); COMPARE_SCALAR_FIELD(xmloption);
COMPARE_NODE_FIELD(expr); COMPARE_NODE_FIELD(expr);
COMPARE_NODE_FIELD(typename); COMPARE_NODE_FIELD(typename);
COMPARE_LOCATION_FIELD(location);
return true; return true;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.58 2008/01/01 19:45:50 momjian Exp $ * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.59 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -84,6 +84,9 @@ makeVar(Index varno, ...@@ -84,6 +84,9 @@ makeVar(Index varno,
var->varnoold = varno; var->varnoold = varno;
var->varoattno = varattno; var->varoattno = varattno;
/* Likewise, we just set location to "unknown" here */
var->location = -1;
return var; return var;
} }
...@@ -168,6 +171,7 @@ makeConst(Oid consttype, ...@@ -168,6 +171,7 @@ makeConst(Oid consttype,
cnst->constvalue = constvalue; cnst->constvalue = constvalue;
cnst->constisnull = constisnull; cnst->constisnull = constisnull;
cnst->constbyval = constbyval; cnst->constbyval = constbyval;
cnst->location = -1; /* "unknown" */
return cnst; return cnst;
} }
...@@ -211,12 +215,13 @@ makeBoolConst(bool value, bool isnull) ...@@ -211,12 +215,13 @@ makeBoolConst(bool value, bool isnull)
* creates a BoolExpr node * creates a BoolExpr node
*/ */
Expr * Expr *
makeBoolExpr(BoolExprType boolop, List *args) makeBoolExpr(BoolExprType boolop, List *args, int location)
{ {
BoolExpr *b = makeNode(BoolExpr); BoolExpr *b = makeNode(BoolExpr);
b->boolop = boolop; b->boolop = boolop;
b->args = args; b->args = args;
b->location = location;
return (Expr *) b; return (Expr *) b;
} }
...@@ -251,6 +256,7 @@ makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, CoercionForm rformat) ...@@ -251,6 +256,7 @@ makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, CoercionForm rformat)
r->resulttype = rtype; r->resulttype = rtype;
r->resulttypmod = rtypmod; r->resulttypmod = rtypmod;
r->relabelformat = rformat; r->relabelformat = rformat;
r->location = -1;
return r; return r;
} }
...@@ -336,6 +342,7 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args, CoercionForm fformat) ...@@ -336,6 +342,7 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
funcexpr->funcretset = false; /* only allowed case here */ funcexpr->funcretset = false; /* only allowed case here */
funcexpr->funcformat = fformat; funcexpr->funcformat = fformat;
funcexpr->args = args; funcexpr->args = args;
funcexpr->location = -1;
return funcexpr; return funcexpr;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.30 2008/08/25 22:42:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.31 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
static bool expression_returns_set_walker(Node *node, void *context); static bool expression_returns_set_walker(Node *node, void *context);
static int leftmostLoc(int loc1, int loc2);
/* /*
...@@ -574,6 +575,315 @@ expression_returns_set_walker(Node *node, void *context) ...@@ -574,6 +575,315 @@ expression_returns_set_walker(Node *node, void *context)
} }
/*
* exprLocation -
* returns the parse location of an expression tree, for error reports
*
* -1 is returned if the location can't be determined.
*
* For expressions larger than a single token, the intent here is to
* return the location of the expression's leftmost token, not necessarily
* the topmost Node's location field. For example, an OpExpr's location
* field will point at the operator name, but if it is not a prefix operator
* then we should return the location of the left-hand operand instead.
* The reason is that we want to reference the entire expression not just
* that operator, and pointing to its start seems to be the most natural way.
*
* The location is not perfect --- for example, since the grammar doesn't
* explicitly represent parentheses in the parsetree, given something that
* had been written "(a + b) * c" we are going to point at "a" not "(".
* But it should be plenty good enough for error reporting purposes.
*
* You might think that this code is overly general, for instance why check
* the operands of a FuncExpr node, when the function name can be expected
* to be to the left of them? There are a couple of reasons. The grammar
* sometimes builds expressions that aren't quite what the user wrote;
* for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
* pointer is to the right of its leftmost argument. Also, nodes that were
* inserted implicitly by parse analysis (such as FuncExprs for implicit
* coercions) will have location -1, and so we can have odd combinations of
* known and unknown locations in a tree.
*/
int
exprLocation(Node *expr)
{
int loc;
if (expr == NULL)
return -1;
switch (nodeTag(expr))
{
case T_Var:
loc = ((Var *) expr)->location;
break;
case T_Const:
loc = ((Const *) expr)->location;
break;
case T_Param:
loc = ((Param *) expr)->location;
break;
case T_Aggref:
/* function name should always be the first thing */
loc = ((Aggref *) expr)->location;
break;
case T_ArrayRef:
/* just use array argument's location */
loc = exprLocation((Node *) ((ArrayRef *) expr)->refexpr);
break;
case T_FuncExpr:
{
FuncExpr *fexpr = (FuncExpr *) expr;
/* consider both function name and leftmost arg */
loc = leftmostLoc(fexpr->location,
exprLocation((Node *) fexpr->args));
}
break;
case T_OpExpr:
case T_DistinctExpr: /* struct-equivalent to OpExpr */
case T_NullIfExpr: /* struct-equivalent to OpExpr */
{
OpExpr *opexpr = (OpExpr *) expr;
/* consider both operator name and leftmost arg */
loc = leftmostLoc(opexpr->location,
exprLocation((Node *) opexpr->args));
}
break;
case T_ScalarArrayOpExpr:
{
ScalarArrayOpExpr *saopexpr = (ScalarArrayOpExpr *) expr;
/* consider both operator name and leftmost arg */
loc = leftmostLoc(saopexpr->location,
exprLocation((Node *) saopexpr->args));
}
break;
case T_BoolExpr:
{
BoolExpr *bexpr = (BoolExpr *) expr;
/*
* Same as above, to handle either NOT or AND/OR. We can't
* special-case NOT because of the way that it's used for
* things like IS NOT BETWEEN.
*/
loc = leftmostLoc(bexpr->location,
exprLocation((Node *) bexpr->args));
}
break;
case T_SubLink:
{
SubLink *sublink = (SubLink *) expr;
/* check the testexpr, if any, and the operator/keyword */
loc = leftmostLoc(exprLocation(sublink->testexpr),
sublink->location);
}
break;
case T_FieldSelect:
/* just use argument's location */
loc = exprLocation((Node *) ((FieldSelect *) expr)->arg);
break;
case T_FieldStore:
/* just use argument's location */
loc = exprLocation((Node *) ((FieldStore *) expr)->arg);
break;
case T_RelabelType:
{
RelabelType *rexpr = (RelabelType *) expr;
/* Much as above */
loc = leftmostLoc(rexpr->location,
exprLocation((Node *) rexpr->arg));
}
break;
case T_CoerceViaIO:
{
CoerceViaIO *cexpr = (CoerceViaIO *) expr;
/* Much as above */
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_ArrayCoerceExpr:
{
ArrayCoerceExpr *cexpr = (ArrayCoerceExpr *) expr;
/* Much as above */
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_ConvertRowtypeExpr:
{
ConvertRowtypeExpr *cexpr = (ConvertRowtypeExpr *) expr;
/* Much as above */
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_CaseExpr:
/* CASE keyword should always be the first thing */
loc = ((CaseExpr *) expr)->location;
break;
case T_CaseWhen:
/* WHEN keyword should always be the first thing */
loc = ((CaseWhen *) expr)->location;
break;
case T_ArrayExpr:
/* the location points at ARRAY or [, which must be leftmost */
loc = ((ArrayExpr *) expr)->location;
break;
case T_RowExpr:
/* the location points at ROW or (, which must be leftmost */
loc = ((RowExpr *) expr)->location;
break;
case T_RowCompareExpr:
/* just use leftmost argument's location */
loc = exprLocation((Node *) ((RowCompareExpr *) expr)->largs);
break;
case T_CoalesceExpr:
/* COALESCE keyword should always be the first thing */
loc = ((CoalesceExpr *) expr)->location;
break;
case T_MinMaxExpr:
/* GREATEST/LEAST keyword should always be the first thing */
loc = ((MinMaxExpr *) expr)->location;
break;
case T_XmlExpr:
{
XmlExpr *xexpr = (XmlExpr *) expr;
/* consider both function name and leftmost arg */
loc = leftmostLoc(xexpr->location,
exprLocation((Node *) xexpr->args));
}
break;
case T_NullTest:
/* just use argument's location */
loc = exprLocation((Node *) ((NullTest *) expr)->arg);
break;
case T_BooleanTest:
/* just use argument's location */
loc = exprLocation((Node *) ((BooleanTest *) expr)->arg);
break;
case T_CoerceToDomain:
{
CoerceToDomain *cexpr = (CoerceToDomain *) expr;
/* Much as above */
loc = leftmostLoc(cexpr->location,
exprLocation((Node *) cexpr->arg));
}
break;
case T_CoerceToDomainValue:
loc = ((CoerceToDomainValue *) expr)->location;
break;
case T_SetToDefault:
loc = ((SetToDefault *) expr)->location;
break;
case T_TargetEntry:
/* just use argument's location */
loc = exprLocation((Node *) ((TargetEntry *) expr)->expr);
break;
case T_List:
{
/* report location of first list member that has a location */
ListCell *lc;
loc = -1; /* just to suppress compiler warning */
foreach(lc, (List *) expr)
{
loc = exprLocation((Node *) lfirst(lc));
if (loc >= 0)
break;
}
}
break;
case T_A_Expr:
{
A_Expr *aexpr = (A_Expr *) expr;
/* use leftmost of operator or left operand (if any) */
/* we assume right operand can't be to left of operator */
loc = leftmostLoc(aexpr->location,
exprLocation(aexpr->lexpr));
}
break;
case T_ColumnRef:
loc = ((ColumnRef *) expr)->location;
break;
case T_ParamRef:
loc = ((ParamRef *) expr)->location;
break;
case T_A_Const:
loc = ((A_Const *) expr)->location;
break;
case T_FuncCall:
{
FuncCall *fc = (FuncCall *) expr;
/* consider both function name and leftmost arg */
loc = leftmostLoc(fc->location,
exprLocation((Node *) fc->args));
}
break;
case T_A_ArrayExpr:
/* the location points at ARRAY or [, which must be leftmost */
loc = ((A_ArrayExpr *) expr)->location;
break;
case T_ResTarget:
/* we need not examine the contained expression (if any) */
loc = ((ResTarget *) expr)->location;
break;
case T_TypeCast:
{
TypeCast *tc = (TypeCast *) expr;
/*
* This could represent CAST(), ::, or TypeName 'literal',
* so any of the components might be leftmost.
*/
loc = exprLocation(tc->arg);
loc = leftmostLoc(loc, tc->typename->location);
loc = leftmostLoc(loc, tc->location);
}
break;
case T_TypeName:
loc = ((TypeName *) expr)->location;
break;
case T_XmlSerialize:
/* XMLSERIALIZE keyword should always be the first thing */
loc = ((XmlSerialize *) expr)->location;
break;
default:
/* for any other node type it's just unknown... */
loc = -1;
break;
}
return loc;
}
/*
* leftmostLoc - support for exprLocation
*
* Take the minimum of two parse location values, but ignore unknowns
*/
static int
leftmostLoc(int loc1, int loc2)
{
if (loc1 < 0)
return loc2;
else if (loc2 < 0)
return loc1;
else
return Min(loc1, loc2);
}
/* /*
* Standard expression-tree walking support * Standard expression-tree walking support
* *
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.335 2008/08/22 00:16:03 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.336 2008/08/28 23:09:46 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*
...@@ -79,6 +79,10 @@ ...@@ -79,6 +79,10 @@
(appendStringInfo(str, " :" CppAsString(fldname) " "), \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \
_outToken(str, node->fldname)) _outToken(str, node->fldname))
/* Write a parse location field (actually same as INT case) */
#define WRITE_LOCATION_FIELD(fldname) \
appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
/* Write a Node field */ /* Write a Node field */
#define WRITE_NODE_FIELD(fldname) \ #define WRITE_NODE_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \ (appendStringInfo(str, " :" CppAsString(fldname) " "), \
...@@ -689,6 +693,7 @@ _outVar(StringInfo str, Var *node) ...@@ -689,6 +693,7 @@ _outVar(StringInfo str, Var *node)
WRITE_UINT_FIELD(varlevelsup); WRITE_UINT_FIELD(varlevelsup);
WRITE_UINT_FIELD(varnoold); WRITE_UINT_FIELD(varnoold);
WRITE_INT_FIELD(varoattno); WRITE_INT_FIELD(varoattno);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -701,6 +706,7 @@ _outConst(StringInfo str, Const *node) ...@@ -701,6 +706,7 @@ _outConst(StringInfo str, Const *node)
WRITE_INT_FIELD(constlen); WRITE_INT_FIELD(constlen);
WRITE_BOOL_FIELD(constbyval); WRITE_BOOL_FIELD(constbyval);
WRITE_BOOL_FIELD(constisnull); WRITE_BOOL_FIELD(constisnull);
WRITE_LOCATION_FIELD(location);
appendStringInfo(str, " :constvalue "); appendStringInfo(str, " :constvalue ");
if (node->constisnull) if (node->constisnull)
...@@ -718,6 +724,7 @@ _outParam(StringInfo str, Param *node) ...@@ -718,6 +724,7 @@ _outParam(StringInfo str, Param *node)
WRITE_INT_FIELD(paramid); WRITE_INT_FIELD(paramid);
WRITE_OID_FIELD(paramtype); WRITE_OID_FIELD(paramtype);
WRITE_INT_FIELD(paramtypmod); WRITE_INT_FIELD(paramtypmod);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -731,6 +738,7 @@ _outAggref(StringInfo str, Aggref *node) ...@@ -731,6 +738,7 @@ _outAggref(StringInfo str, Aggref *node)
WRITE_UINT_FIELD(agglevelsup); WRITE_UINT_FIELD(agglevelsup);
WRITE_BOOL_FIELD(aggstar); WRITE_BOOL_FIELD(aggstar);
WRITE_BOOL_FIELD(aggdistinct); WRITE_BOOL_FIELD(aggdistinct);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -757,6 +765,7 @@ _outFuncExpr(StringInfo str, FuncExpr *node) ...@@ -757,6 +765,7 @@ _outFuncExpr(StringInfo str, FuncExpr *node)
WRITE_BOOL_FIELD(funcretset); WRITE_BOOL_FIELD(funcretset);
WRITE_ENUM_FIELD(funcformat, CoercionForm); WRITE_ENUM_FIELD(funcformat, CoercionForm);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -769,6 +778,7 @@ _outOpExpr(StringInfo str, OpExpr *node) ...@@ -769,6 +778,7 @@ _outOpExpr(StringInfo str, OpExpr *node)
WRITE_OID_FIELD(opresulttype); WRITE_OID_FIELD(opresulttype);
WRITE_BOOL_FIELD(opretset); WRITE_BOOL_FIELD(opretset);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -781,6 +791,7 @@ _outDistinctExpr(StringInfo str, DistinctExpr *node) ...@@ -781,6 +791,7 @@ _outDistinctExpr(StringInfo str, DistinctExpr *node)
WRITE_OID_FIELD(opresulttype); WRITE_OID_FIELD(opresulttype);
WRITE_BOOL_FIELD(opretset); WRITE_BOOL_FIELD(opretset);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -792,6 +803,7 @@ _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node) ...@@ -792,6 +803,7 @@ _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr *node)
WRITE_OID_FIELD(opfuncid); WRITE_OID_FIELD(opfuncid);
WRITE_BOOL_FIELD(useOr); WRITE_BOOL_FIELD(useOr);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -818,6 +830,7 @@ _outBoolExpr(StringInfo str, BoolExpr *node) ...@@ -818,6 +830,7 @@ _outBoolExpr(StringInfo str, BoolExpr *node)
_outToken(str, opstr); _outToken(str, opstr);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -829,6 +842,7 @@ _outSubLink(StringInfo str, SubLink *node) ...@@ -829,6 +842,7 @@ _outSubLink(StringInfo str, SubLink *node)
WRITE_NODE_FIELD(testexpr); WRITE_NODE_FIELD(testexpr);
WRITE_NODE_FIELD(operName); WRITE_NODE_FIELD(operName);
WRITE_NODE_FIELD(subselect); WRITE_NODE_FIELD(subselect);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -889,6 +903,7 @@ _outRelabelType(StringInfo str, RelabelType *node) ...@@ -889,6 +903,7 @@ _outRelabelType(StringInfo str, RelabelType *node)
WRITE_OID_FIELD(resulttype); WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod); WRITE_INT_FIELD(resulttypmod);
WRITE_ENUM_FIELD(relabelformat, CoercionForm); WRITE_ENUM_FIELD(relabelformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -899,6 +914,7 @@ _outCoerceViaIO(StringInfo str, CoerceViaIO *node) ...@@ -899,6 +914,7 @@ _outCoerceViaIO(StringInfo str, CoerceViaIO *node)
WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype); WRITE_OID_FIELD(resulttype);
WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_ENUM_FIELD(coerceformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -912,6 +928,7 @@ _outArrayCoerceExpr(StringInfo str, ArrayCoerceExpr *node) ...@@ -912,6 +928,7 @@ _outArrayCoerceExpr(StringInfo str, ArrayCoerceExpr *node)
WRITE_INT_FIELD(resulttypmod); WRITE_INT_FIELD(resulttypmod);
WRITE_BOOL_FIELD(isExplicit); WRITE_BOOL_FIELD(isExplicit);
WRITE_ENUM_FIELD(coerceformat, CoercionForm); WRITE_ENUM_FIELD(coerceformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -922,6 +939,7 @@ _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node) ...@@ -922,6 +939,7 @@ _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node)
WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype); WRITE_OID_FIELD(resulttype);
WRITE_ENUM_FIELD(convertformat, CoercionForm); WRITE_ENUM_FIELD(convertformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -933,6 +951,7 @@ _outCaseExpr(StringInfo str, CaseExpr *node) ...@@ -933,6 +951,7 @@ _outCaseExpr(StringInfo str, CaseExpr *node)
WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(defresult); WRITE_NODE_FIELD(defresult);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -942,6 +961,7 @@ _outCaseWhen(StringInfo str, CaseWhen *node) ...@@ -942,6 +961,7 @@ _outCaseWhen(StringInfo str, CaseWhen *node)
WRITE_NODE_FIELD(expr); WRITE_NODE_FIELD(expr);
WRITE_NODE_FIELD(result); WRITE_NODE_FIELD(result);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -962,6 +982,7 @@ _outArrayExpr(StringInfo str, ArrayExpr *node) ...@@ -962,6 +982,7 @@ _outArrayExpr(StringInfo str, ArrayExpr *node)
WRITE_OID_FIELD(element_typeid); WRITE_OID_FIELD(element_typeid);
WRITE_NODE_FIELD(elements); WRITE_NODE_FIELD(elements);
WRITE_BOOL_FIELD(multidims); WRITE_BOOL_FIELD(multidims);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -972,6 +993,7 @@ _outRowExpr(StringInfo str, RowExpr *node) ...@@ -972,6 +993,7 @@ _outRowExpr(StringInfo str, RowExpr *node)
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_OID_FIELD(row_typeid); WRITE_OID_FIELD(row_typeid);
WRITE_ENUM_FIELD(row_format, CoercionForm); WRITE_ENUM_FIELD(row_format, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -993,6 +1015,7 @@ _outCoalesceExpr(StringInfo str, CoalesceExpr *node) ...@@ -993,6 +1015,7 @@ _outCoalesceExpr(StringInfo str, CoalesceExpr *node)
WRITE_OID_FIELD(coalescetype); WRITE_OID_FIELD(coalescetype);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1003,6 +1026,7 @@ _outMinMaxExpr(StringInfo str, MinMaxExpr *node) ...@@ -1003,6 +1026,7 @@ _outMinMaxExpr(StringInfo str, MinMaxExpr *node)
WRITE_OID_FIELD(minmaxtype); WRITE_OID_FIELD(minmaxtype);
WRITE_ENUM_FIELD(op, MinMaxOp); WRITE_ENUM_FIELD(op, MinMaxOp);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1018,6 +1042,7 @@ _outXmlExpr(StringInfo str, XmlExpr *node) ...@@ -1018,6 +1042,7 @@ _outXmlExpr(StringInfo str, XmlExpr *node)
WRITE_ENUM_FIELD(xmloption, XmlOptionType); WRITE_ENUM_FIELD(xmloption, XmlOptionType);
WRITE_OID_FIELD(type); WRITE_OID_FIELD(type);
WRITE_INT_FIELD(typmod); WRITE_INT_FIELD(typmod);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1030,6 +1055,7 @@ _outNullIfExpr(StringInfo str, NullIfExpr *node) ...@@ -1030,6 +1055,7 @@ _outNullIfExpr(StringInfo str, NullIfExpr *node)
WRITE_OID_FIELD(opresulttype); WRITE_OID_FIELD(opresulttype);
WRITE_BOOL_FIELD(opretset); WRITE_BOOL_FIELD(opretset);
WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1059,6 +1085,7 @@ _outCoerceToDomain(StringInfo str, CoerceToDomain *node) ...@@ -1059,6 +1085,7 @@ _outCoerceToDomain(StringInfo str, CoerceToDomain *node)
WRITE_OID_FIELD(resulttype); WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod); WRITE_INT_FIELD(resulttypmod);
WRITE_ENUM_FIELD(coercionformat, CoercionForm); WRITE_ENUM_FIELD(coercionformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1068,6 +1095,7 @@ _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node) ...@@ -1068,6 +1095,7 @@ _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue *node)
WRITE_OID_FIELD(typeId); WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod); WRITE_INT_FIELD(typeMod);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1077,6 +1105,7 @@ _outSetToDefault(StringInfo str, SetToDefault *node) ...@@ -1077,6 +1105,7 @@ _outSetToDefault(StringInfo str, SetToDefault *node)
WRITE_OID_FIELD(typeId); WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod); WRITE_INT_FIELD(typeMod);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1626,7 +1655,7 @@ _outFuncCall(StringInfo str, FuncCall *node) ...@@ -1626,7 +1655,7 @@ _outFuncCall(StringInfo str, FuncCall *node)
WRITE_BOOL_FIELD(agg_star); WRITE_BOOL_FIELD(agg_star);
WRITE_BOOL_FIELD(agg_distinct); WRITE_BOOL_FIELD(agg_distinct);
WRITE_BOOL_FIELD(func_variadic); WRITE_BOOL_FIELD(func_variadic);
WRITE_INT_FIELD(location); WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1656,6 +1685,7 @@ _outXmlSerialize(StringInfo str, XmlSerialize *node) ...@@ -1656,6 +1685,7 @@ _outXmlSerialize(StringInfo str, XmlSerialize *node)
WRITE_ENUM_FIELD(xmloption, XmlOptionType); WRITE_ENUM_FIELD(xmloption, XmlOptionType);
WRITE_NODE_FIELD(expr); WRITE_NODE_FIELD(expr);
WRITE_NODE_FIELD(typename); WRITE_NODE_FIELD(typename);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1685,7 +1715,7 @@ _outTypeName(StringInfo str, TypeName *node) ...@@ -1685,7 +1715,7 @@ _outTypeName(StringInfo str, TypeName *node)
WRITE_NODE_FIELD(typmods); WRITE_NODE_FIELD(typmods);
WRITE_INT_FIELD(typemod); WRITE_INT_FIELD(typemod);
WRITE_NODE_FIELD(arrayBounds); WRITE_NODE_FIELD(arrayBounds);
WRITE_INT_FIELD(location); WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1695,6 +1725,7 @@ _outTypeCast(StringInfo str, TypeCast *node) ...@@ -1695,6 +1725,7 @@ _outTypeCast(StringInfo str, TypeCast *node)
WRITE_NODE_FIELD(arg); WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(typename); WRITE_NODE_FIELD(typename);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1892,7 +1923,7 @@ _outAExpr(StringInfo str, A_Expr *node) ...@@ -1892,7 +1923,7 @@ _outAExpr(StringInfo str, A_Expr *node)
WRITE_NODE_FIELD(lexpr); WRITE_NODE_FIELD(lexpr);
WRITE_NODE_FIELD(rexpr); WRITE_NODE_FIELD(rexpr);
WRITE_INT_FIELD(location); WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1936,7 +1967,7 @@ _outColumnRef(StringInfo str, ColumnRef *node) ...@@ -1936,7 +1967,7 @@ _outColumnRef(StringInfo str, ColumnRef *node)
WRITE_NODE_TYPE("COLUMNREF"); WRITE_NODE_TYPE("COLUMNREF");
WRITE_NODE_FIELD(fields); WRITE_NODE_FIELD(fields);
WRITE_INT_FIELD(location); WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1945,6 +1976,7 @@ _outParamRef(StringInfo str, ParamRef *node) ...@@ -1945,6 +1976,7 @@ _outParamRef(StringInfo str, ParamRef *node)
WRITE_NODE_TYPE("PARAMREF"); WRITE_NODE_TYPE("PARAMREF");
WRITE_INT_FIELD(number); WRITE_INT_FIELD(number);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1954,6 +1986,7 @@ _outAConst(StringInfo str, A_Const *node) ...@@ -1954,6 +1986,7 @@ _outAConst(StringInfo str, A_Const *node)
appendStringInfo(str, " :val "); appendStringInfo(str, " :val ");
_outValue(str, &(node->val)); _outValue(str, &(node->val));
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1980,6 +2013,7 @@ _outA_ArrayExpr(StringInfo str, A_ArrayExpr *node) ...@@ -1980,6 +2013,7 @@ _outA_ArrayExpr(StringInfo str, A_ArrayExpr *node)
WRITE_NODE_TYPE("A_ARRAYEXPR"); WRITE_NODE_TYPE("A_ARRAYEXPR");
WRITE_NODE_FIELD(elements); WRITE_NODE_FIELD(elements);
WRITE_LOCATION_FIELD(location);
} }
static void static void
...@@ -1990,7 +2024,7 @@ _outResTarget(StringInfo str, ResTarget *node) ...@@ -1990,7 +2024,7 @@ _outResTarget(StringInfo str, ResTarget *node)
WRITE_STRING_FIELD(name); WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(indirection); WRITE_NODE_FIELD(indirection);
WRITE_NODE_FIELD(val); WRITE_NODE_FIELD(val);
WRITE_INT_FIELD(location); WRITE_LOCATION_FIELD(location);
} }
static void static void
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.212 2008/08/07 01:11:49 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.213 2008/08/28 23:09:46 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
...@@ -16,6 +16,12 @@ ...@@ -16,6 +16,12 @@
* claimed to read them, but it was broken as well as unused.) We * claimed to read them, but it was broken as well as unused.) We
* never read executor state trees, either. * never read executor state trees, either.
* *
* Parse location fields are written out by outfuncs.c, but only for
* possible debugging use. When reading a location field, we discard
* the stored value and set the location field to -1 (ie, "unknown").
* This is because nodes coming from a stored rule should not be thought
* to have a known location in the current query's text.
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -97,6 +103,12 @@ ...@@ -97,6 +103,12 @@
token = pg_strtok(&length); /* get field value */ \ token = pg_strtok(&length); /* get field value */ \
local_node->fldname = nullable_string(token, length) local_node->fldname = nullable_string(token, length)
/* Read a parse location field (and throw away the value, per notes above) */
#define READ_LOCATION_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \
token = pg_strtok(&length); /* get field value */ \
local_node->fldname = -1 /* set field to "unknown" */
/* Read a Node field */ /* Read a Node field */
#define READ_NODE_FIELD(fldname) \ #define READ_NODE_FIELD(fldname) \
token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* skip :fldname */ \
...@@ -299,6 +311,7 @@ _readVar(void) ...@@ -299,6 +311,7 @@ _readVar(void)
READ_UINT_FIELD(varlevelsup); READ_UINT_FIELD(varlevelsup);
READ_UINT_FIELD(varnoold); READ_UINT_FIELD(varnoold);
READ_INT_FIELD(varoattno); READ_INT_FIELD(varoattno);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -316,6 +329,7 @@ _readConst(void) ...@@ -316,6 +329,7 @@ _readConst(void)
READ_INT_FIELD(constlen); READ_INT_FIELD(constlen);
READ_BOOL_FIELD(constbyval); READ_BOOL_FIELD(constbyval);
READ_BOOL_FIELD(constisnull); READ_BOOL_FIELD(constisnull);
READ_LOCATION_FIELD(location);
token = pg_strtok(&length); /* skip :constvalue */ token = pg_strtok(&length); /* skip :constvalue */
if (local_node->constisnull) if (local_node->constisnull)
...@@ -338,6 +352,7 @@ _readParam(void) ...@@ -338,6 +352,7 @@ _readParam(void)
READ_INT_FIELD(paramid); READ_INT_FIELD(paramid);
READ_OID_FIELD(paramtype); READ_OID_FIELD(paramtype);
READ_INT_FIELD(paramtypmod); READ_INT_FIELD(paramtypmod);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -356,6 +371,7 @@ _readAggref(void) ...@@ -356,6 +371,7 @@ _readAggref(void)
READ_UINT_FIELD(agglevelsup); READ_UINT_FIELD(agglevelsup);
READ_BOOL_FIELD(aggstar); READ_BOOL_FIELD(aggstar);
READ_BOOL_FIELD(aggdistinct); READ_BOOL_FIELD(aggdistinct);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -392,6 +408,7 @@ _readFuncExpr(void) ...@@ -392,6 +408,7 @@ _readFuncExpr(void)
READ_BOOL_FIELD(funcretset); READ_BOOL_FIELD(funcretset);
READ_ENUM_FIELD(funcformat, CoercionForm); READ_ENUM_FIELD(funcformat, CoercionForm);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -420,6 +437,7 @@ _readOpExpr(void) ...@@ -420,6 +437,7 @@ _readOpExpr(void)
READ_OID_FIELD(opresulttype); READ_OID_FIELD(opresulttype);
READ_BOOL_FIELD(opretset); READ_BOOL_FIELD(opretset);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -448,6 +466,7 @@ _readDistinctExpr(void) ...@@ -448,6 +466,7 @@ _readDistinctExpr(void)
READ_OID_FIELD(opresulttype); READ_OID_FIELD(opresulttype);
READ_BOOL_FIELD(opretset); READ_BOOL_FIELD(opretset);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -475,6 +494,7 @@ _readScalarArrayOpExpr(void) ...@@ -475,6 +494,7 @@ _readScalarArrayOpExpr(void)
READ_BOOL_FIELD(useOr); READ_BOOL_FIELD(useOr);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -500,6 +520,7 @@ _readBoolExpr(void) ...@@ -500,6 +520,7 @@ _readBoolExpr(void)
elog(ERROR, "unrecognized boolop \"%.*s\"", length, token); elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -516,6 +537,7 @@ _readSubLink(void) ...@@ -516,6 +537,7 @@ _readSubLink(void)
READ_NODE_FIELD(testexpr); READ_NODE_FIELD(testexpr);
READ_NODE_FIELD(operName); READ_NODE_FIELD(operName);
READ_NODE_FIELD(subselect); READ_NODE_FIELD(subselect);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -568,6 +590,7 @@ _readRelabelType(void) ...@@ -568,6 +590,7 @@ _readRelabelType(void)
READ_OID_FIELD(resulttype); READ_OID_FIELD(resulttype);
READ_INT_FIELD(resulttypmod); READ_INT_FIELD(resulttypmod);
READ_ENUM_FIELD(relabelformat, CoercionForm); READ_ENUM_FIELD(relabelformat, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -583,6 +606,7 @@ _readCoerceViaIO(void) ...@@ -583,6 +606,7 @@ _readCoerceViaIO(void)
READ_NODE_FIELD(arg); READ_NODE_FIELD(arg);
READ_OID_FIELD(resulttype); READ_OID_FIELD(resulttype);
READ_ENUM_FIELD(coerceformat, CoercionForm); READ_ENUM_FIELD(coerceformat, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -601,6 +625,7 @@ _readArrayCoerceExpr(void) ...@@ -601,6 +625,7 @@ _readArrayCoerceExpr(void)
READ_INT_FIELD(resulttypmod); READ_INT_FIELD(resulttypmod);
READ_BOOL_FIELD(isExplicit); READ_BOOL_FIELD(isExplicit);
READ_ENUM_FIELD(coerceformat, CoercionForm); READ_ENUM_FIELD(coerceformat, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -616,6 +641,7 @@ _readConvertRowtypeExpr(void) ...@@ -616,6 +641,7 @@ _readConvertRowtypeExpr(void)
READ_NODE_FIELD(arg); READ_NODE_FIELD(arg);
READ_OID_FIELD(resulttype); READ_OID_FIELD(resulttype);
READ_ENUM_FIELD(convertformat, CoercionForm); READ_ENUM_FIELD(convertformat, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -632,6 +658,7 @@ _readCaseExpr(void) ...@@ -632,6 +658,7 @@ _readCaseExpr(void)
READ_NODE_FIELD(arg); READ_NODE_FIELD(arg);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_NODE_FIELD(defresult); READ_NODE_FIELD(defresult);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -646,6 +673,7 @@ _readCaseWhen(void) ...@@ -646,6 +673,7 @@ _readCaseWhen(void)
READ_NODE_FIELD(expr); READ_NODE_FIELD(expr);
READ_NODE_FIELD(result); READ_NODE_FIELD(result);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -676,6 +704,7 @@ _readArrayExpr(void) ...@@ -676,6 +704,7 @@ _readArrayExpr(void)
READ_OID_FIELD(element_typeid); READ_OID_FIELD(element_typeid);
READ_NODE_FIELD(elements); READ_NODE_FIELD(elements);
READ_BOOL_FIELD(multidims); READ_BOOL_FIELD(multidims);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -691,6 +720,7 @@ _readRowExpr(void) ...@@ -691,6 +720,7 @@ _readRowExpr(void)
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_OID_FIELD(row_typeid); READ_OID_FIELD(row_typeid);
READ_ENUM_FIELD(row_format, CoercionForm); READ_ENUM_FIELD(row_format, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -722,6 +752,7 @@ _readCoalesceExpr(void) ...@@ -722,6 +752,7 @@ _readCoalesceExpr(void)
READ_OID_FIELD(coalescetype); READ_OID_FIELD(coalescetype);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -737,6 +768,7 @@ _readMinMaxExpr(void) ...@@ -737,6 +768,7 @@ _readMinMaxExpr(void)
READ_OID_FIELD(minmaxtype); READ_OID_FIELD(minmaxtype);
READ_ENUM_FIELD(op, MinMaxOp); READ_ENUM_FIELD(op, MinMaxOp);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -757,6 +789,7 @@ _readXmlExpr(void) ...@@ -757,6 +789,7 @@ _readXmlExpr(void)
READ_ENUM_FIELD(xmloption, XmlOptionType); READ_ENUM_FIELD(xmloption, XmlOptionType);
READ_OID_FIELD(type); READ_OID_FIELD(type);
READ_INT_FIELD(typmod); READ_INT_FIELD(typmod);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -785,6 +818,7 @@ _readNullIfExpr(void) ...@@ -785,6 +818,7 @@ _readNullIfExpr(void)
READ_OID_FIELD(opresulttype); READ_OID_FIELD(opresulttype);
READ_BOOL_FIELD(opretset); READ_BOOL_FIELD(opretset);
READ_NODE_FIELD(args); READ_NODE_FIELD(args);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -829,6 +863,7 @@ _readCoerceToDomain(void) ...@@ -829,6 +863,7 @@ _readCoerceToDomain(void)
READ_OID_FIELD(resulttype); READ_OID_FIELD(resulttype);
READ_INT_FIELD(resulttypmod); READ_INT_FIELD(resulttypmod);
READ_ENUM_FIELD(coercionformat, CoercionForm); READ_ENUM_FIELD(coercionformat, CoercionForm);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -843,6 +878,7 @@ _readCoerceToDomainValue(void) ...@@ -843,6 +878,7 @@ _readCoerceToDomainValue(void)
READ_OID_FIELD(typeId); READ_OID_FIELD(typeId);
READ_INT_FIELD(typeMod); READ_INT_FIELD(typeMod);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
...@@ -857,6 +893,7 @@ _readSetToDefault(void) ...@@ -857,6 +893,7 @@ _readSetToDefault(void)
READ_OID_FIELD(typeId); READ_OID_FIELD(typeId);
READ_INT_FIELD(typeMod); READ_INT_FIELD(typeMod);
READ_LOCATION_FIELD(location);
READ_DONE(); READ_DONE();
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.246 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.247 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1949,6 +1949,7 @@ get_switched_clauses(List *clauses, Relids outerrelids) ...@@ -1949,6 +1949,7 @@ get_switched_clauses(List *clauses, Relids outerrelids)
temp->opresulttype = clause->opresulttype; temp->opresulttype = clause->opresulttype;
temp->opretset = clause->opretset; temp->opretset = clause->opretset;
temp->args = list_copy(clause->args); temp->args = list_copy(clause->args);
temp->location = clause->location;
/* Commute it --- note this modifies the temp node in-place. */ /* Commute it --- note this modifies the temp node in-place. */
CommuteOpExpr(temp); CommuteOpExpr(temp);
t_list = lappend(t_list, temp); t_list = lappend(t_list, temp);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,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/optimizer/plan/subselect.c,v 1.139 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.140 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -140,6 +140,7 @@ replace_outer_var(PlannerInfo *root, Var *var) ...@@ -140,6 +140,7 @@ replace_outer_var(PlannerInfo *root, Var *var)
retval->paramid = i; retval->paramid = i;
retval->paramtype = var->vartype; retval->paramtype = var->vartype;
retval->paramtypmod = var->vartypmod; retval->paramtypmod = var->vartypmod;
retval->location = -1;
return retval; return retval;
} }
...@@ -179,6 +180,7 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg) ...@@ -179,6 +180,7 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
retval->paramid = i; retval->paramid = i;
retval->paramtype = agg->aggtype; retval->paramtype = agg->aggtype;
retval->paramtypmod = -1; retval->paramtypmod = -1;
retval->location = -1;
return retval; return retval;
} }
...@@ -199,6 +201,7 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod) ...@@ -199,6 +201,7 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod)
retval->paramid = list_length(root->glob->paramlist); retval->paramid = list_length(root->glob->paramlist);
retval->paramtype = paramtype; retval->paramtype = paramtype;
retval->paramtypmod = paramtypmod; retval->paramtypmod = paramtypmod;
retval->location = -1;
pitem = makeNode(PlannerParamItem); pitem = makeNode(PlannerParamItem);
pitem->item = (Node *) retval; pitem->item = (Node *) retval;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.58 2008/01/01 19:45:50 momjian Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.59 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -219,6 +219,7 @@ push_nots(Expr *qual) ...@@ -219,6 +219,7 @@ push_nots(Expr *qual)
newopexpr->opresulttype = opexpr->opresulttype; newopexpr->opresulttype = opexpr->opresulttype;
newopexpr->opretset = opexpr->opretset; newopexpr->opretset = opexpr->opretset;
newopexpr->args = opexpr->args; newopexpr->args = opexpr->args;
newopexpr->location = opexpr->location;
return (Expr *) newopexpr; return (Expr *) newopexpr;
} }
else else
...@@ -243,6 +244,7 @@ push_nots(Expr *qual) ...@@ -243,6 +244,7 @@ push_nots(Expr *qual)
newopexpr->opfuncid = InvalidOid; newopexpr->opfuncid = InvalidOid;
newopexpr->useOr = !saopexpr->useOr; newopexpr->useOr = !saopexpr->useOr;
newopexpr->args = saopexpr->args; newopexpr->args = saopexpr->args;
newopexpr->location = saopexpr->location;
return (Expr *) newopexpr; return (Expr *) newopexpr;
} }
else else
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,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/optimizer/prep/preptlist.c,v 1.90 2008/06/19 00:46:04 alvherre Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.91 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -292,6 +292,7 @@ expand_targetlist(List *tlist, int command_type, ...@@ -292,6 +292,7 @@ expand_targetlist(List *tlist, int command_type,
InvalidOid, -1, InvalidOid, -1,
atttype, atttype,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,
-1,
false, false,
false); false);
} }
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.154 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.155 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1410,6 +1410,7 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context) ...@@ -1410,6 +1410,7 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
r->arg = (Expr *) var; r->arg = (Expr *) var;
r->resulttype = context->parent_reltype; r->resulttype = context->parent_reltype;
r->convertformat = COERCE_IMPLICIT_CAST; r->convertformat = COERCE_IMPLICIT_CAST;
r->location = -1;
/* Make sure the Var node has the right type ID, too */ /* Make sure the Var node has the right type ID, too */
var->vartype = context->child_reltype; var->vartype = context->child_reltype;
return (Node *) r; return (Node *) r;
...@@ -1428,6 +1429,8 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context) ...@@ -1428,6 +1429,8 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
rowexpr->args = fields; rowexpr->args = fields;
rowexpr->row_typeid = var->vartype; rowexpr->row_typeid = var->vartype;
rowexpr->row_format = COERCE_IMPLICIT_CAST; rowexpr->row_format = COERCE_IMPLICIT_CAST;
rowexpr->location = -1;
return (Node *) rowexpr; return (Node *) rowexpr;
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.265 2008/08/26 02:16:31 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.266 2008/08/28 23:09:46 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -135,6 +135,7 @@ make_opclause(Oid opno, Oid opresulttype, bool opretset, ...@@ -135,6 +135,7 @@ make_opclause(Oid opno, Oid opresulttype, bool opretset,
expr->args = list_make2(leftop, rightop); expr->args = list_make2(leftop, rightop);
else else
expr->args = list_make1(leftop); expr->args = list_make1(leftop);
expr->location = -1;
return (Expr *) expr; return (Expr *) expr;
} }
...@@ -201,6 +202,7 @@ make_notclause(Expr *notclause) ...@@ -201,6 +202,7 @@ make_notclause(Expr *notclause)
expr->boolop = NOT_EXPR; expr->boolop = NOT_EXPR;
expr->args = list_make1(notclause); expr->args = list_make1(notclause);
expr->location = -1;
return (Expr *) expr; return (Expr *) expr;
} }
...@@ -244,6 +246,7 @@ make_orclause(List *orclauses) ...@@ -244,6 +246,7 @@ make_orclause(List *orclauses)
expr->boolop = OR_EXPR; expr->boolop = OR_EXPR;
expr->args = orclauses; expr->args = orclauses;
expr->location = -1;
return (Expr *) expr; return (Expr *) expr;
} }
...@@ -277,6 +280,7 @@ make_andclause(List *andclauses) ...@@ -277,6 +280,7 @@ make_andclause(List *andclauses)
expr->boolop = AND_EXPR; expr->boolop = AND_EXPR;
expr->args = andclauses; expr->args = andclauses;
expr->location = -1;
return (Expr *) expr; return (Expr *) expr;
} }
...@@ -2014,6 +2018,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2014,6 +2018,7 @@ eval_const_expressions_mutator(Node *node,
newexpr->funcretset = expr->funcretset; newexpr->funcretset = expr->funcretset;
newexpr->funcformat = expr->funcformat; newexpr->funcformat = expr->funcformat;
newexpr->args = args; newexpr->args = args;
newexpr->location = expr->location;
return (Node *) newexpr; return (Node *) newexpr;
} }
if (IsA(node, OpExpr)) if (IsA(node, OpExpr))
...@@ -2071,6 +2076,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2071,6 +2076,7 @@ eval_const_expressions_mutator(Node *node,
newexpr->opresulttype = expr->opresulttype; newexpr->opresulttype = expr->opresulttype;
newexpr->opretset = expr->opretset; newexpr->opretset = expr->opretset;
newexpr->args = args; newexpr->args = args;
newexpr->location = expr->location;
return (Node *) newexpr; return (Node *) newexpr;
} }
if (IsA(node, DistinctExpr)) if (IsA(node, DistinctExpr))
...@@ -2162,6 +2168,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2162,6 +2168,7 @@ eval_const_expressions_mutator(Node *node,
newexpr->opresulttype = expr->opresulttype; newexpr->opresulttype = expr->opresulttype;
newexpr->opretset = expr->opretset; newexpr->opretset = expr->opretset;
newexpr->args = args; newexpr->args = args;
newexpr->location = expr->location;
return (Node *) newexpr; return (Node *) newexpr;
} }
if (IsA(node, BoolExpr)) if (IsA(node, BoolExpr))
...@@ -2291,6 +2298,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2291,6 +2298,7 @@ eval_const_expressions_mutator(Node *node,
newrelabel->resulttype = relabel->resulttype; newrelabel->resulttype = relabel->resulttype;
newrelabel->resulttypmod = relabel->resulttypmod; newrelabel->resulttypmod = relabel->resulttypmod;
newrelabel->relabelformat = relabel->relabelformat; newrelabel->relabelformat = relabel->relabelformat;
newrelabel->location = relabel->location;
return (Node *) newrelabel; return (Node *) newrelabel;
} }
} }
...@@ -2357,6 +2365,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2357,6 +2365,7 @@ eval_const_expressions_mutator(Node *node,
newexpr->arg = arg; newexpr->arg = arg;
newexpr->resulttype = expr->resulttype; newexpr->resulttype = expr->resulttype;
newexpr->coerceformat = expr->coerceformat; newexpr->coerceformat = expr->coerceformat;
newexpr->location = expr->location;
return (Node *) newexpr; return (Node *) newexpr;
} }
if (IsA(node, ArrayCoerceExpr)) if (IsA(node, ArrayCoerceExpr))
...@@ -2379,6 +2388,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2379,6 +2388,7 @@ eval_const_expressions_mutator(Node *node,
newexpr->resulttypmod = expr->resulttypmod; newexpr->resulttypmod = expr->resulttypmod;
newexpr->isExplicit = expr->isExplicit; newexpr->isExplicit = expr->isExplicit;
newexpr->coerceformat = expr->coerceformat; newexpr->coerceformat = expr->coerceformat;
newexpr->location = expr->location;
/* /*
* If constant argument and it's a binary-coercible or immutable * If constant argument and it's a binary-coercible or immutable
...@@ -2477,6 +2487,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2477,6 +2487,7 @@ eval_const_expressions_mutator(Node *node,
newcasewhen->expr = (Expr *) casecond; newcasewhen->expr = (Expr *) casecond;
newcasewhen->result = (Expr *) caseresult; newcasewhen->result = (Expr *) caseresult;
newcasewhen->location = oldcasewhen->location;
newargs = lappend(newargs, newcasewhen); newargs = lappend(newargs, newcasewhen);
continue; continue;
} }
...@@ -2506,6 +2517,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2506,6 +2517,7 @@ eval_const_expressions_mutator(Node *node,
newcase->arg = (Expr *) newarg; newcase->arg = (Expr *) newarg;
newcase->args = newargs; newcase->args = newargs;
newcase->defresult = (Expr *) defresult; newcase->defresult = (Expr *) defresult;
newcase->location = caseexpr->location;
return (Node *) newcase; return (Node *) newcase;
} }
if (IsA(node, CaseTestExpr)) if (IsA(node, CaseTestExpr))
...@@ -2545,6 +2557,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2545,6 +2557,7 @@ eval_const_expressions_mutator(Node *node,
newarray->element_typeid = arrayexpr->element_typeid; newarray->element_typeid = arrayexpr->element_typeid;
newarray->elements = newelems; newarray->elements = newelems;
newarray->multidims = arrayexpr->multidims; newarray->multidims = arrayexpr->multidims;
newarray->location = arrayexpr->location;
if (all_const) if (all_const)
return (Node *) evaluate_expr((Expr *) newarray, return (Node *) evaluate_expr((Expr *) newarray,
...@@ -2590,6 +2603,7 @@ eval_const_expressions_mutator(Node *node, ...@@ -2590,6 +2603,7 @@ eval_const_expressions_mutator(Node *node,
newcoalesce = makeNode(CoalesceExpr); newcoalesce = makeNode(CoalesceExpr);
newcoalesce->coalescetype = coalesceexpr->coalescetype; newcoalesce->coalescetype = coalesceexpr->coalescetype;
newcoalesce->args = newargs; newcoalesce->args = newargs;
newcoalesce->location = coalesceexpr->location;
return (Node *) newcoalesce; return (Node *) newcoalesce;
} }
if (IsA(node, FieldSelect)) if (IsA(node, FieldSelect))
...@@ -3206,6 +3220,7 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, List *args, ...@@ -3206,6 +3220,7 @@ evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, List *args,
newexpr->funcretset = false; newexpr->funcretset = false;
newexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */ newexpr->funcformat = COERCE_DONTCARE; /* doesn't matter */
newexpr->args = args; newexpr->args = args;
newexpr->location = -1;
return evaluate_expr((Expr *) newexpr, result_type, result_typmod); return evaluate_expr((Expr *) newexpr, result_type, result_typmod);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.77 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.78 2008/08/28 23:09:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -624,6 +624,7 @@ flatten_join_alias_vars_mutator(Node *node, ...@@ -624,6 +624,7 @@ flatten_join_alias_vars_mutator(Node *node,
rowexpr->args = fields; rowexpr->args = fields;
rowexpr->row_typeid = var->vartype; rowexpr->row_typeid = var->vartype;
rowexpr->row_format = COERCE_IMPLICIT_CAST; rowexpr->row_format = COERCE_IMPLICIT_CAST;
rowexpr->location = -1;
return (Node *) rowexpr; return (Node *) rowexpr;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.81 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.82 2008/08/28 23:09:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -396,6 +396,7 @@ build_aggregate_fnexprs(Oid *agg_input_types, ...@@ -396,6 +396,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
argp->paramid = -1; argp->paramid = -1;
argp->paramtype = agg_state_type; argp->paramtype = agg_state_type;
argp->paramtypmod = -1; argp->paramtypmod = -1;
argp->location = -1;
args = list_make1(argp); args = list_make1(argp);
...@@ -406,6 +407,7 @@ build_aggregate_fnexprs(Oid *agg_input_types, ...@@ -406,6 +407,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
argp->paramid = -1; argp->paramid = -1;
argp->paramtype = agg_input_types[i]; argp->paramtype = agg_input_types[i];
argp->paramtypmod = -1; argp->paramtypmod = -1;
argp->location = -1;
args = lappend(args, argp); args = lappend(args, argp);
} }
...@@ -429,6 +431,7 @@ build_aggregate_fnexprs(Oid *agg_input_types, ...@@ -429,6 +431,7 @@ build_aggregate_fnexprs(Oid *agg_input_types,
argp->paramid = -1; argp->paramid = -1;
argp->paramtype = agg_state_type; argp->paramtype = agg_state_type;
argp->paramtypmod = -1; argp->paramtypmod = -1;
argp->location = -1;
args = list_make1(argp); args = list_make1(argp);
*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid, *finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.176 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.177 2008/08/28 23:09:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -964,9 +964,10 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype, ...@@ -964,9 +964,10 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype,
outcoltypmod = l_colvar->vartypmod; outcoltypmod = l_colvar->vartypmod;
if (outcoltype != r_colvar->vartype) if (outcoltype != r_colvar->vartype)
{ {
outcoltype = select_common_type(list_make2_oid(l_colvar->vartype, outcoltype = select_common_type(pstate,
r_colvar->vartype), list_make2(l_colvar, r_colvar),
"JOIN/USING"); "JOIN/USING",
NULL);
outcoltypmod = -1; /* ie, unknown */ outcoltypmod = -1; /* ie, unknown */
} }
else if (outcoltypmod != r_colvar->vartypmod) else if (outcoltypmod != r_colvar->vartypmod)
...@@ -984,7 +985,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype, ...@@ -984,7 +985,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype,
if (l_colvar->vartype != outcoltype) if (l_colvar->vartype != outcoltype)
l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype, l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype,
outcoltype, outcoltypmod, outcoltype, outcoltypmod,
COERCION_IMPLICIT, COERCE_IMPLICIT_CAST); COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
else if (l_colvar->vartypmod != outcoltypmod) else if (l_colvar->vartypmod != outcoltypmod)
l_node = (Node *) makeRelabelType((Expr *) l_colvar, l_node = (Node *) makeRelabelType((Expr *) l_colvar,
outcoltype, outcoltypmod, outcoltype, outcoltypmod,
...@@ -995,7 +996,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype, ...@@ -995,7 +996,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype,
if (r_colvar->vartype != outcoltype) if (r_colvar->vartype != outcoltype)
r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype, r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype,
outcoltype, outcoltypmod, outcoltype, outcoltypmod,
COERCION_IMPLICIT, COERCE_IMPLICIT_CAST); COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
else if (r_colvar->vartypmod != outcoltypmod) else if (r_colvar->vartypmod != outcoltypmod)
r_node = (Node *) makeRelabelType((Expr *) r_colvar, r_node = (Node *) makeRelabelType((Expr *) r_colvar,
outcoltype, outcoltypmod, outcoltype, outcoltypmod,
...@@ -1038,6 +1039,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype, ...@@ -1038,6 +1039,7 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype,
c->coalescetype = outcoltype; c->coalescetype = outcoltype;
c->args = list_make2(l_node, r_node); c->args = list_make2(l_node, r_node);
c->location = -1;
res_node = (Node *) c; res_node = (Node *) c;
break; break;
} }
...@@ -1239,6 +1241,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause) ...@@ -1239,6 +1241,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
if (IsA(node, A_Const)) if (IsA(node, A_Const))
{ {
Value *val = &((A_Const *) node)->val; Value *val = &((A_Const *) node)->val;
int location = ((A_Const *) node)->location;
int targetlist_pos = 0; int targetlist_pos = 0;
int target_pos; int target_pos;
...@@ -1247,7 +1250,9 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause) ...@@ -1247,7 +1250,9 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is name of a SQL construct, eg ORDER BY */ /* translator: %s is name of a SQL construct, eg ORDER BY */
errmsg("non-integer constant in %s", errmsg("non-integer constant in %s",
clauseText[clause]))); clauseText[clause]),
parser_errposition(pstate, location)));
target_pos = intVal(val); target_pos = intVal(val);
foreach(tl, *tlist) foreach(tl, *tlist)
{ {
...@@ -1263,7 +1268,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause) ...@@ -1263,7 +1268,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE), (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
/* translator: %s is name of a SQL construct, eg ORDER BY */ /* translator: %s is name of a SQL construct, eg ORDER BY */
errmsg("%s position %d is not in select list", errmsg("%s position %d is not in select list",
clauseText[clause], target_pos))); clauseText[clause], target_pos),
parser_errposition(pstate, location)));
} }
/* /*
...@@ -1590,7 +1596,8 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle, ...@@ -1590,7 +1596,8 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle,
tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr, tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
restype, TEXTOID, -1, restype, TEXTOID, -1,
COERCION_IMPLICIT, COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
restype = TEXTOID; restype = TEXTOID;
} }
...@@ -1704,7 +1711,8 @@ addTargetToGroupList(ParseState *pstate, TargetEntry *tle, ...@@ -1704,7 +1711,8 @@ addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr, tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
restype, TEXTOID, -1, restype, TEXTOID, -1,
COERCION_IMPLICIT, COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
restype = TEXTOID; restype = TEXTOID;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.205 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.206 2008/08/28 23:09:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -173,7 +173,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, ...@@ -173,7 +173,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
*/ */
return coerce_type(pstate, linitial(fargs), return coerce_type(pstate, linitial(fargs),
actual_arg_types[0], rettype, -1, actual_arg_types[0], rettype, -1,
COERCION_EXPLICIT, COERCE_EXPLICIT_CALL); COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location);
} }
else if (fdresult == FUNCDETAIL_NORMAL) else if (fdresult == FUNCDETAIL_NORMAL)
{ {
...@@ -272,6 +272,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, ...@@ -272,6 +272,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
errmsg("could not find array type for data type %s", errmsg("could not find array type for data type %s",
format_type_be(newa->element_typeid)))); format_type_be(newa->element_typeid))));
newa->multidims = false; newa->multidims = false;
newa->location = exprLocation((Node *) vargs);
fargs = lappend(fargs, newa); fargs = lappend(fargs, newa);
} }
...@@ -286,6 +287,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, ...@@ -286,6 +287,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
funcexpr->funcretset = retset; funcexpr->funcretset = retset;
funcexpr->funcformat = COERCE_EXPLICIT_CALL; funcexpr->funcformat = COERCE_EXPLICIT_CALL;
funcexpr->args = fargs; funcexpr->args = fargs;
funcexpr->location = location;
retval = (Node *) funcexpr; retval = (Node *) funcexpr;
} }
...@@ -299,6 +301,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, ...@@ -299,6 +301,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
aggref->args = fargs; aggref->args = fargs;
aggref->aggstar = agg_star; aggref->aggstar = agg_star;
aggref->aggdistinct = agg_distinct; aggref->aggdistinct = agg_distinct;
aggref->location = location;
/* /*
* Reject attempt to call a parameterless aggregate without (*) * Reject attempt to call a parameterless aggregate without (*)
...@@ -1009,7 +1012,8 @@ make_fn_arguments(ParseState *pstate, ...@@ -1009,7 +1012,8 @@ make_fn_arguments(ParseState *pstate,
actual_arg_types[i], actual_arg_types[i],
declared_arg_types[i], -1, declared_arg_types[i], -1,
COERCION_IMPLICIT, COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
} }
i++; i++;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.101 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.102 2008/08/28 23:09:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -117,8 +117,9 @@ parser_errposition(ParseState *pstate, int location) ...@@ -117,8 +117,9 @@ parser_errposition(ParseState *pstate, int location)
* Build a Var node for an attribute identified by RTE and attrno * Build a Var node for an attribute identified by RTE and attrno
*/ */
Var * Var *
make_var(ParseState *pstate, RangeTblEntry *rte, int attrno) make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
{ {
Var *result;
int vnum, int vnum,
sublevels_up; sublevels_up;
Oid vartypeid; Oid vartypeid;
...@@ -126,7 +127,9 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno) ...@@ -126,7 +127,9 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno)
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up); vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod); get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod);
return makeVar(vnum, attrno, vartypeid, type_mod, sublevels_up); result = makeVar(vnum, attrno, vartypeid, type_mod, sublevels_up);
result->location = location;
return result;
} }
/* /*
...@@ -243,11 +246,13 @@ transformArraySubscripts(ParseState *pstate, ...@@ -243,11 +246,13 @@ transformArraySubscripts(ParseState *pstate,
subexpr, exprType(subexpr), subexpr, exprType(subexpr),
INT4OID, -1, INT4OID, -1,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (subexpr == NULL) if (subexpr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"))); errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->lidx))));
} }
else else
{ {
...@@ -267,11 +272,13 @@ transformArraySubscripts(ParseState *pstate, ...@@ -267,11 +272,13 @@ transformArraySubscripts(ParseState *pstate,
subexpr, exprType(subexpr), subexpr, exprType(subexpr),
INT4OID, -1, INT4OID, -1,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (subexpr == NULL) if (subexpr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"))); errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->uidx))));
upperIndexpr = lappend(upperIndexpr, subexpr); upperIndexpr = lappend(upperIndexpr, subexpr);
} }
...@@ -283,20 +290,24 @@ transformArraySubscripts(ParseState *pstate, ...@@ -283,20 +290,24 @@ transformArraySubscripts(ParseState *pstate,
{ {
Oid typesource = exprType(assignFrom); Oid typesource = exprType(assignFrom);
Oid typeneeded = isSlice ? arrayType : elementType; Oid typeneeded = isSlice ? arrayType : elementType;
Node *newFrom;
assignFrom = coerce_to_target_type(pstate, newFrom = coerce_to_target_type(pstate,
assignFrom, typesource, assignFrom, typesource,
typeneeded, elementTypMod, typeneeded, elementTypMod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
if (assignFrom == NULL) -1);
if (newFrom == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array assignment requires type %s" errmsg("array assignment requires type %s"
" but expression is of type %s", " but expression is of type %s",
format_type_be(typeneeded), format_type_be(typeneeded),
format_type_be(typesource)), format_type_be(typesource)),
errhint("You will need to rewrite or cast the expression."))); errhint("You will need to rewrite or cast the expression."),
parser_errposition(pstate, exprLocation(assignFrom))));
assignFrom = newFrom;
} }
/* /*
...@@ -333,7 +344,7 @@ transformArraySubscripts(ParseState *pstate, ...@@ -333,7 +344,7 @@ transformArraySubscripts(ParseState *pstate,
* too many examples that fail if we try. * too many examples that fail if we try.
*/ */
Const * Const *
make_const(Value *value) make_const(Value *value, int location)
{ {
Datum val; Datum val;
int64 val64; int64 val64;
...@@ -423,6 +434,7 @@ make_const(Value *value) ...@@ -423,6 +434,7 @@ make_const(Value *value)
(Datum) 0, (Datum) 0,
true, true,
false); false);
con->location = location;
return con; return con;
default: default:
...@@ -436,6 +448,7 @@ make_const(Value *value) ...@@ -436,6 +448,7 @@ make_const(Value *value)
val, val,
false, false,
typebyval); typebyval);
con->location = location;
return con; return con;
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.104 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.105 2008/08/28 23:09:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -857,6 +857,7 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, ...@@ -857,6 +857,7 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
result->opresulttype = rettype; result->opresulttype = rettype;
result->opretset = get_func_retset(opform->oprcode); result->opretset = get_func_retset(opform->oprcode);
result->args = args; result->args = args;
result->location = location;
ReleaseSysCache(tup); ReleaseSysCache(tup);
...@@ -984,6 +985,7 @@ make_scalar_array_op(ParseState *pstate, List *opname, ...@@ -984,6 +985,7 @@ make_scalar_array_op(ParseState *pstate, List *opname,
result->opfuncid = opform->oprcode; result->opfuncid = opform->oprcode;
result->useOr = useOr; result->useOr = useOr;
result->args = args; result->args = args;
result->location = location;
ReleaseSysCache(tup); ReleaseSysCache(tup);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.133 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.134 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -362,7 +362,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname, ...@@ -362,7 +362,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
errmsg("column reference \"%s\" is ambiguous", errmsg("column reference \"%s\" is ambiguous",
colname), colname),
parser_errposition(pstate, location))); parser_errposition(pstate, location)));
result = (Node *) make_var(pstate, rte, attnum); result = (Node *) make_var(pstate, rte, attnum, location);
/* Require read access */ /* Require read access */
rte->requiredPerms |= ACL_SELECT; rte->requiredPerms |= ACL_SELECT;
} }
...@@ -390,7 +390,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname, ...@@ -390,7 +390,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0)) 0, 0))
{ {
result = (Node *) make_var(pstate, rte, attnum); result = (Node *) make_var(pstate, rte, attnum, location);
/* Require read access */ /* Require read access */
rte->requiredPerms |= ACL_SELECT; rte->requiredPerms |= ACL_SELECT;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.161 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.162 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -318,7 +318,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle, ...@@ -318,7 +318,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
* colname target column name (ie, name of attribute to be assigned to) * colname target column name (ie, name of attribute to be assigned to)
* attrno target attribute number * attrno target attribute number
* indirection subscripts/field names for target column, if any * indirection subscripts/field names for target column, if any
* location error cursor position, or -1 * location error cursor position for the target column, or -1
* *
* Returns the modified expression. * Returns the modified expression.
*/ */
...@@ -403,7 +403,8 @@ transformAssignedExpr(ParseState *pstate, ...@@ -403,7 +403,8 @@ transformAssignedExpr(ParseState *pstate,
*/ */
colVar = (Node *) make_var(pstate, colVar = (Node *) make_var(pstate,
pstate->p_target_rangetblentry, pstate->p_target_rangetblentry,
attrno); attrno,
location);
} }
expr = (Expr *) expr = (Expr *)
...@@ -428,7 +429,8 @@ transformAssignedExpr(ParseState *pstate, ...@@ -428,7 +429,8 @@ transformAssignedExpr(ParseState *pstate,
(Node *) expr, type_id, (Node *) expr, type_id,
attrtype, attrtypmod, attrtype, attrtypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (expr == NULL) if (expr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
...@@ -677,7 +679,8 @@ transformAssignmentIndirection(ParseState *pstate, ...@@ -677,7 +679,8 @@ transformAssignmentIndirection(ParseState *pstate,
rhs, exprType(rhs), rhs, exprType(rhs),
targetTypeId, targetTypMod, targetTypeId, targetTypMod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (result == NULL) if (result == NULL)
{ {
if (targetIsArray) if (targetIsArray)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/parse_utilcmd.c,v 2.15 2008/08/25 22:42:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.16 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -380,9 +380,11 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, ...@@ -380,9 +380,11 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
snamenode = makeNode(A_Const); snamenode = makeNode(A_Const);
snamenode->val.type = T_String; snamenode->val.type = T_String;
snamenode->val.val.str = qstring; snamenode->val.val.str = qstring;
snamenode->location = -1;
castnode = makeNode(TypeCast); castnode = makeNode(TypeCast);
castnode->typename = SystemTypeName("regclass"); castnode->typename = SystemTypeName("regclass");
castnode->arg = (Node *) snamenode; castnode->arg = (Node *) snamenode;
castnode->location = -1;
funccallnode = makeNode(FuncCall); funccallnode = makeNode(FuncCall);
funccallnode->funcname = SystemFuncName("nextval"); funccallnode->funcname = SystemFuncName("nextval");
funccallnode->args = list_make1(castnode); funccallnode->args = list_make1(castnode);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,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/rewrite/rewriteHandler.c,v 1.178 2008/08/25 22:42:34 tgl Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.179 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -654,6 +654,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation, ...@@ -654,6 +654,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation,
InvalidOid, -1, InvalidOid, -1,
att_tup->atttypid, att_tup->atttypid,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,
-1,
false, false,
false); false);
} }
...@@ -886,7 +887,8 @@ build_column_default(Relation rel, int attrno) ...@@ -886,7 +887,8 @@ build_column_default(Relation rel, int attrno)
expr, exprtype, expr, exprtype,
atttype, atttypmod, atttype, atttypmod,
COERCION_ASSIGNMENT, COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST); COERCE_IMPLICIT_CAST,
-1);
if (expr == NULL) if (expr == NULL)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
...@@ -993,6 +995,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos) ...@@ -993,6 +995,7 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
InvalidOid, -1, InvalidOid, -1,
att_tup->atttypid, att_tup->atttypid,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,
-1,
false, false,
false); false);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.111 2008/08/25 22:42:34 tgl Exp $ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.112 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -933,6 +933,7 @@ resolve_one_var(Var *var, ResolveNew_context *context) ...@@ -933,6 +933,7 @@ resolve_one_var(Var *var, ResolveNew_context *context)
InvalidOid, -1, InvalidOid, -1,
var->vartype, var->vartype,
COERCE_IMPLICIT_CAST, COERCE_IMPLICIT_CAST,
-1,
false, false,
false); false);
} }
...@@ -989,6 +990,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context) ...@@ -989,6 +990,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
rowexpr->args = fields; rowexpr->args = fields;
rowexpr->row_typeid = var->vartype; rowexpr->row_typeid = var->vartype;
rowexpr->row_format = COERCE_IMPLICIT_CAST; rowexpr->row_format = COERCE_IMPLICIT_CAST;
rowexpr->location = -1;
return (Node *) rowexpr; return (Node *) rowexpr;
} }
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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.480 2008/08/25 11:18:43 mha Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.481 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200808251 #define CATALOG_VERSION_NO 200808281
#endif #endif
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/makefuncs.h,v 1.61 2008/01/01 19:45:58 momjian Exp $ * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.62 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -49,7 +49,7 @@ extern Const *makeNullConst(Oid consttype, int32 consttypmod); ...@@ -49,7 +49,7 @@ extern Const *makeNullConst(Oid consttype, int32 consttypmod);
extern Node *makeBoolConst(bool value, bool isnull); extern Node *makeBoolConst(bool value, bool isnull);
extern Expr *makeBoolExpr(BoolExprType boolop, List *args); extern Expr *makeBoolExpr(BoolExprType boolop, List *args, int location);
extern Alias *makeAlias(const char *aliasname, List *colnames); extern Alias *makeAlias(const char *aliasname, List *colnames);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/nodeFuncs.h,v 1.27 2008/08/25 22:42:34 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/nodeFuncs.h,v 1.28 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -27,6 +27,8 @@ extern int32 exprTypmod(Node *expr); ...@@ -27,6 +27,8 @@ extern int32 exprTypmod(Node *expr);
extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod); extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod);
extern bool expression_returns_set(Node *clause); extern bool expression_returns_set(Node *clause);
extern int exprLocation(Node *expr);
extern bool expression_tree_walker(Node *node, bool (*walker) (), extern bool expression_tree_walker(Node *node, bool (*walker) (),
void *context); void *context);
extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (), extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (),
......
...@@ -3,11 +3,17 @@ ...@@ -3,11 +3,17 @@
* parsenodes.h * parsenodes.h
* definitions for parse tree nodes * definitions for parse tree nodes
* *
* Many of the node types used in parsetrees include a "location" field.
* This is a byte (not character) offset in the original source text, to be
* used for positioning an error cursor when there is an error related to
* the node. Access to the original source text is needed to make use of
* the location.
*
* *
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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.371 2008/08/07 01:11:51 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.372 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -141,11 +147,6 @@ typedef struct Query ...@@ -141,11 +147,6 @@ typedef struct Query
* Most of these node types appear in raw parsetrees output by the grammar, * Most of these node types appear in raw parsetrees output by the grammar,
* and get transformed to something else by the analyzer. A few of them * and get transformed to something else by the analyzer. A few of them
* are used as-is in transformed querytrees. * are used as-is in transformed querytrees.
*
* Many of the node types used in raw parsetrees include a "location" field.
* This is a byte (not character) offset in the original source text, to be
* used for positioning an error cursor when there is an analysis-time
* error related to the node.
****************************************************************************/ ****************************************************************************/
/* /*
...@@ -199,6 +200,7 @@ typedef struct ParamRef ...@@ -199,6 +200,7 @@ typedef struct ParamRef
{ {
NodeTag type; NodeTag type;
int number; /* the number of the parameter */ int number; /* the number of the parameter */
int location; /* token location, or -1 if unknown */
} ParamRef; } ParamRef;
/* /*
...@@ -235,6 +237,7 @@ typedef struct A_Const ...@@ -235,6 +237,7 @@ typedef struct A_Const
{ {
NodeTag type; NodeTag type;
Value val; /* value (includes type info, see value.h) */ Value val; /* value (includes type info, see value.h) */
int location; /* token location, or -1 if unknown */
} A_Const; } A_Const;
/* /*
...@@ -245,6 +248,7 @@ typedef struct TypeCast ...@@ -245,6 +248,7 @@ typedef struct TypeCast
NodeTag type; NodeTag type;
Node *arg; /* the expression being casted */ Node *arg; /* the expression being casted */
TypeName *typename; /* the target type */ TypeName *typename; /* the target type */
int location; /* token location, or -1 if unknown */
} TypeCast; } TypeCast;
/* /*
...@@ -305,6 +309,7 @@ typedef struct A_ArrayExpr ...@@ -305,6 +309,7 @@ typedef struct A_ArrayExpr
{ {
NodeTag type; NodeTag type;
List *elements; /* array element expressions */ List *elements; /* array element expressions */
int location; /* token location, or -1 if unknown */
} A_ArrayExpr; } A_ArrayExpr;
/* /*
...@@ -459,14 +464,15 @@ typedef struct LockingClause ...@@ -459,14 +464,15 @@ typedef struct LockingClause
} LockingClause; } LockingClause;
/* /*
* XMLSERIALIZE * XMLSERIALIZE (in raw parse tree only)
*/ */
typedef struct XmlSerialize typedef struct XmlSerialize
{ {
NodeTag type; NodeTag type;
XmlOptionType xmloption; XmlOptionType xmloption; /* DOCUMENT or CONTENT */
Node *expr; Node *expr;
TypeName *typename; TypeName *typename;
int location; /* token location, or -1 if unknown */
} XmlSerialize; } XmlSerialize;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/primnodes.h,v 1.139 2008/08/22 00:16:04 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.140 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -138,14 +138,12 @@ typedef struct Var ...@@ -138,14 +138,12 @@ typedef struct Var
* all */ * all */
Oid vartype; /* pg_type OID for the type of this var */ Oid vartype; /* pg_type OID for the type of this var */
int32 vartypmod; /* pg_attribute typmod value */ int32 vartypmod; /* pg_attribute typmod value */
Index varlevelsup; Index varlevelsup; /* for subquery variables referencing outer
* relations; 0 in a normal var, >0 means N
/* * levels up */
* for subquery variables referencing outer relations; 0 in a normal var,
* >0 means N levels up
*/
Index varnoold; /* original value of varno, for debugging */ Index varnoold; /* original value of varno, for debugging */
AttrNumber varoattno; /* original value of varattno */ AttrNumber varoattno; /* original value of varattno */
int location; /* token location, or -1 if unknown */
} Var; } Var;
/* /*
...@@ -164,6 +162,7 @@ typedef struct Const ...@@ -164,6 +162,7 @@ typedef struct Const
* If true, then all the information is stored * If true, then all the information is stored
* in the Datum. If false, then the Datum * in the Datum. If false, then the Datum
* contains a pointer to the information. */ * contains a pointer to the information. */
int location; /* token location, or -1 if unknown */
} Const; } Const;
/* ---------------- /* ----------------
...@@ -204,6 +203,7 @@ typedef struct Param ...@@ -204,6 +203,7 @@ typedef struct Param
int paramid; /* numeric ID for parameter */ int paramid; /* numeric ID for parameter */
Oid paramtype; /* pg_type OID of parameter's datatype */ Oid paramtype; /* pg_type OID of parameter's datatype */
int32 paramtypmod; /* typmod value, if known */ int32 paramtypmod; /* typmod value, if known */
int location; /* token location, or -1 if unknown */
} Param; } Param;
/* /*
...@@ -218,6 +218,7 @@ typedef struct Aggref ...@@ -218,6 +218,7 @@ typedef struct Aggref
Index agglevelsup; /* > 0 if agg belongs to outer query */ Index agglevelsup; /* > 0 if agg belongs to outer query */
bool aggstar; /* TRUE if argument list was really '*' */ bool aggstar; /* TRUE if argument list was really '*' */
bool aggdistinct; /* TRUE if it's agg(DISTINCT ...) */ bool aggdistinct; /* TRUE if it's agg(DISTINCT ...) */
int location; /* token location, or -1 if unknown */
} Aggref; } Aggref;
/* ---------------- /* ----------------
...@@ -293,6 +294,7 @@ typedef struct FuncExpr ...@@ -293,6 +294,7 @@ typedef struct FuncExpr
bool funcretset; /* true if function returns set */ bool funcretset; /* true if function returns set */
CoercionForm funcformat; /* how to display this function call */ CoercionForm funcformat; /* how to display this function call */
List *args; /* arguments to the function */ List *args; /* arguments to the function */
int location; /* token location, or -1 if unknown */
} FuncExpr; } FuncExpr;
/* /*
...@@ -312,6 +314,7 @@ typedef struct OpExpr ...@@ -312,6 +314,7 @@ typedef struct OpExpr
Oid opresulttype; /* PG_TYPE OID of result value */ Oid opresulttype; /* PG_TYPE OID of result value */
bool opretset; /* true if operator returns set */ bool opretset; /* true if operator returns set */
List *args; /* arguments to the operator (1 or 2) */ List *args; /* arguments to the operator (1 or 2) */
int location; /* token location, or -1 if unknown */
} OpExpr; } OpExpr;
/* /*
...@@ -343,6 +346,7 @@ typedef struct ScalarArrayOpExpr ...@@ -343,6 +346,7 @@ typedef struct ScalarArrayOpExpr
Oid opfuncid; /* PG_PROC OID of underlying function */ Oid opfuncid; /* PG_PROC OID of underlying function */
bool useOr; /* true for ANY, false for ALL */ bool useOr; /* true for ANY, false for ALL */
List *args; /* the scalar and array operands */ List *args; /* the scalar and array operands */
int location; /* token location, or -1 if unknown */
} ScalarArrayOpExpr; } ScalarArrayOpExpr;
/* /*
...@@ -350,9 +354,11 @@ typedef struct ScalarArrayOpExpr ...@@ -350,9 +354,11 @@ typedef struct ScalarArrayOpExpr
* *
* Notice the arguments are given as a List. For NOT, of course the list * Notice the arguments are given as a List. For NOT, of course the list
* must always have exactly one element. For AND and OR, the executor can * must always have exactly one element. For AND and OR, the executor can
* handle any number of arguments. The parser treats AND and OR as binary * handle any number of arguments. The parser generally treats AND and OR
* and so it only produces two-element lists, but the optimizer will flatten * as binary and so it typically only produces two-element lists, but the
* trees of AND and OR nodes to produce longer lists when possible. * optimizer will flatten trees of AND and OR nodes to produce longer lists
* when possible. There are also a few special cases where more arguments
* can appear before optimization.
*/ */
typedef enum BoolExprType typedef enum BoolExprType
{ {
...@@ -364,6 +370,7 @@ typedef struct BoolExpr ...@@ -364,6 +370,7 @@ typedef struct BoolExpr
Expr xpr; Expr xpr;
BoolExprType boolop; BoolExprType boolop;
List *args; /* arguments to this expression */ List *args; /* arguments to this expression */
int location; /* token location, or -1 if unknown */
} BoolExpr; } BoolExpr;
/* /*
...@@ -423,6 +430,7 @@ typedef struct SubLink ...@@ -423,6 +430,7 @@ typedef struct SubLink
Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */ Node *testexpr; /* outer-query test for ALL/ANY/ROWCOMPARE */
List *operName; /* originally specified operator name */ List *operName; /* originally specified operator name */
Node *subselect; /* subselect as Query* or parsetree */ Node *subselect; /* subselect as Query* or parsetree */
int location; /* token location, or -1 if unknown */
} SubLink; } SubLink;
/* /*
...@@ -570,6 +578,7 @@ typedef struct RelabelType ...@@ -570,6 +578,7 @@ typedef struct RelabelType
Oid resulttype; /* output type of coercion expression */ Oid resulttype; /* output type of coercion expression */
int32 resulttypmod; /* output typmod (usually -1) */ int32 resulttypmod; /* output typmod (usually -1) */
CoercionForm relabelformat; /* how to display this node */ CoercionForm relabelformat; /* how to display this node */
int location; /* token location, or -1 if unknown */
} RelabelType; } RelabelType;
/* ---------------- /* ----------------
...@@ -588,6 +597,7 @@ typedef struct CoerceViaIO ...@@ -588,6 +597,7 @@ typedef struct CoerceViaIO
Oid resulttype; /* output type of coercion */ Oid resulttype; /* output type of coercion */
/* output typmod is not stored, but is presumed -1 */ /* output typmod is not stored, but is presumed -1 */
CoercionForm coerceformat; /* how to display this node */ CoercionForm coerceformat; /* how to display this node */
int location; /* token location, or -1 if unknown */
} CoerceViaIO; } CoerceViaIO;
/* ---------------- /* ----------------
...@@ -611,6 +621,7 @@ typedef struct ArrayCoerceExpr ...@@ -611,6 +621,7 @@ typedef struct ArrayCoerceExpr
int32 resulttypmod; /* output typmod (also element typmod) */ int32 resulttypmod; /* output typmod (also element typmod) */
bool isExplicit; /* conversion semantics flag to pass to func */ bool isExplicit; /* conversion semantics flag to pass to func */
CoercionForm coerceformat; /* how to display this node */ CoercionForm coerceformat; /* how to display this node */
int location; /* token location, or -1 if unknown */
} ArrayCoerceExpr; } ArrayCoerceExpr;
/* ---------------- /* ----------------
...@@ -632,6 +643,7 @@ typedef struct ConvertRowtypeExpr ...@@ -632,6 +643,7 @@ typedef struct ConvertRowtypeExpr
Oid resulttype; /* output type (always a composite type) */ Oid resulttype; /* output type (always a composite type) */
/* result typmod is not stored, but must be -1; see RowExpr comments */ /* result typmod is not stored, but must be -1; see RowExpr comments */
CoercionForm convertformat; /* how to display this node */ CoercionForm convertformat; /* how to display this node */
int location; /* token location, or -1 if unknown */
} ConvertRowtypeExpr; } ConvertRowtypeExpr;
/*---------- /*----------
...@@ -663,6 +675,7 @@ typedef struct CaseExpr ...@@ -663,6 +675,7 @@ typedef struct CaseExpr
Expr *arg; /* implicit equality comparison argument */ Expr *arg; /* implicit equality comparison argument */
List *args; /* the arguments (list of WHEN clauses) */ List *args; /* the arguments (list of WHEN clauses) */
Expr *defresult; /* the default result (ELSE clause) */ Expr *defresult; /* the default result (ELSE clause) */
int location; /* token location, or -1 if unknown */
} CaseExpr; } CaseExpr;
/* /*
...@@ -673,6 +686,7 @@ typedef struct CaseWhen ...@@ -673,6 +686,7 @@ typedef struct CaseWhen
Expr xpr; Expr xpr;
Expr *expr; /* condition expression */ Expr *expr; /* condition expression */
Expr *result; /* substitution result */ Expr *result; /* substitution result */
int location; /* token location, or -1 if unknown */
} CaseWhen; } CaseWhen;
/* /*
...@@ -705,6 +719,7 @@ typedef struct ArrayExpr ...@@ -705,6 +719,7 @@ typedef struct ArrayExpr
Oid element_typeid; /* common type of array elements */ Oid element_typeid; /* common type of array elements */
List *elements; /* the array elements or sub-arrays */ List *elements; /* the array elements or sub-arrays */
bool multidims; /* true if elements are sub-arrays */ bool multidims; /* true if elements are sub-arrays */
int location; /* token location, or -1 if unknown */
} ArrayExpr; } ArrayExpr;
/* /*
...@@ -733,6 +748,7 @@ typedef struct RowExpr ...@@ -733,6 +748,7 @@ typedef struct RowExpr
* parsetrees. We must assume typmod -1 for a RowExpr node. * parsetrees. We must assume typmod -1 for a RowExpr node.
*/ */
CoercionForm row_format; /* how to display this node */ CoercionForm row_format; /* how to display this node */
int location; /* token location, or -1 if unknown */
} RowExpr; } RowExpr;
/* /*
...@@ -778,6 +794,7 @@ typedef struct CoalesceExpr ...@@ -778,6 +794,7 @@ typedef struct CoalesceExpr
Expr xpr; Expr xpr;
Oid coalescetype; /* type of expression result */ Oid coalescetype; /* type of expression result */
List *args; /* the arguments */ List *args; /* the arguments */
int location; /* token location, or -1 if unknown */
} CoalesceExpr; } CoalesceExpr;
/* /*
...@@ -795,6 +812,7 @@ typedef struct MinMaxExpr ...@@ -795,6 +812,7 @@ typedef struct MinMaxExpr
Oid minmaxtype; /* common type of arguments and result */ Oid minmaxtype; /* common type of arguments and result */
MinMaxOp op; /* function to execute */ MinMaxOp op; /* function to execute */
List *args; /* the arguments */ List *args; /* the arguments */
int location; /* token location, or -1 if unknown */
} MinMaxExpr; } MinMaxExpr;
/* /*
...@@ -833,6 +851,7 @@ typedef struct XmlExpr ...@@ -833,6 +851,7 @@ typedef struct XmlExpr
XmlOptionType xmloption; /* DOCUMENT or CONTENT */ XmlOptionType xmloption; /* DOCUMENT or CONTENT */
Oid type; /* target type for XMLSERIALIZE */ Oid type; /* target type for XMLSERIALIZE */
int32 typmod; int32 typmod;
int location; /* token location, or -1 if unknown */
} XmlExpr; } XmlExpr;
/* /*
...@@ -905,6 +924,7 @@ typedef struct CoerceToDomain ...@@ -905,6 +924,7 @@ typedef struct CoerceToDomain
Oid resulttype; /* domain type ID (result type) */ Oid resulttype; /* domain type ID (result type) */
int32 resulttypmod; /* output typmod (currently always -1) */ int32 resulttypmod; /* output typmod (currently always -1) */
CoercionForm coercionformat; /* how to display this node */ CoercionForm coercionformat; /* how to display this node */
int location; /* token location, or -1 if unknown */
} CoerceToDomain; } CoerceToDomain;
/* /*
...@@ -921,6 +941,7 @@ typedef struct CoerceToDomainValue ...@@ -921,6 +941,7 @@ typedef struct CoerceToDomainValue
Expr xpr; Expr xpr;
Oid typeId; /* type for substituted value */ Oid typeId; /* type for substituted value */
int32 typeMod; /* typemod for substituted value */ int32 typeMod; /* typemod for substituted value */
int location; /* token location, or -1 if unknown */
} CoerceToDomainValue; } CoerceToDomainValue;
/* /*
...@@ -935,6 +956,7 @@ typedef struct SetToDefault ...@@ -935,6 +956,7 @@ typedef struct SetToDefault
Expr xpr; Expr xpr;
Oid typeId; /* type for substituted value */ Oid typeId; /* type for substituted value */
int32 typeMod; /* typemod for substituted value */ int32 typeMod; /* typemod for substituted value */
int location; /* token location, or -1 if unknown */
} SetToDefault; } SetToDefault;
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/parser/parse_coerce.h,v 1.76 2008/07/30 17:05:05 tgl Exp $ * $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.77 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -39,15 +39,17 @@ extern Node *coerce_to_target_type(ParseState *pstate, ...@@ -39,15 +39,17 @@ extern Node *coerce_to_target_type(ParseState *pstate,
Node *expr, Oid exprtype, Node *expr, Oid exprtype,
Oid targettype, int32 targettypmod, Oid targettype, int32 targettypmod,
CoercionContext ccontext, CoercionContext ccontext,
CoercionForm cformat); CoercionForm cformat,
int location);
extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids, extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
CoercionContext ccontext); CoercionContext ccontext);
extern Node *coerce_type(ParseState *pstate, Node *node, extern Node *coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
CoercionContext ccontext, CoercionForm cformat); CoercionContext ccontext, CoercionForm cformat, int location);
extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
Oid typeId, Oid typeId,
CoercionForm cformat, bool hideInputCoercion, CoercionForm cformat, int location,
bool hideInputCoercion,
bool lengthCoercionDone); bool lengthCoercionDone);
extern Node *coerce_to_boolean(ParseState *pstate, Node *node, extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
...@@ -56,7 +58,12 @@ extern Node *coerce_to_specific_type(ParseState *pstate, Node *node, ...@@ -56,7 +58,12 @@ extern Node *coerce_to_specific_type(ParseState *pstate, Node *node,
Oid targetTypeId, Oid targetTypeId,
const char *constructName); const char *constructName);
extern Oid select_common_type(List *typeids, const char *context); extern int parser_coercion_errposition(ParseState *pstate,
int coerce_location,
Node *input_expr);
extern Oid select_common_type(ParseState *pstate, List *exprs,
const char *context, Node **which_expr);
extern Node *coerce_to_common_type(ParseState *pstate, Node *node, extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
Oid targetTypeId, Oid targetTypeId,
const char *context); const char *context);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, 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/parser/parse_node.h,v 1.54 2008/06/19 00:46:06 alvherre Exp $ * $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.55 2008/08/28 23:09:48 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -86,7 +86,8 @@ extern ParseState *make_parsestate(ParseState *parentParseState); ...@@ -86,7 +86,8 @@ extern ParseState *make_parsestate(ParseState *parentParseState);
extern void free_parsestate(ParseState *pstate); extern void free_parsestate(ParseState *pstate);
extern int parser_errposition(ParseState *pstate, int location); extern int parser_errposition(ParseState *pstate, int location);
extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno); extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno,
int location);
extern Oid transformArrayType(Oid arrayType); extern Oid transformArrayType(Oid arrayType);
extern ArrayRef *transformArraySubscripts(ParseState *pstate, extern ArrayRef *transformArraySubscripts(ParseState *pstate,
Node *arrayBase, Node *arrayBase,
...@@ -95,6 +96,6 @@ extern ArrayRef *transformArraySubscripts(ParseState *pstate, ...@@ -95,6 +96,6 @@ extern ArrayRef *transformArraySubscripts(ParseState *pstate,
int32 elementTypMod, int32 elementTypMod,
List *indirection, List *indirection,
Node *assignFrom); Node *assignFrom);
extern Const *make_const(Value *value); extern Const *make_const(Value *value, int location);
#endif /* PARSE_NODE_H */ #endif /* PARSE_NODE_H */
...@@ -787,6 +787,8 @@ select '{ }}'::text[]; ...@@ -787,6 +787,8 @@ select '{ }}'::text[];
ERROR: malformed array literal: "{ }}" ERROR: malformed array literal: "{ }}"
select array[]; select array[];
ERROR: cannot determine type of empty array ERROR: cannot determine type of empty array
LINE 1: select array[];
^
HINT: Explicitly cast to the desired type, for example ARRAY[]::integer[]. HINT: Explicitly cast to the desired type, for example ARRAY[]::integer[].
-- none of the above should be accepted -- none of the above should be accepted
-- all of the following should be accepted -- all of the following should be accepted
......
...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1; ...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1;
-- failure expected -- failure expected
SELECT c, count(*) FROM test_missing_target GROUP BY 3; SELECT c, count(*) FROM test_missing_target GROUP BY 3;
ERROR: GROUP BY position 3 is not in select list ERROR: GROUP BY position 3 is not in select list
LINE 1: SELECT c, count(*) FROM test_missing_target GROUP BY 3;
^
-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition -- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
-- failure expected -- failure expected
SELECT count(*) FROM test_missing_target x, test_missing_target y SELECT count(*) FROM test_missing_target x, test_missing_target y
......
...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1; ...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1;
-- failure expected -- failure expected
SELECT c, count(*) FROM test_missing_target GROUP BY 3; SELECT c, count(*) FROM test_missing_target GROUP BY 3;
ERROR: GROUP BY position 3 is not in select list ERROR: GROUP BY position 3 is not in select list
LINE 1: SELECT c, count(*) FROM test_missing_target GROUP BY 3;
^
-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition -- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
-- failure expected -- failure expected
SELECT count(*) FROM test_missing_target x, test_missing_target y SELECT count(*) FROM test_missing_target x, test_missing_target y
......
...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1; ...@@ -115,6 +115,8 @@ SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1;
-- failure expected -- failure expected
SELECT c, count(*) FROM test_missing_target GROUP BY 3; SELECT c, count(*) FROM test_missing_target GROUP BY 3;
ERROR: GROUP BY position 3 is not in select list ERROR: GROUP BY position 3 is not in select list
LINE 1: SELECT c, count(*) FROM test_missing_target GROUP BY 3;
^
-- group w/o existing GROUP BY and ORDER BY target under ambiguous condition -- group w/o existing GROUP BY and ORDER BY target under ambiguous condition
-- failure expected -- failure expected
SELECT count(*) FROM test_missing_target x, test_missing_target y SELECT count(*) FROM test_missing_target x, test_missing_target y
......
...@@ -54,6 +54,8 @@ SELECT xmlconcat('hello', 'you'); ...@@ -54,6 +54,8 @@ SELECT xmlconcat('hello', 'you');
SELECT xmlconcat(1, 2); SELECT xmlconcat(1, 2);
ERROR: argument of XMLCONCAT must be type xml, not type integer ERROR: argument of XMLCONCAT must be type xml, not type integer
LINE 1: SELECT xmlconcat(1, 2);
^
SELECT xmlconcat('bad', '<syntax'); SELECT xmlconcat('bad', '<syntax');
ERROR: invalid XML content ERROR: invalid XML content
DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax line 1 DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax line 1
...@@ -82,6 +84,8 @@ SELECT xmlelement(name element, ...@@ -82,6 +84,8 @@ SELECT xmlelement(name element,
SELECT xmlelement(name element, SELECT xmlelement(name element,
xmlattributes ('unnamed and wrong')); xmlattributes ('unnamed and wrong'));
ERROR: unnamed XML attribute value must be a column reference ERROR: unnamed XML attribute value must be a column reference
LINE 2: xmlattributes ('unnamed and wrong'));
^
SELECT xmlelement(name element, xmlelement(name nested, 'stuff')); SELECT xmlelement(name element, xmlelement(name nested, 'stuff'));
xmlelement xmlelement
------------------------------------------- -------------------------------------------
...@@ -101,6 +105,8 @@ SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; ...@@ -101,6 +105,8 @@ SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp;
SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)); SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a));
ERROR: XML attribute name "a" appears more than once ERROR: XML attribute name "a" appears more than once
LINE 1: ...ment(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a));
^
SELECT xmlelement(name num, 37); SELECT xmlelement(name num, 37);
xmlelement xmlelement
--------------- ---------------
......
...@@ -51,6 +51,8 @@ DETAIL: This functionality requires the server to be built with libxml support. ...@@ -51,6 +51,8 @@ DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml. HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlconcat(1, 2); SELECT xmlconcat(1, 2);
ERROR: argument of XMLCONCAT must be type xml, not type integer ERROR: argument of XMLCONCAT must be type xml, not type integer
LINE 1: SELECT xmlconcat(1, 2);
^
SELECT xmlconcat('bad', '<syntax'); SELECT xmlconcat('bad', '<syntax');
ERROR: unsupported XML feature ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support. DETAIL: This functionality requires the server to be built with libxml support.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment