aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/tupdesc.c4
-rw-r--r--src/backend/catalog/pg_aggregate.c6
-rw-r--r--src/backend/catalog/pg_operator.c7
-rw-r--r--src/backend/commands/aggregatecmds.c12
-rw-r--r--src/backend/commands/comment.c32
-rw-r--r--src/backend/commands/define.c13
-rw-r--r--src/backend/commands/functioncmds.c50
-rw-r--r--src/backend/commands/opclasscmds.c18
-rw-r--r--src/backend/commands/operatorcmds.c16
-rw-r--r--src/backend/commands/schemacmds.c4
-rw-r--r--src/backend/commands/sequence.c31
-rw-r--r--src/backend/commands/tablecmds.c33
-rw-r--r--src/backend/commands/typecmds.c151
-rw-r--r--src/backend/commands/view.c10
-rw-r--r--src/backend/executor/spi.c4
-rw-r--r--src/backend/nodes/copyfuncs.c6
-rw-r--r--src/backend/nodes/equalfuncs.c6
-rw-r--r--src/backend/nodes/makefuncs.c44
-rw-r--r--src/backend/nodes/outfuncs.c6
-rw-r--r--src/backend/nodes/readfuncs.c4
-rw-r--r--src/backend/optimizer/plan/initsplan.c7
-rw-r--r--src/backend/optimizer/util/clauses.c4
-rw-r--r--src/backend/parser/analyze.c26
-rw-r--r--src/backend/parser/gram.y221
-rw-r--r--src/backend/parser/parse_clause.c14
-rw-r--r--src/backend/parser/parse_expr.c162
-rw-r--r--src/backend/parser/parse_func.c62
-rw-r--r--src/backend/parser/parse_node.c37
-rw-r--r--src/backend/parser/parse_oper.c111
-rw-r--r--src/backend/parser/parse_relation.c46
-rw-r--r--src/backend/parser/parse_target.c12
-rw-r--r--src/backend/parser/parse_type.c38
-rw-r--r--src/backend/parser/scan.l103
-rw-r--r--src/backend/tcop/postgres.c13
-rw-r--r--src/backend/utils/adt/ruleutils.c13
35 files changed, 742 insertions, 584 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 4c40ef3c119..8726797524b 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.114 2006/03/05 15:58:20 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.115 2006/03/14 22:48:18 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -499,7 +499,7 @@ BuildDescForRelation(List *schema)
attname)));
TupleDescInitEntry(desc, attnum, attname,
- typenameTypeId(entry->typename),
+ typenameTypeId(NULL, entry->typename),
atttypmod, attdim);
/* Fill in additional stuff not handled by TupleDescInitEntry */
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 054c531a9e7..2f40eca1152 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.78 2006/03/05 15:58:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.79 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -171,9 +171,9 @@ AggregateCreate(const char *aggName,
/* handle sortop, if supplied */
if (aggsortopName)
- sortop = LookupOperName(aggsortopName,
+ sortop = LookupOperName(NULL, aggsortopName,
aggBaseType, aggBaseType,
- false);
+ false, -1);
/*
* Everything looks okay. Try to create the pg_proc entry for the
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index c9c19e4ec32..c51c841800e 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.95 2006/03/05 15:58:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.96 2006/03/14 22:48:18 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -175,8 +175,9 @@ OperatorLookup(List *operatorName,
Oid operatorObjectId;
RegProcedure oprcode;
- operatorObjectId = LookupOperName(operatorName, leftObjectId,
- rightObjectId, true);
+ operatorObjectId = LookupOperName(NULL, operatorName,
+ leftObjectId, rightObjectId,
+ true, -1);
if (!OidIsValid(operatorObjectId))
{
*defined = false;
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 99c7d531f91..3c0855238e2 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.32 2006/03/05 15:58:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.33 2006/03/14 22:48:18 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -129,9 +129,9 @@ DefineAggregate(List *names, List *parameters)
if (pg_strcasecmp(TypeNameToString(baseType), "ANY") == 0)
baseTypeId = ANYOID;
else
- baseTypeId = typenameTypeId(baseType);
+ baseTypeId = typenameTypeId(NULL, baseType);
- transTypeId = typenameTypeId(transType);
+ transTypeId = typenameTypeId(NULL, transType);
if (get_typtype(transTypeId) == 'p' &&
transTypeId != ANYARRAYOID &&
transTypeId != ANYELEMENTOID)
@@ -176,7 +176,7 @@ RemoveAggregate(RemoveAggrStmt *stmt)
* that the aggregate is to apply to all basetypes (eg, COUNT).
*/
if (aggType)
- basetypeID = typenameTypeId(aggType);
+ basetypeID = typenameTypeId(NULL, aggType);
else
basetypeID = ANYOID;
@@ -231,7 +231,7 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname)
* COUNT).
*/
if (basetype)
- basetypeOid = typenameTypeId(basetype);
+ basetypeOid = typenameTypeId(NULL, basetype);
else
basetypeOid = ANYOID;
@@ -311,7 +311,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
* COUNT).
*/
if (basetype)
- basetypeOid = typenameTypeId(basetype);
+ basetypeOid = typenameTypeId(NULL, basetype);
else
basetypeOid = ANYOID;
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 8f85dcb8d94..07d82785254 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -7,7 +7,7 @@
* Copyright (c) 1996-2006, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.87 2006/03/05 15:58:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.88 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -39,6 +39,7 @@
#include "commands/dbcommands.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
+#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_type.h"
@@ -846,13 +847,11 @@ CommentType(List *typename, char *comment)
Oid oid;
/* XXX a bit of a crock; should accept TypeName in COMMENT syntax */
- tname = makeNode(TypeName);
- tname->names = typename;
- tname->typmod = -1;
+ tname = makeTypeNameFromNameList(typename);
/* Find the type's oid */
- oid = typenameTypeId(tname);
+ oid = typenameTypeId(NULL, tname);
/* Check object security */
@@ -881,7 +880,7 @@ CommentAggregate(List *aggregate, List *arguments, char *comment)
/* First, attempt to determine the base aggregate oid */
if (aggtype)
- baseoid = typenameTypeId(aggtype);
+ baseoid = typenameTypeId(NULL, aggtype);
else
baseoid = ANYOID;
@@ -945,9 +944,11 @@ CommentOperator(List *opername, List *arguments, char *comment)
Oid oid;
/* Look up the operator */
- oid = LookupOperNameTypeNames(opername, typenode1, typenode2, false);
+ oid = LookupOperNameTypeNames(NULL, opername,
+ typenode1, typenode2,
+ false, -1);
- /* Valid user's ability to comment on this operator */
+ /* Check user's privilege to comment on this operator */
if (!pg_oper_ownercheck(oid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
NameListToString(opername));
@@ -1352,19 +1353,8 @@ CommentCast(List *qualname, List *arguments, char *comment)
targettype = (TypeName *) linitial(arguments);
Assert(IsA(targettype, TypeName));
- sourcetypeid = typenameTypeId(sourcetype);
- if (!OidIsValid(sourcetypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("source data type %s does not exist",
- TypeNameToString(sourcetype))));
-
- targettypeid = typenameTypeId(targettype);
- if (!OidIsValid(targettypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("target data type %s does not exist",
- TypeNameToString(targettype))));
+ sourcetypeid = typenameTypeId(NULL, sourcetype);
+ targettypeid = typenameTypeId(NULL, targettype);
tuple = SearchSysCache(CASTSOURCETARGET,
ObjectIdGetDatum(sourcetypeid),
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index 15ee606c8de..98cded67cc4 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.94 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.95 2006/03/14 22:48:18 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -37,6 +37,7 @@
#include "catalog/namespace.h"
#include "commands/defrem.h"
+#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "parser/scansup.h"
#include "utils/int8.h"
@@ -219,14 +220,8 @@ defGetTypeName(DefElem *def)
case T_TypeName:
return (TypeName *) def->arg;
case T_String:
- {
- /* Allow quoted typename for backwards compatibility */
- TypeName *n = makeNode(TypeName);
-
- n->names = list_make1(def->arg);
- n->typmod = -1;
- return n;
- }
+ /* Allow quoted typename for backwards compatibility */
+ return makeTypeNameFromNameList(list_make1(def->arg));
default:
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 4a78db5200a..1da1cf66cb3 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.72 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.73 2006/03/14 22:48:18 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -75,7 +75,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
{
Oid rettype;
- rettype = LookupTypeName(returnType);
+ rettype = LookupTypeName(NULL, returnType);
if (OidIsValid(rettype))
{
@@ -174,7 +174,7 @@ examine_parameter_list(List *parameters, Oid languageOid,
TypeName *t = fp->argType;
Oid toid;
- toid = LookupTypeName(t);
+ toid = LookupTypeName(NULL, t);
if (OidIsValid(toid))
{
if (!get_typisdefined(toid))
@@ -1152,33 +1152,10 @@ CreateCast(CreateCastStmt *stmt)
ObjectAddress myself,
referenced;
- sourcetypeid = LookupTypeName(stmt->sourcetype);
- if (!OidIsValid(sourcetypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("source data type %s does not exist",
- TypeNameToString(stmt->sourcetype))));
-
- targettypeid = LookupTypeName(stmt->targettype);
- if (!OidIsValid(targettypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("target data type %s does not exist",
- TypeNameToString(stmt->targettype))));
-
- /* No shells, no pseudo-types allowed */
- if (!get_typisdefined(sourcetypeid))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("source data type %s is only a shell",
- TypeNameToString(stmt->sourcetype))));
-
- if (!get_typisdefined(targettypeid))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("target data type %s is only a shell",
- TypeNameToString(stmt->targettype))));
+ sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
+ targettypeid = typenameTypeId(NULL, stmt->targettype);
+ /* No pseudo-types allowed */
if (get_typtype(sourcetypeid) == 'p')
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1400,19 +1377,8 @@ DropCast(DropCastStmt *stmt)
HeapTuple tuple;
ObjectAddress object;
- sourcetypeid = LookupTypeName(stmt->sourcetype);
- if (!OidIsValid(sourcetypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("source data type %s does not exist",
- TypeNameToString(stmt->sourcetype))));
-
- targettypeid = LookupTypeName(stmt->targettype);
- if (!OidIsValid(targettypeid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("target data type %s does not exist",
- TypeNameToString(stmt->targettype))));
+ sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
+ targettypeid = typenameTypeId(NULL, stmt->targettype);
tuple = SearchSysCache(CASTSOURCETARGET,
ObjectIdGetDatum(sourcetypeid),
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 7aa941262bf..d66c403e515 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.42 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.43 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -144,7 +144,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
errmsg("must be superuser to create an operator class")));
/* Look up the datatype */
- typeoid = typenameTypeId(stmt->datatype);
+ typeoid = typenameTypeId(NULL, stmt->datatype);
#ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */
@@ -185,16 +185,16 @@ DefineOpClass(CreateOpClassStmt *stmt)
TypeName *typeName1 = (TypeName *) linitial(item->args);
TypeName *typeName2 = (TypeName *) lsecond(item->args);
- operOid = LookupOperNameTypeNames(item->name,
- typeName1,
- typeName2,
- false);
+ operOid = LookupOperNameTypeNames(NULL, item->name,
+ typeName1, typeName2,
+ false, -1);
}
else
{
/* Default to binary op on input datatype */
- operOid = LookupOperName(item->name, typeoid, typeoid,
- false);
+ operOid = LookupOperName(NULL, item->name,
+ typeoid, typeoid,
+ false, -1);
}
#ifdef NOT_USED
@@ -246,7 +246,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("storage type specified more than once")));
- storageoid = typenameTypeId(item->storedtype);
+ storageoid = typenameTypeId(NULL, item->storedtype);
#ifdef NOT_USED
/* XXX this is unnecessary given the superuser check above */
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index e835aa94c1b..c40dbf9d821 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.28 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.29 2006/03/14 22:48:18 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -152,9 +152,9 @@ DefineOperator(List *names, List *parameters)
/* Transform type names to type OIDs */
if (typeName1)
- typeId1 = typenameTypeId(typeName1);
+ typeId1 = typenameTypeId(NULL, typeName1);
if (typeName2)
- typeId2 = typenameTypeId(typeName2);
+ typeId2 = typenameTypeId(NULL, typeName2);
/*
* If any of the mergejoin support operators were given, then canMerge is
@@ -210,8 +210,9 @@ RemoveOperator(RemoveOperStmt *stmt)
HeapTuple tup;
ObjectAddress object;
- operOid = LookupOperNameTypeNames(operatorName, typeName1, typeName2,
- false);
+ operOid = LookupOperNameTypeNames(NULL, operatorName,
+ typeName1, typeName2,
+ false, -1);
tup = SearchSysCache(OPEROID,
ObjectIdGetDatum(operOid),
@@ -286,8 +287,9 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
rel = heap_open(OperatorRelationId, RowExclusiveLock);
- operOid = LookupOperNameTypeNames(name, typeName1, typeName2,
- false);
+ operOid = LookupOperNameTypeNames(NULL, name,
+ typeName1, typeName2,
+ false, -1);
AlterOperatorOwner_internal(rel, operOid, newOwnerId);
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index c171d8bfdc3..73d532da4a5 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.39 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.40 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -121,7 +121,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
List *querytree_list;
ListCell *querytree_item;
- querytree_list = parse_analyze(parsetree, NULL, 0);
+ querytree_list = parse_analyze(parsetree, NULL, NULL, 0);
foreach(querytree_item, querytree_list)
{
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 2d6d1928639..5638f4fe9b7 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.128 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.129 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,7 @@
#include "commands/tablecmds.h"
#include "commands/sequence.h"
#include "miscadmin.h"
+#include "nodes/makefuncs.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/resowner.h"
@@ -112,16 +113,8 @@ DefineSequence(CreateSeqStmt *seq)
stmt->tableElts = NIL;
for (i = SEQ_COL_FIRSTCOL; i <= SEQ_COL_LASTCOL; i++)
{
- ColumnDef *coldef;
- TypeName *typnam;
+ ColumnDef *coldef = makeNode(ColumnDef);
- typnam = makeNode(TypeName);
- typnam->setof = FALSE;
- typnam->arrayBounds = NIL;
- typnam->typmod = -1;
-
- coldef = makeNode(ColumnDef);
- coldef->typename = typnam;
coldef->inhcount = 0;
coldef->is_local = true;
coldef->is_not_null = true;
@@ -135,48 +128,48 @@ DefineSequence(CreateSeqStmt *seq)
switch (i)
{
case SEQ_COL_NAME:
- typnam->typeid = NAMEOID;
+ coldef->typename = makeTypeNameFromOid(NAMEOID, -1);
coldef->colname = "sequence_name";
namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name);
break;
case SEQ_COL_LASTVAL:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "last_value";
value[i - 1] = Int64GetDatumFast(new.last_value);
break;
case SEQ_COL_INCBY:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "increment_by";
value[i - 1] = Int64GetDatumFast(new.increment_by);
break;
case SEQ_COL_MAXVALUE:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "max_value";
value[i - 1] = Int64GetDatumFast(new.max_value);
break;
case SEQ_COL_MINVALUE:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "min_value";
value[i - 1] = Int64GetDatumFast(new.min_value);
break;
case SEQ_COL_CACHE:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "cache_value";
value[i - 1] = Int64GetDatumFast(new.cache_value);
break;
case SEQ_COL_LOG:
- typnam->typeid = INT8OID;
+ coldef->typename = makeTypeNameFromOid(INT8OID, -1);
coldef->colname = "log_cnt";
value[i - 1] = Int64GetDatum((int64) 1);
break;
case SEQ_COL_CYCLE:
- typnam->typeid = BOOLOID;
+ coldef->typename = makeTypeNameFromOid(BOOLOID, -1);
coldef->colname = "is_cycled";
value[i - 1] = BoolGetDatum(new.is_cycled);
break;
case SEQ_COL_CALLED:
- typnam->typeid = BOOLOID;
+ coldef->typename = makeTypeNameFromOid(BOOLOID, -1);
coldef->colname = "is_called";
value[i - 1] = BoolGetDatum(false);
break;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c484c148c25..6483578e808 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.180 2006/03/05 15:58:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.181 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -867,7 +867,6 @@ MergeAttributes(List *schema, List *supers, bool istemp,
char *attributeName = NameStr(attribute->attname);
int exist_attno;
ColumnDef *def;
- TypeName *typename;
/*
* Ignore dropped columns in the parent.
@@ -897,7 +896,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging multiple inherited definitions of column \"%s\"",
attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
- if (typenameTypeId(def->typename) != attribute->atttypid ||
+ if (typenameTypeId(NULL, def->typename) != attribute->atttypid ||
def->typename->typmod != attribute->atttypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -919,10 +918,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
*/
def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName);
- typename = makeNode(TypeName);
- typename->typeid = attribute->atttypid;
- typename->typmod = attribute->atttypmod;
- def->typename = typename;
+ def->typename = makeTypeNameFromOid(attribute->atttypid,
+ attribute->atttypmod);
def->inhcount = 1;
def->is_local = false;
def->is_not_null = attribute->attnotnull;
@@ -1041,7 +1038,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
(errmsg("merging column \"%s\" with inherited definition",
attributeName)));
def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
- if (typenameTypeId(def->typename) != typenameTypeId(newdef->typename) ||
+ if (typenameTypeId(NULL, def->typename) != typenameTypeId(NULL, newdef->typename) ||
def->typename->typmod != newdef->typename->typmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -2955,7 +2952,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
/* Okay if child matches by type */
- if (typenameTypeId(colDef->typename) != childatt->atttypid ||
+ if (typenameTypeId(NULL, colDef->typename) != childatt->atttypid ||
colDef->typename->typmod != childatt->atttypmod)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -3009,7 +3006,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
MaxHeapAttributeNumber)));
i = minattnum + 1;
- typeTuple = typenameType(colDef->typename);
+ typeTuple = typenameType(NULL, colDef->typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple);
@@ -3991,8 +3988,9 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
* the right answer from the test below on opclass membership unless
* we select the proper operator.)
*/
- Operator o = oper(list_make1(makeString("=")),
- pktypoid[i], fktypoid[i], true);
+ Operator o = oper(NULL, list_make1(makeString("=")),
+ pktypoid[i], fktypoid[i],
+ true, -1);
if (o == NULL)
ereport(ERROR,
@@ -4773,12 +4771,7 @@ ATPrepAlterColumnType(List **wqueue,
colName)));
/* Look up the target type */
- targettype = LookupTypeName(typename);
- if (!OidIsValid(targettype))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
+ targettype = typenameTypeId(NULL, typename);
/* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype);
@@ -4904,7 +4897,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
colName)));
/* Look up the target type (should not fail, since prep found it) */
- typeTuple = typenameType(typename);
+ typeTuple = typenameType(NULL, typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple);
@@ -5265,7 +5258,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
Node *parsetree = (Node *) lfirst(list_item);
querytree_list = list_concat(querytree_list,
- parse_analyze(parsetree, NULL, 0));
+ parse_analyze(parsetree, cmd, NULL, 0));
}
/*
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 933f76c12d5..83143496dbc 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.88 2006/03/05 15:58:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.89 2006/03/14 22:48:18 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -47,7 +47,7 @@
#include "executor/executor.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
-#include "nodes/nodes.h"
+#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/planmain.h"
#include "optimizer/var.h"
@@ -80,7 +80,7 @@ static Oid findTypeReceiveFunction(List *procname, Oid typeOid);
static Oid findTypeSendFunction(List *procname, Oid typeOid);
static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid);
static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
-static void domainOwnerCheck(HeapTuple tup, TypeName *typename);
+static void checkDomainOwner(HeapTuple tup, TypeName *typename);
static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
Oid baseTypeOid,
int typMod, Constraint *constr,
@@ -196,7 +196,7 @@ DefineType(List *names, List *parameters)
}
else if (pg_strcasecmp(defel->defname, "element") == 0)
{
- elemType = typenameTypeId(defGetTypeName(defel));
+ elemType = typenameTypeId(NULL, defGetTypeName(defel));
/* disallow arrays of pseudotypes */
if (get_typtype(elemType) == 'p')
ereport(ERROR,
@@ -445,13 +445,10 @@ RemoveType(List *names, DropBehavior behavior, bool missing_ok)
ObjectAddress object;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be removed. */
- typeoid = LookupTypeName(typename);
+ typeoid = LookupTypeName(NULL, typename);
if (!OidIsValid(typeoid))
{
if (!missing_ok)
@@ -586,7 +583,7 @@ DefineDomain(CreateDomainStmt *stmt)
/*
* Look up the base type.
*/
- typeTup = typenameType(stmt->typename);
+ typeTup = typenameType(NULL, stmt->typename);
baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup);
@@ -840,13 +837,10 @@ RemoveDomain(List *names, DropBehavior behavior, bool missing_ok)
ObjectAddress object;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
/* Use LookupTypeName here so that shell types can be removed. */
- typeoid = LookupTypeName(typename);
+ typeoid = LookupTypeName(NULL, typename);
if (!OidIsValid(typeoid))
{
if (!missing_ok)
@@ -1172,39 +1166,27 @@ AlterDomainDefault(List *names, Node *defaultRaw)
Form_pg_type typTup;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
+ domainoid = typenameTypeId(NULL, typename);
- /* Lock the domain in the type table */
+ /* Look up the domain in the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock);
- /* Use LookupTypeName here so that shell types can be removed. */
- domainoid = LookupTypeName(typename);
- if (!OidIsValid(domainoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
-
tup = SearchSysCacheCopy(TYPEOID,
ObjectIdGetDatum(domainoid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for type %u", domainoid);
+ typTup = (Form_pg_type) GETSTRUCT(tup);
- /* Doesn't return if user isn't allowed to alter the domain */
- domainOwnerCheck(tup, typename);
+ /* Check it's a domain and check user has permission for ALTER DOMAIN */
+ checkDomainOwner(tup, typename);
/* Setup new tuple */
MemSet(new_record, (Datum) 0, sizeof(new_record));
MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
MemSet(new_record_repl, ' ', sizeof(new_record_repl));
- /* Useful later */
- typTup = (Form_pg_type) GETSTRUCT(tup);
-
/* Store the new default, if null then skip this step */
if (defaultRaw)
{
@@ -1295,22 +1277,12 @@ AlterDomainNotNull(List *names, bool notNull)
Form_pg_type typTup;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
+ domainoid = typenameTypeId(NULL, typename);
- /* Lock the type table */
+ /* Look up the domain in the type table */
typrel = heap_open(TypeRelationId, RowExclusiveLock);
- /* Use LookupTypeName here so that shell types can be found (why?). */
- domainoid = LookupTypeName(typename);
- if (!OidIsValid(domainoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
-
tup = SearchSysCacheCopy(TYPEOID,
ObjectIdGetDatum(domainoid),
0, 0, 0);
@@ -1318,8 +1290,8 @@ AlterDomainNotNull(List *names, bool notNull)
elog(ERROR, "cache lookup failed for type %u", domainoid);
typTup = (Form_pg_type) GETSTRUCT(tup);
- /* Doesn't return if user isn't allowed to alter the domain */
- domainOwnerCheck(tup, typename);
+ /* Check it's a domain and check user has permission for ALTER DOMAIN */
+ checkDomainOwner(tup, typename);
/* Is the domain already set to the desired constraint? */
if (typTup->typnotnull == notNull)
@@ -1394,7 +1366,8 @@ AlterDomainNotNull(List *names, bool notNull)
* Implements the ALTER DOMAIN DROP CONSTRAINT statement
*/
void
-AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior)
+AlterDomainDropConstraint(List *names, const char *constrName,
+ DropBehavior behavior)
{
TypeName *typename;
Oid domainoid;
@@ -1406,30 +1379,20 @@ AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior beha
HeapTuple contup;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
+ domainoid = typenameTypeId(NULL, typename);
- /* Lock the type table */
+ /* Look up the domain in the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock);
- /* Use LookupTypeName here so that shell types can be removed. */
- domainoid = LookupTypeName(typename);
- if (!OidIsValid(domainoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
-
tup = SearchSysCacheCopy(TYPEOID,
ObjectIdGetDatum(domainoid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for type %u", domainoid);
- /* Doesn't return if user isn't allowed to alter the domain */
- domainOwnerCheck(tup, typename);
+ /* Check it's a domain and check user has permission for ALTER DOMAIN */
+ checkDomainOwner(tup, typename);
/* Grab an appropriate lock on the pg_constraint relation */
conrel = heap_open(ConstraintRelationId, RowExclusiveLock);
@@ -1491,22 +1454,12 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
Constraint *constr;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
+ typename = makeTypeNameFromNameList(names);
+ domainoid = typenameTypeId(NULL, typename);
- /* Lock the type table */
+ /* Look up the domain in the type table */
typrel = heap_open(TypeRelationId, RowExclusiveLock);
- /* Use LookupTypeName here so that shell types can be found (why?). */
- domainoid = LookupTypeName(typename);
- if (!OidIsValid(domainoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
-
tup = SearchSysCacheCopy(TYPEOID,
ObjectIdGetDatum(domainoid),
0, 0, 0);
@@ -1514,8 +1467,8 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
elog(ERROR, "cache lookup failed for type %u", domainoid);
typTup = (Form_pg_type) GETSTRUCT(tup);
- /* Doesn't return if user isn't allowed to alter the domain */
- domainOwnerCheck(tup, typename);
+ /* Check it's a domain and check user has permission for ALTER DOMAIN */
+ checkDomainOwner(tup, typename);
/* Check for unsupported constraint types */
if (IsA(newConstraint, FkConstraint))
@@ -1782,14 +1735,13 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
}
/*
- * domainOwnerCheck
+ * checkDomainOwner
*
- * Throw an error if the current user doesn't have permission to modify
- * the domain in an ALTER DOMAIN statement, or if the type isn't actually
- * a domain.
+ * Check that the type is actually a domain and that the current user
+ * has permission to do ALTER DOMAIN on it. Throw an error if not.
*/
static void
-domainOwnerCheck(HeapTuple tup, TypeName *typename)
+checkDomainOwner(HeapTuple tup, TypeName *typename)
{
Form_pg_type typTup = (Form_pg_type) GETSTRUCT(tup);
@@ -2079,22 +2031,19 @@ AlterTypeOwner(List *names, Oid newOwnerId)
AclResult aclresult;
/* Make a TypeName so we can use standard type lookup machinery */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
-
- /* Lock the type table */
- rel = heap_open(TypeRelationId, RowExclusiveLock);
+ typename = makeTypeNameFromNameList(names);
- /* Use LookupTypeName here so that shell types can be processed (why?) */
- typeOid = LookupTypeName(typename);
+ /* Use LookupTypeName here so that shell types can be processed */
+ typeOid = LookupTypeName(NULL, typename);
if (!OidIsValid(typeOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typename))));
+ /* Look up the type in the type table */
+ rel = heap_open(TypeRelationId, RowExclusiveLock);
+
tup = SearchSysCacheCopy(TYPEOID,
ObjectIdGetDatum(typeOid),
0, 0, 0);
@@ -2206,19 +2155,9 @@ AlterTypeNamespace(List *names, const char *newschema)
Oid typeOid;
Oid nspOid;
- /* get type OID */
- typename = makeNode(TypeName);
- typename->names = names;
- typename->typmod = -1;
- typename->arrayBounds = NIL;
-
- typeOid = LookupTypeName(typename);
-
- if (!OidIsValid(typeOid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
+ /* Make a TypeName so we can use standard type lookup machinery */
+ typename = makeTypeNameFromNameList(names);
+ typeOid = typenameTypeId(NULL, typename);
/* check permissions on type */
if (!pg_type_ownercheck(typeOid, GetUserId()))
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index bdecdad247b..490e0aa3519 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.93 2006/03/05 15:58:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.94 2006/03/14 22:48:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -114,14 +114,10 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
if (!tle->resjunk)
{
ColumnDef *def = makeNode(ColumnDef);
- TypeName *typename = makeNode(TypeName);
def->colname = pstrdup(tle->resname);
-
- typename->typeid = exprType((Node *) tle->expr);
- typename->typmod = exprTypmod((Node *) tle->expr);
- def->typename = typename;
-
+ def->typename = makeTypeNameFromOid(exprType((Node *) tle->expr),
+ exprTypmod((Node *) tle->expr));
def->inhcount = 0;
def->is_local = true;
def->is_not_null = false;
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 2f0d73caf78..183bc89b020 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.148 2006/03/05 15:58:26 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.149 2006/03/14 22:48:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1282,7 +1282,7 @@ _SPI_prepare_plan(const char *src, _SPI_plan *plan)
Node *parsetree = (Node *) lfirst(list_item);
List *query_list;
- query_list = pg_analyze_and_rewrite(parsetree, argtypes, nargs);
+ query_list = pg_analyze_and_rewrite(parsetree, src, argtypes, nargs);
query_list_list = lappend(query_list_list, query_list);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index f37daaf3a6f..b38efcdec8b 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.329 2006/03/05 15:58:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.330 2006/03/14 22:48:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1418,6 +1418,7 @@ _copyAExpr(A_Expr *from)
COPY_NODE_FIELD(name);
COPY_NODE_FIELD(lexpr);
COPY_NODE_FIELD(rexpr);
+ COPY_SCALAR_FIELD(location);
return newnode;
}
@@ -1428,6 +1429,7 @@ _copyColumnRef(ColumnRef *from)
ColumnRef *newnode = makeNode(ColumnRef);
COPY_NODE_FIELD(fields);
+ COPY_SCALAR_FIELD(location);
return newnode;
}
@@ -1482,6 +1484,7 @@ _copyFuncCall(FuncCall *from)
COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(agg_star);
COPY_SCALAR_FIELD(agg_distinct);
+ COPY_SCALAR_FIELD(location);
return newnode;
}
@@ -1532,6 +1535,7 @@ _copyTypeName(TypeName *from)
COPY_SCALAR_FIELD(pct_type);
COPY_SCALAR_FIELD(typmod);
COPY_NODE_FIELD(arrayBounds);
+ COPY_SCALAR_FIELD(location);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 757acd9fb91..0275b01c28e 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.265 2006/03/05 15:58:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.266 2006/03/14 22:48:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1540,6 +1540,7 @@ _equalAExpr(A_Expr *a, A_Expr *b)
COMPARE_NODE_FIELD(name);
COMPARE_NODE_FIELD(lexpr);
COMPARE_NODE_FIELD(rexpr);
+ COMPARE_SCALAR_FIELD(location);
return true;
}
@@ -1548,6 +1549,7 @@ static bool
_equalColumnRef(ColumnRef *a, ColumnRef *b)
{
COMPARE_NODE_FIELD(fields);
+ COMPARE_SCALAR_FIELD(location);
return true;
}
@@ -1577,6 +1579,7 @@ _equalFuncCall(FuncCall *a, FuncCall *b)
COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(agg_star);
COMPARE_SCALAR_FIELD(agg_distinct);
+ COMPARE_SCALAR_FIELD(location);
return true;
}
@@ -1619,6 +1622,7 @@ _equalTypeName(TypeName *a, TypeName *b)
COMPARE_SCALAR_FIELD(pct_type);
COMPARE_SCALAR_FIELD(typmod);
COMPARE_NODE_FIELD(arrayBounds);
+ COMPARE_SCALAR_FIELD(location);
return true;
}
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index f69b6e6244b..784dd57831d 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.49 2006/03/05 15:58:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.50 2006/03/14 22:48:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,8 @@
* makes an A_Expr node
*/
A_Expr *
-makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr)
+makeA_Expr(A_Expr_Kind kind, List *name,
+ Node *lexpr, Node *rexpr, int location)
{
A_Expr *a = makeNode(A_Expr);
@@ -33,6 +34,7 @@ makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr)
a->name = name;
a->lexpr = lexpr;
a->rexpr = rexpr;
+ a->location = location;
return a;
}
@@ -42,7 +44,7 @@ makeA_Expr(A_Expr_Kind kind, List *name, Node *lexpr, Node *rexpr)
*/
A_Expr *
makeSimpleA_Expr(A_Expr_Kind kind, const char *name,
- Node *lexpr, Node *rexpr)
+ Node *lexpr, Node *rexpr, int location)
{
A_Expr *a = makeNode(A_Expr);
@@ -50,6 +52,7 @@ makeSimpleA_Expr(A_Expr_Kind kind, const char *name,
a->name = list_make1(makeString((char *) name));
a->lexpr = lexpr;
a->rexpr = rexpr;
+ a->location = location;
return a;
}
@@ -253,6 +256,8 @@ makeRangeVar(char *schemaname, char *relname)
/*
* makeTypeName -
* build a TypeName node for an unqualified name.
+ *
+ * typmod is defaulted, but can be changed later by caller.
*/
TypeName *
makeTypeName(char *typnam)
@@ -261,6 +266,39 @@ makeTypeName(char *typnam)
n->names = list_make1(makeString(typnam));
n->typmod = -1;
+ n->location = -1;
+ return n;
+}
+
+/*
+ * makeTypeNameFromNameList -
+ * build a TypeName node for a String list representing a qualified name.
+ *
+ * typmod is defaulted, but can be changed later by caller.
+ */
+TypeName *
+makeTypeNameFromNameList(List *names)
+{
+ TypeName *n = makeNode(TypeName);
+
+ n->names = names;
+ n->typmod = -1;
+ n->location = -1;
+ return n;
+}
+
+/*
+ * makeTypeNameFromOid -
+ * build a TypeName node to represent a type already known by OID.
+ */
+TypeName *
+makeTypeNameFromOid(Oid typeid, int32 typmod)
+{
+ TypeName *n = makeNode(TypeName);
+
+ n->typeid = typeid;
+ n->typmod = typmod;
+ n->location = -1;
return n;
}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 7bb20628c60..ef87fedbc21 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.269 2006/03/05 15:58:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.270 2006/03/14 22:48:19 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1400,6 +1400,7 @@ _outFuncCall(StringInfo str, FuncCall *node)
WRITE_NODE_FIELD(args);
WRITE_BOOL_FIELD(agg_star);
WRITE_BOOL_FIELD(agg_distinct);
+ WRITE_INT_FIELD(location);
}
static void
@@ -1449,6 +1450,7 @@ _outTypeName(StringInfo str, TypeName *node)
WRITE_BOOL_FIELD(pct_type);
WRITE_INT_FIELD(typmod);
WRITE_NODE_FIELD(arrayBounds);
+ /* location is deliberately not stored */
}
static void
@@ -1648,6 +1650,7 @@ _outAExpr(StringInfo str, A_Expr *node)
WRITE_NODE_FIELD(lexpr);
WRITE_NODE_FIELD(rexpr);
+ WRITE_INT_FIELD(location);
}
static void
@@ -1687,6 +1690,7 @@ _outColumnRef(StringInfo str, ColumnRef *node)
WRITE_NODE_TYPE("COLUMNREF");
WRITE_NODE_FIELD(fields);
+ WRITE_INT_FIELD(location);
}
static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 2733db62b3a..c7490a9567c 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.185 2006/03/05 15:58:28 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.186 2006/03/14 22:48:19 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
@@ -893,6 +893,8 @@ _readTypeName(void)
READ_BOOL_FIELD(pct_type);
READ_INT_FIELD(typmod);
READ_NODE_FIELD(arrayBounds);
+ /* location is deliberately not stored */
+ local_node->location = -1;
READ_DONE();
}
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index d980cde06bc..1c04a8784d2 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.116 2006/03/07 01:00:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.117 2006/03/14 22:48:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -992,8 +992,9 @@ process_implied_equality(PlannerInfo *root,
*/
ltype = exprType(item1);
rtype = exprType(item2);
- eq_operator = compatible_oper(list_make1(makeString("=")),
- ltype, rtype, true);
+ eq_operator = compatible_oper(NULL, list_make1(makeString("=")),
+ ltype, rtype,
+ true, -1);
if (!HeapTupleIsValid(eq_operator))
{
/*
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 37d693b9950..aa21dfdac95 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.209 2006/03/05 15:58:31 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.210 2006/03/14 22:48:19 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -2637,7 +2637,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
if (list_length(raw_parsetree_list) != 1)
goto fail;
- querytree_list = parse_analyze(linitial(raw_parsetree_list),
+ querytree_list = parse_analyze(linitial(raw_parsetree_list), src,
argtypes, funcform->pronargs);
if (list_length(querytree_list) != 1)
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 645a740be0e..1c4dc363034 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.330 2006/03/05 15:58:32 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.331 2006/03/14 22:48:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -146,6 +146,9 @@ static bool check_parameter_resolution_walker(Node *node,
* parse_analyze
* Analyze a raw parse tree and transform it to Query form.
*
+ * If available, pass the source text from which the raw parse tree was
+ * generated; it's OK to pass NULL if this is not available.
+ *
* Optionally, information about $n parameter types can be supplied.
* References to $n indexes not defined by paramTypes[] are disallowed.
*
@@ -155,11 +158,13 @@ static bool check_parameter_resolution_walker(Node *node,
* a dummy CMD_UTILITY Query node.
*/
List *
-parse_analyze(Node *parseTree, Oid *paramTypes, int numParams)
+parse_analyze(Node *parseTree, const char *sourceText,
+ Oid *paramTypes, int numParams)
{
ParseState *pstate = make_parsestate(NULL);
List *result;
+ pstate->p_sourcetext = sourceText;
pstate->p_paramtypes = paramTypes;
pstate->p_numparams = numParams;
pstate->p_variableparams = false;
@@ -179,11 +184,13 @@ parse_analyze(Node *parseTree, Oid *paramTypes, int numParams)
* be modified or enlarged (via repalloc).
*/
List *
-parse_analyze_varparams(Node *parseTree, Oid **paramTypes, int *numParams)
+parse_analyze_varparams(Node *parseTree, const char *sourceText,
+ Oid **paramTypes, int *numParams)
{
ParseState *pstate = make_parsestate(NULL);
List *result;
+ pstate->p_sourcetext = sourceText;
pstate->p_paramtypes = *paramTypes;
pstate->p_numparams = *numParams;
pstate->p_variableparams = true;
@@ -921,6 +928,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
funccallnode->args = list_make1(snamenode);
funccallnode->agg_star = false;
funccallnode->agg_distinct = false;
+ funccallnode->location = -1;
constraint = makeNode(Constraint);
constraint->contype = CONSTR_DEFAULT;
@@ -1097,7 +1105,6 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
char *attributeName = NameStr(attribute->attname);
ColumnDef *def;
- TypeName *typename;
/*
* Ignore dropped columns in the parent.
@@ -1113,10 +1120,8 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
*/
def = makeNode(ColumnDef);
def->colname = pstrdup(attributeName);
- typename = makeNode(TypeName);
- typename->typeid = attribute->atttypid;
- typename->typmod = attribute->atttypmod;
- def->typename = typename;
+ def->typename = makeTypeNameFromOid(attribute->atttypid,
+ attribute->atttypmod);
def->inhcount = 0;
def->is_local = false;
def->is_not_null = attribute->attnotnull;
@@ -2608,7 +2613,7 @@ transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt)
foreach(l, stmt->argtypes)
{
TypeName *tn = lfirst(l);
- Oid toid = typenameTypeId(tn);
+ Oid toid = typenameTypeId(pstate, tn);
argtoids[i++] = toid;
}
@@ -2621,6 +2626,7 @@ transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt)
* from context.
*/
queries = parse_analyze_varparams((Node *) stmt->query,
+ pstate->p_sourcetext,
&argtoids, &nargs);
/*
@@ -3029,7 +3035,7 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
/*
* All we really need to do here is verify that the type is valid.
*/
- Type ctype = typenameType(column->typename);
+ Type ctype = typenameType(pstate, column->typename);
ReleaseSysCache(ctype);
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c86a6888f20..acaddb13651 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.534 2006/03/07 01:00:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.535 2006/03/14 22:48:20 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -61,6 +61,10 @@
#include "utils/numeric.h"
+/* Location tracking support --- simpler than bison's default */
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current = Rhs[1];
+
extern List *parsetree; /* final parse result is delivered here */
static bool QueryIsRule = FALSE;
@@ -72,7 +76,7 @@ static bool QueryIsRule = FALSE;
*/
/*#define __YYSCLASS*/
-static Node *makeColumnRef(char *relname, List *indirection);
+static Node *makeColumnRef(char *relname, List *indirection, int location);
static Node *makeTypeCast(Node *arg, TypeName *typename);
static Node *makeStringConst(char *str, TypeName *typename);
static Node *makeIntConst(int val);
@@ -81,7 +85,7 @@ static Node *makeAConst(Value *v);
static Node *makeRowNullTest(NullTestType test, RowExpr *row);
static DefElem *makeDefElem(char *name, Node *arg);
static A_Const *makeBoolAConst(bool state);
-static FuncCall *makeOverlaps(List *largs, List *rargs);
+static FuncCall *makeOverlaps(List *largs, List *rargs, int location);
static void check_qualified_name(List *names);
static List *check_func_name(List *names);
static List *extractArgTypes(List *parameters);
@@ -90,12 +94,13 @@ static void insertSelectOptions(SelectStmt *stmt,
List *sortClause, Node *lockingClause,
Node *limitOffset, Node *limitCount);
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
-static Node *doNegate(Node *n);
+static Node *doNegate(Node *n, int location);
static void doNegateFloat(Value *v);
%}
%name-prefix="base_yy"
+%locations
%union
{
@@ -3705,6 +3710,7 @@ func_type: Typename { $$ = $1; }
$$->names = lcons(makeString($1), $2);
$$->pct_type = true;
$$->typmod = -1;
+ $$->location = @1;
}
| SETOF type_name attrs '%' TYPE_P
{
@@ -3713,6 +3719,7 @@ func_type: Typename { $$ = $1; }
$$->pct_type = true;
$$->typmod = -1;
$$->setof = TRUE;
+ $$->location = @2;
}
;
@@ -6053,6 +6060,7 @@ SimpleTypename:
$$ = makeNode(TypeName);
$$->names = lcons(makeString($1), $2);
$$->typmod = -1;
+ $$->location = @1;
}
;
@@ -6077,6 +6085,7 @@ GenericType:
type_name
{
$$ = makeTypeName($1);
+ $$->location = @1;
}
;
@@ -6540,6 +6549,7 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($5, $1);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @2;
$$ = (Node *) n;
}
/*
@@ -6552,44 +6562,44 @@ a_expr: c_expr { $$ = $1; }
* also to b_expr and to the MathOp list above.
*/
| '+' a_expr %prec UMINUS
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
| '-' a_expr %prec UMINUS
- { $$ = doNegate($2); }
+ { $$ = doNegate($2, @1); }
| a_expr '+' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
| a_expr '-' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
| a_expr '*' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
| a_expr '/' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
| a_expr '%' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
| a_expr '^' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
| a_expr '<' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
| a_expr '>' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
| a_expr '=' a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
| a_expr qual_Op a_expr %prec Op
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
| qual_Op a_expr %prec Op
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
| a_expr qual_Op %prec POSTFIXOP
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
| a_expr AND a_expr
- { $$ = (Node *) makeA_Expr(AEXPR_AND, NIL, $1, $3); }
+ { $$ = (Node *) makeA_Expr(AEXPR_AND, NIL, $1, $3, @2); }
| a_expr OR a_expr
- { $$ = (Node *) makeA_Expr(AEXPR_OR, NIL, $1, $3); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OR, NIL, $1, $3, @2); }
| NOT a_expr
- { $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, $2); }
+ { $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, $2, @1); }
| a_expr LIKE a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, $3, @2); }
| a_expr LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
@@ -6597,10 +6607,11 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($3, $5);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n);
+ n->location = @4;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2);
}
| a_expr NOT LIKE a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, $4); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, $4, @2); }
| a_expr NOT LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
@@ -6608,10 +6619,11 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($4, $6);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n);
+ n->location = @5;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2);
}
| a_expr ILIKE a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, $3, @2); }
| a_expr ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
@@ -6619,10 +6631,11 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($3, $5);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n);
+ n->location = @4;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2);
}
| a_expr NOT ILIKE a_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, $4); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, $4, @2); }
| a_expr NOT ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
@@ -6630,7 +6643,8 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($4, $6);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n);
+ n->location = @5;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2);
}
| a_expr SIMILAR TO a_expr %prec SIMILAR
@@ -6642,7 +6656,8 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($4, (Node *) c);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n);
+ n->location = @2;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
}
| a_expr SIMILAR TO a_expr ESCAPE a_expr
{
@@ -6651,7 +6666,8 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($4, $6);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n);
+ n->location = @5;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
}
| a_expr NOT SIMILAR TO a_expr %prec SIMILAR
{
@@ -6662,7 +6678,8 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($5, (Node *) c);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n);
+ n->location = @5;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
}
| a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
{
@@ -6671,7 +6688,8 @@ a_expr: c_expr { $$ = $1; }
n->args = list_make2($5, $7);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n);
+ n->location = @6;
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
}
/* NullTest clause
@@ -6733,7 +6751,7 @@ a_expr: c_expr { $$ = $1; }
}
| row OVERLAPS row
{
- $$ = (Node *)makeOverlaps($1, $3);
+ $$ = (Node *)makeOverlaps($1, $3, @2);
}
| a_expr IS TRUE_P
{
@@ -6779,54 +6797,63 @@ a_expr: c_expr { $$ = $1; }
}
| a_expr IS DISTINCT FROM a_expr %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
}
| a_expr IS NOT DISTINCT FROM a_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
(Node *) makeSimpleA_Expr(AEXPR_DISTINCT,
- "=", $1, $6));
+ "=", $1, $6, @2),
+ @2);
}
| a_expr IS OF '(' type_list ')' %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
}
| a_expr IS NOT OF '(' type_list ')' %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
}
| a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4),
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6));
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2),
+ @2);
}
| a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5),
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7));
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2),
+ @2);
}
| a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
(Node *) makeA_Expr(AEXPR_AND, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4),
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6)),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2),
+ @2),
(Node *) makeA_Expr(AEXPR_AND, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $6),
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $4)));
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $6, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $4, @2),
+ @2),
+ @2);
}
| a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
(Node *) makeA_Expr(AEXPR_OR, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5),
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7)),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2),
+ @2),
(Node *) makeA_Expr(AEXPR_OR, NIL,
- (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $7),
- (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $5)));
+ (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $7, @2),
+ (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $5, @2),
+ @2),
+ @2);
}
| a_expr IN_P in_expr
{
@@ -6843,7 +6870,7 @@ a_expr: c_expr { $$ = $1; }
else
{
/* generate scalar IN expression */
- $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3, @2);
}
}
| a_expr NOT IN_P in_expr
@@ -6858,12 +6885,12 @@ a_expr: c_expr { $$ = $1; }
n->testexpr = $1;
n->operName = list_make1(makeString("="));
/* Stick a NOT on top */
- $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n);
+ $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n, @2);
}
else
{
/* generate scalar NOT IN expression */
- $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4, @2);
}
}
| a_expr subquery_Op sub_type select_with_parens %prec Op
@@ -6878,9 +6905,9 @@ a_expr: c_expr { $$ = $1; }
| a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
{
if ($3 == ANY_SUBLINK)
- $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5);
+ $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5, @2);
else
- $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5);
+ $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5, @2);
}
| UNIQUE select_with_parens
{
@@ -6913,49 +6940,49 @@ b_expr: c_expr
| b_expr TYPECAST Typename
{ $$ = makeTypeCast($1, $3); }
| '+' b_expr %prec UMINUS
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
| '-' b_expr %prec UMINUS
- { $$ = doNegate($2); }
+ { $$ = doNegate($2, @1); }
| b_expr '+' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
| b_expr '-' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
| b_expr '*' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
| b_expr '/' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
| b_expr '%' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
| b_expr '^' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
| b_expr '<' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
| b_expr '>' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
| b_expr '=' b_expr
- { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3); }
+ { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
| b_expr qual_Op b_expr %prec Op
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
| qual_Op b_expr %prec Op
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
| b_expr qual_Op %prec POSTFIXOP
- { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL); }
+ { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
| b_expr IS DISTINCT FROM b_expr %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
}
| b_expr IS NOT DISTINCT FROM b_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,
- NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $6));
+ NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $6, @2), @2);
}
| b_expr IS OF '(' type_list ')' %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
}
| b_expr IS NOT OF '(' type_list ')' %prec IS
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
}
;
@@ -7052,6 +7079,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| func_name '(' expr_list ')'
@@ -7061,6 +7089,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| func_name '(' ALL expr_list ')'
@@ -7074,6 +7103,7 @@ func_expr: func_name '(' ')'
* "must be an aggregate", but there's no provision
* for that in FuncCall at the moment.
*/
+ n->location = @1;
$$ = (Node *)n;
}
| func_name '(' DISTINCT expr_list ')'
@@ -7083,6 +7113,7 @@ func_expr: func_name '(' ')'
n->args = $4;
n->agg_star = FALSE;
n->agg_distinct = TRUE;
+ n->location = @1;
$$ = (Node *)n;
}
| func_name '(' '*' ')'
@@ -7108,6 +7139,7 @@ func_expr: func_name '(' ')'
n->args = list_make1(star);
n->agg_star = TRUE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CURRENT_DATE
@@ -7196,6 +7228,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CURRENT_TIMESTAMP '(' Iconst ')'
@@ -7331,6 +7364,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CURRENT_USER
@@ -7340,6 +7374,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| SESSION_USER
@@ -7349,6 +7384,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| USER
@@ -7358,6 +7394,7 @@ func_expr: func_name '(' ')'
n->args = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CAST '(' a_expr AS Typename ')'
@@ -7369,6 +7406,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| OVERLAY '(' overlay_list ')'
@@ -7383,6 +7421,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| POSITION '(' position_list ')'
@@ -7393,6 +7432,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| SUBSTRING '(' substr_list ')'
@@ -7405,6 +7445,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| TREAT '(' a_expr AS Typename ')'
@@ -7413,7 +7454,7 @@ func_expr: func_name '(' ')'
* which is defined to be a subtype of the original expression.
* In SQL99, this is intended for use with structured UDTs,
* but let's make this a generally useful form allowing stronger
- * coersions than are handled by implicit casting.
+ * coercions than are handled by implicit casting.
*/
FuncCall *n = makeNode(FuncCall);
/* Convert SystemTypeName() to SystemFuncName() even though
@@ -7421,6 +7462,9 @@ func_expr: func_name '(' ')'
*/
n->funcname = SystemFuncName(((Value *)llast($5->names))->val.str);
n->args = list_make1($3);
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' BOTH trim_list ')'
@@ -7433,6 +7477,7 @@ func_expr: func_name '(' ')'
n->args = $4;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' LEADING trim_list ')'
@@ -7442,6 +7487,7 @@ func_expr: func_name '(' ')'
n->args = $4;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' TRAILING trim_list ')'
@@ -7451,6 +7497,7 @@ func_expr: func_name '(' ')'
n->args = $4;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' trim_list ')'
@@ -7460,6 +7507,7 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CONVERT '(' a_expr USING any_name ')'
@@ -7474,6 +7522,7 @@ func_expr: func_name '(' ')'
n->args = list_make2($3, c);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| CONVERT '(' expr_list ')'
@@ -7483,11 +7532,12 @@ func_expr: func_name '(' ')'
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = @1;
$$ = (Node *)n;
}
| NULLIF '(' a_expr ',' a_expr ')'
{
- $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5);
+ $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5, @1);
}
| COALESCE '(' expr_list ')'
{
@@ -7797,11 +7847,11 @@ case_arg: a_expr { $$ = $1; }
*/
columnref: relation_name
{
- $$ = makeColumnRef($1, NIL);
+ $$ = makeColumnRef($1, NIL, @1);
}
| relation_name indirection
{
- $$ = makeColumnRef($1, $2);
+ $$ = makeColumnRef($1, $2, @1);
}
;
@@ -7875,6 +7925,7 @@ target_el: a_expr AS ColLabel
{
ColumnRef *n = makeNode(ColumnRef);
n->fields = list_make1(makeString("*"));
+ n->location = @1;
$$ = makeNode(ResTarget);
$$->name = NULL;
@@ -8585,7 +8636,7 @@ SpecialRuleRelation:
%%
static Node *
-makeColumnRef(char *relname, List *indirection)
+makeColumnRef(char *relname, List *indirection, int location)
{
/*
* Generate a ColumnRef node, with an A_Indirection node added if there
@@ -8597,6 +8648,7 @@ makeColumnRef(char *relname, List *indirection)
int nfields = 0;
ListCell *l;
+ c->location = location;
foreach(l, indirection)
{
if (IsA(lfirst(l), A_Indices))
@@ -8750,9 +8802,9 @@ makeRowNullTest(NullTestType test, RowExpr *row)
if (result == NULL)
result = (Node *) n;
else if (test == IS_NOT_NULL)
- result = (Node *) makeA_Expr(AEXPR_OR, NIL, result, (Node *)n);
+ result = (Node *) makeA_Expr(AEXPR_OR, NIL, result, (Node *)n, -1);
else
- result = (Node *) makeA_Expr(AEXPR_AND, NIL, result, (Node *)n);
+ result = (Node *) makeA_Expr(AEXPR_AND, NIL, result, (Node *)n, -1);
}
if (result == NULL)
@@ -8768,9 +8820,10 @@ makeRowNullTest(NullTestType test, RowExpr *row)
* Create and populate a FuncCall node to support the OVERLAPS operator.
*/
static FuncCall *
-makeOverlaps(List *largs, List *rargs)
+makeOverlaps(List *largs, List *rargs, int location)
{
FuncCall *n = makeNode(FuncCall);
+
n->funcname = SystemFuncName("overlaps");
if (list_length(largs) == 1)
largs = lappend(largs, largs);
@@ -8787,6 +8840,7 @@ makeOverlaps(List *largs, List *rargs)
n->args = list_concat(largs, rargs);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
+ n->location = location;
return n;
}
@@ -8944,6 +8998,7 @@ SystemTypeName(char *name)
n->names = list_make2(makeString("pg_catalog"), makeString(name));
n->typmod = -1;
+ n->location = -1;
return n;
}
@@ -8987,7 +9042,7 @@ exprIsNullConstant(Node *arg)
* until we know what the desired type is.
*/
static Node *
-doNegate(Node *n)
+doNegate(Node *n, int location)
{
if (IsA(n, A_Const))
{
@@ -9005,7 +9060,7 @@ doNegate(Node *n)
}
}
- return (Node *) makeSimpleA_Expr(AEXPR_OP, "-", NULL, n);
+ return (Node *) makeSimpleA_Expr(AEXPR_OP, "-", NULL, n, location);
}
static void
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index fdc2e41b3aa..4384a4eaab8 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.147 2006/03/05 21:34:34 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.148 2006/03/14 22:48:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -303,7 +303,9 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
Node *rvar = (Node *) lfirst(rvars);
A_Expr *e;
- e = makeSimpleA_Expr(AEXPR_OP, "=", copyObject(lvar), copyObject(rvar));
+ e = makeSimpleA_Expr(AEXPR_OP, "=",
+ copyObject(lvar), copyObject(rvar),
+ -1);
if (result == NULL)
result = (Node *) e;
@@ -311,7 +313,7 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
{
A_Expr *a;
- a = makeA_Expr(AEXPR_AND, NIL, result, (Node *) e);
+ a = makeA_Expr(AEXPR_AND, NIL, result, (Node *) e, -1);
result = (Node *) a;
}
}
@@ -1182,6 +1184,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
list_length(((ColumnRef *) node)->fields) == 1)
{
char *name = strVal(linitial(((ColumnRef *) node)->fields));
+ int location = ((ColumnRef *) node)->location;
if (clause == GROUP_CLAUSE)
{
@@ -1201,7 +1204,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
* breaks no cases that are legal per spec, and it seems a more
* self-consistent behavior.
*/
- if (colNameToVar(pstate, name, true) != NULL)
+ if (colNameToVar(pstate, name, true, location) != NULL)
name = NULL;
}
@@ -1225,7 +1228,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
* construct, eg ORDER BY
*/
errmsg("%s \"%s\" is ambiguous",
- clauseText[clause], name)));
+ clauseText[clause], name),
+ parser_errposition(pstate, location)));
}
else
target_result = tle;
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index ab4d681fdfd..cae682c9e77 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.190 2006/03/05 15:58:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.191 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,18 +57,18 @@ static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
- char *relname);
+ char *relname, int location);
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
static Node *transformIndirection(ParseState *pstate, Node *basenode,
List *indirection);
static Node *typecast_expression(ParseState *pstate, Node *expr,
TypeName *typename);
static Node *make_row_comparison_op(ParseState *pstate, List *opname,
- List *largs, List *rargs);
+ List *largs, List *rargs, int location);
static Node *make_row_distinct_op(ParseState *pstate, List *opname,
- RowExpr *lrow, RowExpr *rrow);
+ RowExpr *lrow, RowExpr *rrow, int location);
static Expr *make_distinct_op(ParseState *pstate, List *opname,
- Node *ltree, Node *rtree);
+ Node *ltree, Node *rtree, int location);
/*
@@ -308,7 +308,8 @@ transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
result = ParseFuncOrColumn(pstate,
list_make1(n),
list_make1(result),
- false, false, true);
+ false, false, true,
+ -1);
}
}
/* process trailing subscripts, if any */
@@ -361,7 +362,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
char *name = strVal(linitial(cref->fields));
/* Try to identify as an unqualified column */
- node = colNameToVar(pstate, name, false);
+ node = colNameToVar(pstate, name, false, cref->location);
if (node == NULL)
{
@@ -391,12 +392,14 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
*/
if (refnameRangeTblEntry(pstate, NULL, name,
&levels_up) != NULL)
- node = transformWholeRowRef(pstate, NULL, name);
+ node = transformWholeRowRef(pstate, NULL, name,
+ cref->location);
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" does not exist",
- name)));
+ name),
+ parser_errposition(pstate, cref->location)));
}
break;
}
@@ -408,12 +411,14 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
/* Whole-row reference? */
if (strcmp(name2, "*") == 0)
{
- node = transformWholeRowRef(pstate, NULL, name1);
+ node = transformWholeRowRef(pstate, NULL, name1,
+ cref->location);
break;
}
/* Try to identify as a once-qualified column */
- node = qualifiedNameToVar(pstate, NULL, name1, name2, true);
+ node = qualifiedNameToVar(pstate, NULL, name1, name2, true,
+ cref->location);
if (node == NULL)
{
/*
@@ -421,11 +426,13 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
* it as a function call. Here, we will create an
* implicit RTE for tables not already entered.
*/
- node = transformWholeRowRef(pstate, NULL, name1);
+ node = transformWholeRowRef(pstate, NULL, name1,
+ cref->location);
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name2)),
list_make1(node),
- false, false, true);
+ false, false, true,
+ cref->location);
}
break;
}
@@ -438,20 +445,24 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
/* Whole-row reference? */
if (strcmp(name3, "*") == 0)
{
- node = transformWholeRowRef(pstate, name1, name2);
+ node = transformWholeRowRef(pstate, name1, name2,
+ cref->location);
break;
}
/* Try to identify as a twice-qualified column */
- node = qualifiedNameToVar(pstate, name1, name2, name3, true);
+ node = qualifiedNameToVar(pstate, name1, name2, name3, true,
+ cref->location);
if (node == NULL)
{
/* Try it as a function call */
- node = transformWholeRowRef(pstate, name1, name2);
+ node = transformWholeRowRef(pstate, name1, name2,
+ cref->location);
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name3)),
list_make1(node),
- false, false, true);
+ false, false, true,
+ cref->location);
}
break;
}
@@ -469,25 +480,30 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cross-database references are not implemented: %s",
- NameListToString(cref->fields))));
+ NameListToString(cref->fields)),
+ parser_errposition(pstate, cref->location)));
/* Whole-row reference? */
if (strcmp(name4, "*") == 0)
{
- node = transformWholeRowRef(pstate, name2, name3);
+ node = transformWholeRowRef(pstate, name2, name3,
+ cref->location);
break;
}
/* Try to identify as a twice-qualified column */
- node = qualifiedNameToVar(pstate, name2, name3, name4, true);
+ node = qualifiedNameToVar(pstate, name2, name3, name4, true,
+ cref->location);
if (node == NULL)
{
/* Try it as a function call */
- node = transformWholeRowRef(pstate, name2, name3);
+ node = transformWholeRowRef(pstate, name2, name3,
+ cref->location);
node = ParseFuncOrColumn(pstate,
list_make1(makeString(name4)),
list_make1(node),
- false, false, true);
+ false, false, true,
+ cref->location);
}
break;
}
@@ -495,7 +511,8 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
- NameListToString(cref->fields))));
+ NameListToString(cref->fields)),
+ parser_errposition(pstate, cref->location)));
node = NULL; /* keep compiler quiet */
break;
}
@@ -614,7 +631,8 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
result = make_row_comparison_op(pstate,
a->name,
((RowExpr *) lexpr)->args,
- ((RowExpr *) rexpr)->args);
+ ((RowExpr *) rexpr)->args,
+ a->location);
}
else
{
@@ -625,7 +643,8 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
result = (Node *) make_op(pstate,
a->name,
lexpr,
- rexpr);
+ rexpr,
+ a->location);
}
return result;
@@ -678,7 +697,8 @@ transformAExprOpAny(ParseState *pstate, A_Expr *a)
a->name,
true,
lexpr,
- rexpr);
+ rexpr,
+ a->location);
}
static Node *
@@ -691,7 +711,8 @@ transformAExprOpAll(ParseState *pstate, A_Expr *a)
a->name,
false,
lexpr,
- rexpr);
+ rexpr,
+ a->location);
}
static Node *
@@ -706,7 +727,8 @@ transformAExprDistinct(ParseState *pstate, A_Expr *a)
/* "row op row" */
return make_row_distinct_op(pstate, a->name,
(RowExpr *) lexpr,
- (RowExpr *) rexpr);
+ (RowExpr *) rexpr,
+ a->location);
}
else
{
@@ -714,7 +736,8 @@ transformAExprDistinct(ParseState *pstate, A_Expr *a)
return (Node *) make_distinct_op(pstate,
a->name,
lexpr,
- rexpr);
+ rexpr,
+ a->location);
}
}
@@ -728,11 +751,13 @@ transformAExprNullIf(ParseState *pstate, A_Expr *a)
result = (Node *) make_op(pstate,
a->name,
lexpr,
- rexpr);
+ rexpr,
+ a->location);
if (((OpExpr *) result)->opresulttype != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("NULLIF requires = operator to yield boolean")));
+ errmsg("NULLIF requires = operator to yield boolean"),
+ parser_errposition(pstate, a->location)));
/*
* We rely on NullIfExpr and OpExpr being the same struct
@@ -758,7 +783,7 @@ transformAExprOf(ParseState *pstate, A_Expr *a)
ltype = exprType(lexpr);
foreach(telem, (List *) a->rexpr)
{
- rtype = LookupTypeName(lfirst(telem));
+ rtype = typenameTypeId(pstate, lfirst(telem));
matched = (rtype == ltype);
if (matched)
break;
@@ -864,7 +889,8 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
a->name,
useOr,
lexpr,
- (Node *) newa);
+ (Node *) newa,
+ a->location);
}
}
@@ -883,17 +909,20 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
!IsA(rexpr, RowExpr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("arguments of row IN must all be row expressions")));
+ errmsg("arguments of row IN must all be row expressions"),
+ parser_errposition(pstate, a->location)));
cmp = make_row_comparison_op(pstate,
a->name,
(List *) copyObject(((RowExpr *) lexpr)->args),
- ((RowExpr *) rexpr)->args);
+ ((RowExpr *) rexpr)->args,
+ a->location);
}
else
cmp = (Node *) make_op(pstate,
a->name,
copyObject(lexpr),
- rexpr);
+ rexpr,
+ a->location);
cmp = coerce_to_boolean(pstate, cmp, "IN");
if (result == NULL)
@@ -931,7 +960,8 @@ transformFuncCall(ParseState *pstate, FuncCall *fn)
targs,
fn->agg_star,
fn->agg_distinct,
- false);
+ false,
+ fn->location);
}
static Node *
@@ -994,7 +1024,8 @@ transformCaseExpr(ParseState *pstate, CaseExpr *c)
/* shorthand form was specified, so expand... */
warg = (Node *) makeSimpleA_Expr(AEXPR_OP, "=",
(Node *) placeholder,
- warg);
+ warg,
+ -1);
}
neww->expr = (Expr *) transformExpr(pstate, warg);
@@ -1173,7 +1204,8 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
sublink->testexpr = make_row_comparison_op(pstate,
sublink->operName,
left_list,
- right_list);
+ right_list,
+ -1);
}
return result;
@@ -1394,7 +1426,8 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b)
* a rowtype; either a named composite type, or RECORD.
*/
static Node *
-transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname)
+transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname,
+ int location)
{
Node *result;
RangeTblEntry *rte;
@@ -1408,7 +1441,8 @@ transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname)
&sublevels_up);
if (rte == NULL)
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname));
+ rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname),
+ location);
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
@@ -1877,7 +1911,7 @@ typecast_expression(ParseState *pstate, Node *expr, TypeName *typename)
Oid inputType = exprType(expr);
Oid targetType;
- targetType = typenameTypeId(typename);
+ targetType = typenameTypeId(pstate, typename);
if (inputType == InvalidOid)
return expr; /* do nothing if NULL input */
@@ -1891,7 +1925,8 @@ typecast_expression(ParseState *pstate, Node *expr, TypeName *typename)
(errcode(ERRCODE_CANNOT_COERCE),
errmsg("cannot cast type %s to %s",
format_type_be(inputType),
- format_type_be(targetType))));
+ format_type_be(targetType)),
+ parser_errposition(pstate, typename->location)));
return expr;
}
@@ -1910,7 +1945,7 @@ typecast_expression(ParseState *pstate, Node *expr, TypeName *typename)
*/
static Node *
make_row_comparison_op(ParseState *pstate, List *opname,
- List *largs, List *rargs)
+ List *largs, List *rargs, int location)
{
RowCompareExpr *rcexpr;
RowCompareType rctype;
@@ -1929,7 +1964,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
if (nopers != list_length(rargs))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("unequal number of entries in row expressions")));
+ errmsg("unequal number of entries in row expressions"),
+ parser_errposition(pstate, location)));
/*
* We can't compare zero-length rows because there is no principled
@@ -1938,7 +1974,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
if (nopers == 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot compare rows of zero length")));
+ errmsg("cannot compare rows of zero length"),
+ parser_errposition(pstate, location)));
/*
* Identify all the pairwise operators, using make_op so that
@@ -1951,7 +1988,7 @@ make_row_comparison_op(ParseState *pstate, List *opname,
Node *rarg = (Node *) lfirst(r);
OpExpr *cmp;
- cmp = (OpExpr *) make_op(pstate, opname, larg, rarg);
+ cmp = (OpExpr *) make_op(pstate, opname, larg, rarg, location);
Assert(IsA(cmp, OpExpr));
/*
@@ -1964,11 +2001,13 @@ make_row_comparison_op(ParseState *pstate, List *opname,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("row comparison operator must yield type boolean, "
"not type %s",
- format_type_be(cmp->opresulttype))));
+ format_type_be(cmp->opresulttype)),
+ parser_errposition(pstate, location)));
if (expression_returns_set((Node *) cmp))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("row comparison operator must not return a set")));
+ errmsg("row comparison operator must not return a set"),
+ parser_errposition(pstate, location)));
opexprs = lappend(opexprs, cmp);
}
@@ -2021,7 +2060,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("could not determine interpretation of row comparison operator %s",
strVal(llast(opname))),
- errhint("Row comparison operators must be associated with btree operator classes.")));
+ errhint("Row comparison operators must be associated with btree operator classes."),
+ parser_errposition(pstate, location)));
rctype = 0; /* keep compiler quiet */
break;
case BMS_SINGLETON:
@@ -2069,7 +2109,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("could not determine interpretation of row comparison operator %s",
strVal(llast(opname))),
- errdetail("There are multiple equally-plausible candidates.")));
+ errdetail("There are multiple equally-plausible candidates."),
+ parser_errposition(pstate, location)));
break;
}
}
@@ -2120,7 +2161,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("could not determine interpretation of row comparison operator %s",
strVal(llast(opname))),
- errdetail("There are multiple equally-plausible candidates.")));
+ errdetail("There are multiple equally-plausible candidates."),
+ parser_errposition(pstate, location)));
}
/*
@@ -2158,7 +2200,8 @@ make_row_comparison_op(ParseState *pstate, List *opname,
*/
static Node *
make_row_distinct_op(ParseState *pstate, List *opname,
- RowExpr *lrow, RowExpr *rrow)
+ RowExpr *lrow, RowExpr *rrow,
+ int location)
{
Node *result = NULL;
List *largs = lrow->args;
@@ -2169,7 +2212,8 @@ make_row_distinct_op(ParseState *pstate, List *opname,
if (list_length(largs) != list_length(rargs))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("unequal number of entries in row expressions")));
+ errmsg("unequal number of entries in row expressions"),
+ parser_errposition(pstate, location)));
forboth(l, largs, r, rargs)
{
@@ -2177,7 +2221,7 @@ make_row_distinct_op(ParseState *pstate, List *opname,
Node *rarg = (Node *) lfirst(r);
Node *cmp;
- cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg);
+ cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg, location);
if (result == NULL)
result = cmp;
else
@@ -2198,15 +2242,17 @@ make_row_distinct_op(ParseState *pstate, List *opname,
* make the node for an IS DISTINCT FROM operator
*/
static Expr *
-make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
+make_distinct_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
+ int location)
{
Expr *result;
- result = make_op(pstate, opname, ltree, rtree);
+ result = make_op(pstate, opname, ltree, rtree, location);
if (((OpExpr *) result)->opresulttype != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("IS DISTINCT FROM requires = operator to yield boolean")));
+ errmsg("IS DISTINCT FROM requires = operator to yield boolean"),
+ parser_errposition(pstate, location)));
/*
* We rely on DistinctExpr and OpExpr being same struct
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index d6b4307a61a..35e826881fd 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.184 2006/03/05 15:58:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.185 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,8 +34,9 @@
static Node *ParseComplexProjection(ParseState *pstate, char *funcname,
- Node *first_arg);
-static void unknown_attribute(ParseState *pstate, Node *relref, char *attname);
+ Node *first_arg, int location);
+static void unknown_attribute(ParseState *pstate, Node *relref, char *attname,
+ int location);
/*
@@ -59,7 +60,8 @@ static void unknown_attribute(ParseState *pstate, Node *relref, char *attname);
*/
Node *
ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
- bool agg_star, bool agg_distinct, bool is_column)
+ bool agg_star, bool agg_distinct, bool is_column,
+ int location)
{
Oid rettype;
Oid funcid;
@@ -83,7 +85,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
ereport(ERROR,
(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
errmsg("cannot pass more than %d arguments to a function",
- FUNC_MAX_ARGS)));
+ FUNC_MAX_ARGS),
+ parser_errposition(pstate, location)));
/*
* Extract arg type info in preparation for function lookup.
@@ -131,7 +134,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
{
retval = ParseComplexProjection(pstate,
strVal(linitial(funcname)),
- first_arg);
+ first_arg,
+ location);
if (retval)
return retval;
@@ -174,12 +178,14 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("%s(*) specified, but %s is not an aggregate function",
NameListToString(funcname),
- NameListToString(funcname))));
+ NameListToString(funcname)),
+ parser_errposition(pstate, location)));
if (agg_distinct)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("DISTINCT specified, but %s is not an aggregate function",
- NameListToString(funcname))));
+ NameListToString(funcname)),
+ parser_errposition(pstate, location)));
}
else if (fdresult != FUNCDETAIL_AGGREGATE)
{
@@ -193,7 +199,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
{
Assert(nargs == 1);
Assert(list_length(funcname) == 1);
- unknown_attribute(pstate, first_arg, strVal(linitial(funcname)));
+ unknown_attribute(pstate, first_arg, strVal(linitial(funcname)),
+ location);
}
/*
@@ -206,7 +213,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
func_signature_string(funcname, nargs,
actual_arg_types)),
errhint("Could not choose a best candidate function. "
- "You may need to add explicit type casts.")));
+ "You may need to add explicit type casts."),
+ parser_errposition(pstate, location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -214,7 +222,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
func_signature_string(funcname, nargs,
actual_arg_types)),
errhint("No function matches the given name and argument types. "
- "You may need to add explicit type casts.")));
+ "You may need to add explicit type casts."),
+ parser_errposition(pstate, location)));
}
/*
@@ -262,7 +271,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
if (retset)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("aggregates may not return sets")));
+ errmsg("aggregates may not return sets"),
+ parser_errposition(pstate, location)));
}
return retval;
@@ -726,11 +736,9 @@ func_get_detail(List *funcname,
if (nargs == 1 && fargs != NIL)
{
Oid targetType;
- TypeName *tn = makeNode(TypeName);
- tn->names = funcname;
- tn->typmod = -1;
- targetType = LookupTypeName(tn);
+ targetType = LookupTypeName(NULL,
+ makeTypeNameFromNameList(funcname));
if (OidIsValid(targetType) &&
!ISCOMPLEX(targetType))
{
@@ -953,7 +961,8 @@ make_fn_arguments(ParseState *pstate,
* transformed expression tree. If not, return NULL.
*/
static Node *
-ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
+ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg,
+ int location)
{
TupleDesc tupdesc;
int i;
@@ -977,7 +986,7 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
((Var *) first_arg)->varno,
((Var *) first_arg)->varlevelsup);
/* Return a Var if funcname matches a column, else NULL */
- return scanRTEForColumn(pstate, rte, funcname);
+ return scanRTEForColumn(pstate, rte, funcname, location);
}
/*
@@ -1019,7 +1028,8 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
* helper routine for delivering "column does not exist" error message
*/
static void
-unknown_attribute(ParseState *pstate, Node *relref, char *attname)
+unknown_attribute(ParseState *pstate, Node *relref, char *attname,
+ int location)
{
RangeTblEntry *rte;
@@ -1033,7 +1043,8 @@ unknown_attribute(ParseState *pstate, Node *relref, char *attname)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column %s.%s does not exist",
- rte->eref->aliasname, attname)));
+ rte->eref->aliasname, attname),
+ parser_errposition(pstate, location)));
}
else
{
@@ -1044,18 +1055,21 @@ unknown_attribute(ParseState *pstate, Node *relref, char *attname)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" not found in data type %s",
- attname, format_type_be(relTypeId))));
+ attname, format_type_be(relTypeId)),
+ parser_errposition(pstate, location)));
else if (relTypeId == RECORDOID)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("could not identify column \"%s\" in record data type",
- attname)));
+ attname),
+ parser_errposition(pstate, location)));
else
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("column notation .%s applied to type %s, "
"which is not a composite type",
- attname, format_type_be(relTypeId))));
+ attname, format_type_be(relTypeId)),
+ parser_errposition(pstate, location)));
}
}
@@ -1219,7 +1233,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(args_item);
- argoids[i] = LookupTypeName(t);
+ argoids[i] = LookupTypeName(NULL, t);
if (!OidIsValid(argoids[i]))
ereport(ERROR,
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 2ac869c9fcd..23d73a13f25 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.91 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.92 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/pg_type.h"
+#include "mb/pg_wchar.h"
#include "nodes/makefuncs.h"
#include "parser/parsetree.h"
#include "parser/parse_coerce.h"
@@ -44,13 +45,47 @@ make_parsestate(ParseState *parentParseState)
pstate->p_next_resno = 1;
if (parentParseState)
+ {
+ pstate->p_sourcetext = parentParseState->p_sourcetext;
pstate->p_variableparams = parentParseState->p_variableparams;
+ }
return pstate;
}
/*
+ * parser_errposition
+ * Report a parse-analysis-time cursor position, if possible.
+ *
+ * This is expected to be used within an ereport() call. The return value
+ * is a dummy (always 0, in fact).
+ *
+ * The locations stored in raw parsetrees are byte offsets into the source
+ * string. We have to convert them to 1-based character indexes for reporting
+ * to clients. (We do things this way to avoid unnecessary overhead in the
+ * normal non-error case: computing character indexes would be much more
+ * expensive than storing token offsets.)
+ */
+int
+parser_errposition(ParseState *pstate, int location)
+{
+ int pos;
+
+ /* No-op if location was not provided */
+ if (location < 0)
+ return 0;
+ /* Can't do anything if source text is not available */
+ if (pstate == NULL || pstate->p_sourcetext == NULL)
+ return 0;
+ /* Convert offset to character number */
+ pos = pg_mbstrlen_with_len(pstate->p_sourcetext, location) + 1;
+ /* And pass it to the ereport mechanism */
+ return errposition(pos);
+}
+
+
+/*
* make_var
* Build a Var node for an attribute identified by RTE and attrno
*/
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 2bd65b2e126..e483372e852 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.85 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_oper.c,v 1.86 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,8 +37,9 @@ static FuncDetailCode oper_select_candidate(int nargs,
Oid *operOid);
static const char *op_signature_string(List *op, char oprkind,
Oid arg1, Oid arg2);
-static void op_error(List *op, char oprkind, Oid arg1, Oid arg2,
- FuncDetailCode fdresult);
+static void op_error(ParseState *pstate, List *op, char oprkind,
+ Oid arg1, Oid arg2,
+ FuncDetailCode fdresult, int location);
static Expr *make_op_expr(ParseState *pstate, Operator op,
Node *ltree, Node *rtree,
Oid ltypeId, Oid rtypeId);
@@ -56,10 +57,12 @@ static Expr *make_op_expr(ParseState *pstate, Operator op,
* namespace search path.
*
* If the operator is not found, we return InvalidOid if noError is true,
- * else raise an error.
+ * else raise an error. pstate and location are used only to report the
+ * error position; pass NULL/-1 if not available.
*/
Oid
-LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError)
+LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
+ bool noError, int location)
{
FuncCandidateList clist;
char oprkind;
@@ -86,7 +89,8 @@ LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError)
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator does not exist: %s",
op_signature_string(opername, oprkind,
- oprleft, oprright))));
+ oprleft, oprright)),
+ parser_errposition(pstate, location)));
return InvalidOid;
}
@@ -99,8 +103,9 @@ LookupOperName(List *opername, Oid oprleft, Oid oprright, bool noError)
* Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
*/
Oid
-LookupOperNameTypeNames(List *opername, TypeName *oprleft,
- TypeName *oprright, bool noError)
+LookupOperNameTypeNames(ParseState *pstate, List *opername,
+ TypeName *oprleft, TypeName *oprright,
+ bool noError, int location)
{
Oid leftoid,
rightoid;
@@ -108,27 +113,15 @@ LookupOperNameTypeNames(List *opername, TypeName *oprleft,
if (oprleft == NULL)
leftoid = InvalidOid;
else
- {
- leftoid = LookupTypeName(oprleft);
- if (!OidIsValid(leftoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type %s does not exist",
- TypeNameToString(oprleft))));
- }
+ leftoid = typenameTypeId(pstate, oprleft);
+
if (oprright == NULL)
rightoid = InvalidOid;
else
- {
- rightoid = LookupTypeName(oprright);
- if (!OidIsValid(rightoid))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("type %s does not exist",
- TypeNameToString(oprright))));
- }
+ rightoid = typenameTypeId(pstate, oprright);
- return LookupOperName(opername, leftoid, rightoid, noError);
+ return LookupOperName(pstate, opername, leftoid, rightoid,
+ noError, location);
}
/*
@@ -500,13 +493,15 @@ oper_select_candidate(int nargs,
* you need an exact- or binary-compatible match; see compatible_oper.
*
* If no matching operator found, return NULL if noError is true,
- * raise an error if it is false.
+ * raise an error if it is false. pstate and location are used only to report
+ * the error position; pass NULL/-1 if not available.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/
Operator
-oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError)
+oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
+ bool noError, int location)
{
FuncCandidateList clist;
Oid inputOids[2];
@@ -549,7 +544,7 @@ oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError)
}
if (!HeapTupleIsValid(tup) && !noError)
- op_error(opname, 'b', ltypeId, rtypeId, fdresult);
+ op_error(pstate, opname, 'b', ltypeId, rtypeId, fdresult, location);
return (Operator) tup;
}
@@ -562,13 +557,14 @@ oper(List *opname, Oid ltypeId, Oid rtypeId, bool noError)
* are accepted). Otherwise, the semantics are the same.
*/
Operator
-compatible_oper(List *op, Oid arg1, Oid arg2, bool noError)
+compatible_oper(ParseState *pstate, List *op, Oid arg1, Oid arg2,
+ bool noError, int location)
{
Operator optup;
Form_pg_operator opform;
/* oper() will find the best available match */
- optup = oper(op, arg1, arg2, noError);
+ optup = oper(pstate, op, arg1, arg2, noError, location);
if (optup == (Operator) NULL)
return (Operator) NULL; /* must be noError case */
@@ -585,7 +581,8 @@ compatible_oper(List *op, Oid arg1, Oid arg2, bool noError)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator requires run-time type coercion: %s",
- op_signature_string(op, 'b', arg1, arg2))));
+ op_signature_string(op, 'b', arg1, arg2)),
+ parser_errposition(pstate, location)));
return (Operator) NULL;
}
@@ -602,7 +599,7 @@ compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
Operator optup;
Oid result;
- optup = compatible_oper(op, arg1, arg2, noError);
+ optup = compatible_oper(NULL, op, arg1, arg2, noError, -1);
if (optup != NULL)
{
result = oprid(optup);
@@ -621,13 +618,14 @@ compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError)
* you need an exact- or binary-compatible match.
*
* If no matching operator found, return NULL if noError is true,
- * raise an error if it is false.
+ * raise an error if it is false. pstate and location are used only to report
+ * the error position; pass NULL/-1 if not available.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/
Operator
-right_oper(List *op, Oid arg, bool noError)
+right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
{
FuncCandidateList clist;
Oid operOid = InvalidOid;
@@ -669,7 +667,7 @@ right_oper(List *op, Oid arg, bool noError)
}
if (!HeapTupleIsValid(tup) && !noError)
- op_error(op, 'r', arg, InvalidOid, fdresult);
+ op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location);
return (Operator) tup;
}
@@ -683,13 +681,14 @@ right_oper(List *op, Oid arg, bool noError)
* you need an exact- or binary-compatible match.
*
* If no matching operator found, return NULL if noError is true,
- * raise an error if it is false.
+ * raise an error if it is false. pstate and location are used only to report
+ * the error position; pass NULL/-1 if not available.
*
* NOTE: on success, the returned object is a syscache entry. The caller
* must ReleaseSysCache() the entry when done with it.
*/
Operator
-left_oper(List *op, Oid arg, bool noError)
+left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
{
FuncCandidateList clist;
Oid operOid = InvalidOid;
@@ -736,7 +735,7 @@ left_oper(List *op, Oid arg, bool noError)
}
if (!HeapTupleIsValid(tup) && !noError)
- op_error(op, 'l', InvalidOid, arg, fdresult);
+ op_error(pstate, op, 'l', InvalidOid, arg, fdresult, location);
return (Operator) tup;
}
@@ -771,7 +770,9 @@ op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2)
* op_error - utility routine to complain about an unresolvable operator
*/
static void
-op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult)
+op_error(ParseState *pstate, List *op, char oprkind,
+ Oid arg1, Oid arg2,
+ FuncDetailCode fdresult, int location)
{
if (fdresult == FUNCDETAIL_MULTIPLE)
ereport(ERROR,
@@ -779,14 +780,16 @@ op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult)
errmsg("operator is not unique: %s",
op_signature_string(op, oprkind, arg1, arg2)),
errhint("Could not choose a best candidate operator. "
- "You may need to add explicit type casts.")));
+ "You may need to add explicit type casts."),
+ parser_errposition(pstate, location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator does not exist: %s",
op_signature_string(op, oprkind, arg1, arg2)),
errhint("No operator matches the given name and argument type(s). "
- "You may need to add explicit type casts.")));
+ "You may need to add explicit type casts."),
+ parser_errposition(pstate, location)));
}
/*
@@ -800,7 +803,8 @@ op_error(List *op, char oprkind, Oid arg1, Oid arg2, FuncDetailCode fdresult)
* processing is wanted.
*/
Expr *
-make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
+make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree,
+ int location)
{
Oid ltypeId,
rtypeId;
@@ -813,21 +817,21 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
/* right operator */
ltypeId = exprType(ltree);
rtypeId = InvalidOid;
- tup = right_oper(opname, ltypeId, false);
+ tup = right_oper(pstate, opname, ltypeId, false, location);
}
else if (ltree == NULL)
{
/* left operator */
rtypeId = exprType(rtree);
ltypeId = InvalidOid;
- tup = left_oper(opname, rtypeId, false);
+ tup = left_oper(pstate, opname, rtypeId, false, location);
}
else
{
/* otherwise, binary operator */
ltypeId = exprType(ltree);
rtypeId = exprType(rtree);
- tup = oper(opname, ltypeId, rtypeId, false);
+ tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
}
/* Do typecasting and build the expression tree */
@@ -845,7 +849,8 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
Expr *
make_scalar_array_op(ParseState *pstate, List *opname,
bool useOr,
- Node *ltree, Node *rtree)
+ Node *ltree, Node *rtree,
+ int location)
{
Oid ltypeId,
rtypeId,
@@ -875,11 +880,12 @@ make_scalar_array_op(ParseState *pstate, List *opname,
if (!OidIsValid(rtypeId))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("op ANY/ALL (array) requires array on right side")));
+ errmsg("op ANY/ALL (array) requires array on right side"),
+ parser_errposition(pstate, location)));
}
/* Now resolve the operator */
- tup = oper(opname, ltypeId, rtypeId, false);
+ tup = oper(pstate, opname, ltypeId, rtypeId, false, location);
opform = (Form_pg_operator) GETSTRUCT(tup);
args = list_make2(ltree, rtree);
@@ -904,11 +910,13 @@ make_scalar_array_op(ParseState *pstate, List *opname,
if (rettype != BOOLOID)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("op ANY/ALL (array) requires operator to yield boolean")));
+ errmsg("op ANY/ALL (array) requires operator to yield boolean"),
+ parser_errposition(pstate, location)));
if (get_func_retset(opform->oprcode))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("op ANY/ALL (array) requires operator not to return a set")));
+ errmsg("op ANY/ALL (array) requires operator not to return a set"),
+ parser_errposition(pstate, location)));
/*
* Now switch back to the array type on the right, arranging for any
@@ -919,7 +927,8 @@ make_scalar_array_op(ParseState *pstate, List *opname,
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for data type %s",
- format_type_be(declared_arg_types[1]))));
+ format_type_be(declared_arg_types[1])),
+ parser_errposition(pstate, location)));
actual_arg_types[1] = atypeId;
declared_arg_types[1] = res_atypeId;
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index af8086a81a8..d0f78b119cd 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.119 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.120 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -47,7 +47,8 @@ static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
bool include_dropped,
List **colnames, List **colvars);
static int specialAttNum(const char *attname);
-static void warnAutoRange(ParseState *pstate, RangeVar *relation);
+static void warnAutoRange(ParseState *pstate, RangeVar *relation,
+ int location);
/*
@@ -329,7 +330,8 @@ GetRTEByRangeTablePosn(ParseState *pstate,
* FROM will be marked as requiring read access from the beginning.
*/
Node *
-scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
+scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname,
+ int location)
{
Node *result = NULL;
int attnum = 0;
@@ -357,7 +359,8 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_COLUMN),
errmsg("column reference \"%s\" is ambiguous",
- colname)));
+ colname),
+ parser_errposition(pstate, location)));
result = (Node *) make_var(pstate, rte, attnum);
/* Require read access */
rte->requiredPerms |= ACL_SELECT;
@@ -404,7 +407,8 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
* If localonly is true, only names in the innermost query are considered.
*/
Node *
-colNameToVar(ParseState *pstate, char *colname, bool localonly)
+colNameToVar(ParseState *pstate, char *colname, bool localonly,
+ int location)
{
Node *result = NULL;
ParseState *orig_pstate = pstate;
@@ -419,7 +423,7 @@ colNameToVar(ParseState *pstate, char *colname, bool localonly)
Node *newresult;
/* use orig_pstate here to get the right sublevels_up */
- newresult = scanRTEForColumn(orig_pstate, rte, colname);
+ newresult = scanRTEForColumn(orig_pstate, rte, colname, location);
if (newresult)
{
@@ -427,7 +431,8 @@ colNameToVar(ParseState *pstate, char *colname, bool localonly)
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_COLUMN),
errmsg("column reference \"%s\" is ambiguous",
- colname)));
+ colname),
+ parser_errposition(orig_pstate, location)));
result = newresult;
}
}
@@ -454,7 +459,8 @@ qualifiedNameToVar(ParseState *pstate,
char *schemaname,
char *refname,
char *colname,
- bool implicitRTEOK)
+ bool implicitRTEOK,
+ int location)
{
RangeTblEntry *rte;
int sublevels_up;
@@ -465,10 +471,11 @@ qualifiedNameToVar(ParseState *pstate,
{
if (!implicitRTEOK)
return NULL;
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname, refname));
+ rte = addImplicitRTE(pstate, makeRangeVar(schemaname, refname),
+ location);
}
- return scanRTEForColumn(pstate, rte, colname);
+ return scanRTEForColumn(pstate, rte, colname, location);
}
/*
@@ -1043,12 +1050,12 @@ addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
* a conflicting name.
*/
RangeTblEntry *
-addImplicitRTE(ParseState *pstate, RangeVar *relation)
+addImplicitRTE(ParseState *pstate, RangeVar *relation, int location)
{
RangeTblEntry *rte;
/* issue warning or error as needed */
- warnAutoRange(pstate, relation);
+ warnAutoRange(pstate, relation, location);
/*
* Note that we set inFromCl true, so that the RTE will be listed
* explicitly if the parsetree is ever decompiled by ruleutils.c. This
@@ -1196,7 +1203,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
Var *varnode;
Oid atttypid;
- atttypid = typenameTypeId(colDef->typename);
+ atttypid = typenameTypeId(NULL, colDef->typename);
varnode = makeVar(rtindex,
attnum,
@@ -1543,7 +1550,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
{
ColumnDef *colDef = list_nth(rte->coldeflist, attnum - 1);
- *vartype = typenameTypeId(colDef->typename);
+ *vartype = typenameTypeId(NULL, colDef->typename);
*vartypmod = colDef->typename->typmod;
}
else
@@ -1802,7 +1809,7 @@ attnumTypeId(Relation rd, int attid)
* a warning.
*/
static void
-warnAutoRange(ParseState *pstate, RangeVar *relation)
+warnAutoRange(ParseState *pstate, RangeVar *relation, int location)
{
RangeTblEntry *rte;
int sublevels_up;
@@ -1841,7 +1848,8 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
errhint("Perhaps you meant to reference the table alias \"%s\".",
badAlias) :
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
- rte->eref->aliasname))));
+ rte->eref->aliasname)),
+ parser_errposition(pstate, location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
@@ -1849,7 +1857,8 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
errmsg("missing FROM-clause entry in subquery for table \"%s\"",
relation->relname) :
errmsg("missing FROM-clause entry for table \"%s\"",
- relation->relname))));
+ relation->relname)),
+ parser_errposition(pstate, location)));
}
else
{
@@ -1866,6 +1875,7 @@ warnAutoRange(ParseState *pstate, RangeVar *relation)
badAlias) :
(rte ?
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
- rte->eref->aliasname) : 0))));
+ rte->eref->aliasname) : 0)),
+ parser_errposition(pstate, location)));
}
}
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 63ce087e71c..300e02d90b9 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.140 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.141 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -718,7 +718,8 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cross-database references are not implemented: %s",
- NameListToString(fields))));
+ NameListToString(fields)),
+ parser_errposition(pstate, cref->location)));
schemaname = strVal(lsecond(fields));
relname = strVal(lthird(fields));
break;
@@ -727,7 +728,8 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
- NameListToString(fields))));
+ NameListToString(fields)),
+ parser_errposition(pstate, cref->location)));
schemaname = NULL; /* keep compiler quiet */
relname = NULL;
break;
@@ -736,8 +738,8 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
rte = refnameRangeTblEntry(pstate, schemaname, relname,
&sublevels_up);
if (rte == NULL)
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname,
- relname));
+ rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname),
+ cref->location);
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 41143540576..e88e6c37c1e 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.78 2006/03/05 15:58:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.79 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,9 +35,11 @@
*
* NB: even if the returned OID is not InvalidOid, the type might be
* just a shell. Caller should check typisdefined before using the type.
+ *
+ * pstate is only used for error location info, and may be NULL.
*/
Oid
-LookupTypeName(const TypeName *typename)
+LookupTypeName(ParseState *pstate, const TypeName *typename)
{
Oid restype;
@@ -60,7 +62,8 @@ LookupTypeName(const TypeName *typename)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper %%TYPE reference (too few dotted names): %s",
- NameListToString(typename->names))));
+ NameListToString(typename->names)),
+ parser_errposition(pstate, typename->location)));
break;
case 2:
rel->relname = strVal(linitial(typename->names));
@@ -81,7 +84,8 @@ LookupTypeName(const TypeName *typename)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper %%TYPE reference (too many dotted names): %s",
- NameListToString(typename->names))));
+ NameListToString(typename->names)),
+ parser_errposition(pstate, typename->location)));
break;
}
@@ -92,7 +96,8 @@ LookupTypeName(const TypeName *typename)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
- field, rel->relname)));
+ field, rel->relname),
+ parser_errposition(pstate, typename->location)));
restype = get_atttype(relid, attnum);
/* this construct should never have an array indicator */
@@ -190,21 +195,24 @@ TypeNameToString(const TypeName *typename)
* a suitable error message if the type cannot be found or is not defined.
*/
Oid
-typenameTypeId(const TypeName *typename)
+typenameTypeId(ParseState *pstate, const TypeName *typename)
{
Oid typoid;
- typoid = LookupTypeName(typename);
+ typoid = LookupTypeName(pstate, typename);
if (!OidIsValid(typoid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
+ TypeNameToString(typename)),
+ parser_errposition(pstate, typename->location)));
+
if (!get_typisdefined(typoid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" is only a shell",
- TypeNameToString(typename))));
+ TypeNameToString(typename)),
+ parser_errposition(pstate, typename->location)));
return typoid;
}
@@ -215,17 +223,18 @@ typenameTypeId(const TypeName *typename)
* NB: caller must ReleaseSysCache the type tuple when done with it.
*/
Type
-typenameType(const TypeName *typename)
+typenameType(ParseState *pstate, const TypeName *typename)
{
Oid typoid;
HeapTuple tup;
- typoid = LookupTypeName(typename);
+ typoid = LookupTypeName(pstate, typename);
if (!OidIsValid(typoid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
- TypeNameToString(typename))));
+ TypeNameToString(typename)),
+ parser_errposition(pstate, typename->location)));
tup = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typoid),
0, 0, 0);
@@ -235,7 +244,8 @@ typenameType(const TypeName *typename)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" is only a shell",
- TypeNameToString(typename))));
+ TypeNameToString(typename)),
+ parser_errposition(pstate, typename->location)));
return (Type) tup;
}
@@ -447,7 +457,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
if (typename->setof)
goto fail;
- *type_id = typenameTypeId(typename);
+ *type_id = typenameTypeId(NULL, typename);
*typmod = typename->typmod;
pfree(buf.data);
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 3d63cb73c8a..0ac8d346a7b 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -24,7 +24,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.132 2006/03/07 01:00:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.133 2006/03/14 22:48:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -74,20 +74,19 @@ static int literalalloc; /* current allocated buffer size */
static void addlit(char *ytext, int yleng);
static void addlitchar(unsigned char ychar);
static char *litbufdup(void);
-static int pg_err_position(void);
+
+static int lexer_errposition(void);
static void check_escape_warning(void);
static void check_string_escape_warning(unsigned char ychar);
/*
+ * Each call to yylex must set yylloc to the location of the found token
+ * (expressed as a byte offset from the start of the input text).
* When we parse a token that requires multiple lexer rules to process,
- * we set token_start to point at the true start of the token, for use
- * by yyerror(). yytext will point at just the text consumed by the last
- * rule, so it's not very helpful (e.g., it might contain just the last
- * quote mark of a quoted identifier). But to avoid cluttering every rule
- * with setting token_start, we allow token_start = NULL to denote that
- * it's okay to use yytext.
+ * this should be done in the first such rule, else yylloc will point
+ * into the middle of the token.
*/
-static char *token_start;
+#define SET_YYLLOC() (yylloc = yytext - scanbuf)
/* Handles to the buffer that the lexer uses internally */
static YY_BUFFER_STATE scanbufhandle;
@@ -316,17 +315,13 @@ other .
%%
-%{
- /* code to execute during start of each call of yylex() */
- token_start = NULL;
-%}
-
{whitespace} {
/* ignore */
}
{xcstart} {
- token_start = yytext;
+ /* Set location in case of syntax error in comment */
+ SET_YYLLOC();
xcdepth = 0;
BEGIN(xc);
/* Put back any characters past slash-star; see above */
@@ -341,11 +336,7 @@ other .
<xc>{xcstop} {
if (xcdepth <= 0)
- {
BEGIN(INITIAL);
- /* reset token_start for next token */
- token_start = NULL;
- }
else
xcdepth--;
}
@@ -371,7 +362,7 @@ other .
* In the meantime, place a leading "b" on the string
* to mark it for the input routine as a binary string.
*/
- token_start = yytext;
+ SET_YYLLOC();
BEGIN(xb);
startlit();
addlitchar('b');
@@ -400,7 +391,7 @@ other .
* In the meantime, place a leading "x" on the string
* to mark it for the input routine as a hex string.
*/
- token_start = yytext;
+ SET_YYLLOC();
BEGIN(xh);
startlit();
addlitchar('x');
@@ -421,6 +412,7 @@ other .
*/
const ScanKeyword *keyword;
+ SET_YYLLOC();
yyless(1); /* eat only 'n' this time */
/* nchar had better be a keyword! */
keyword = ScanKeywordLookup("nchar");
@@ -431,7 +423,7 @@ other .
{xqstart} {
warn_on_first_escape = true;
- token_start = yytext;
+ SET_YYLLOC();
if (standard_conforming_strings)
BEGIN(xq);
else
@@ -440,7 +432,7 @@ other .
}
{xestart} {
warn_on_first_escape = false;
- token_start = yytext;
+ SET_YYLLOC();
BEGIN(xe);
startlit();
}
@@ -490,7 +482,7 @@ other .
<xq,xe><<EOF>> { yyerror("unterminated quoted string"); }
{dolqdelim} {
- token_start = yytext;
+ SET_YYLLOC();
dolqstart = pstrdup(yytext);
BEGIN(xdolq);
startlit();
@@ -533,7 +525,7 @@ other .
<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
{xdstart} {
- token_start = yytext;
+ SET_YYLLOC();
BEGIN(xd);
startlit();
}
@@ -558,10 +550,12 @@ other .
<xd><<EOF>> { yyerror("unterminated quoted identifier"); }
{typecast} {
+ SET_YYLLOC();
return TYPECAST;
}
{self} {
+ SET_YYLLOC();
return yytext[0];
}
@@ -611,6 +605,8 @@ other .
nchars--; /* else remove the +/-, and check again */
}
+ SET_YYLLOC();
+
if (nchars < yyleng)
{
/* Strip the unwanted chars from the token */
@@ -644,6 +640,7 @@ other .
}
{param} {
+ SET_YYLLOC();
yylval.ival = atol(yytext + 1);
return PARAM;
}
@@ -652,6 +649,7 @@ other .
long val;
char* endptr;
+ SET_YYLLOC();
errno = 0;
val = strtol(yytext, &endptr, 10);
if (*endptr != '\0' || errno == ERANGE
@@ -669,10 +667,12 @@ other .
return ICONST;
}
{decimal} {
+ SET_YYLLOC();
yylval.str = pstrdup(yytext);
return FCONST;
}
{real} {
+ SET_YYLLOC();
yylval.str = pstrdup(yytext);
return FCONST;
}
@@ -684,12 +684,14 @@ other .
* syntax error anyway, we don't bother to distinguish.
*/
yyless(yyleng-1);
+ SET_YYLLOC();
yylval.str = pstrdup(yytext);
return FCONST;
}
{realfail2} {
/* throw back the [Ee][+-], and proceed as above */
yyless(yyleng-2);
+ SET_YYLLOC();
yylval.str = pstrdup(yytext);
return FCONST;
}
@@ -699,6 +701,8 @@ other .
const ScanKeyword *keyword;
char *ident;
+ SET_YYLLOC();
+
/* Is it a keyword? */
keyword = ScanKeywordLookup(yytext);
if (keyword != NULL)
@@ -717,25 +721,52 @@ other .
}
{other} {
+ SET_YYLLOC();
return yytext[0];
}
+<<EOF>> {
+ SET_YYLLOC();
+ yyterminate();
+ }
+
%%
+/*
+ * lexer_errposition
+ * Report a lexical-analysis-time cursor position, if possible.
+ *
+ * This is expected to be used within an ereport() call. The return value
+ * is a dummy (always 0, in fact).
+ *
+ * Note that this can only be used for messages from the lexer itself,
+ * since it depends on scanbuf to still be valid.
+ */
static int
-pg_err_position(void)
+lexer_errposition(void)
{
- const char *loc = token_start ? token_start : yytext;
+ int pos;
- /* in multibyte encodings, return index in characters not bytes */
- return pg_mbstrlen_with_len(scanbuf, loc - scanbuf) + 1;
+ /* Convert byte offset to character number */
+ pos = pg_mbstrlen_with_len(scanbuf, yylloc) + 1;
+ /* And pass it to the ereport mechanism */
+ return errposition(pos);
}
+/*
+ * yyerror
+ * Report a lexer or grammar error.
+ *
+ * The message's cursor position identifies the most recently lexed token.
+ * This is OK for syntax error messages from the Bison parser, because Bison
+ * parsers report error as soon as the first unparsable token is reached.
+ * Beware of using yyerror for other purposes, as the cursor position might
+ * be misleading!
+ */
void
yyerror(const char *message)
{
- const char *loc = token_start ? token_start : yytext;
- int cursorpos = pg_err_position();
+ const char *loc = scanbuf + yylloc;
if (*loc == YY_END_OF_BUFFER_CHAR)
{
@@ -743,7 +774,7 @@ yyerror(const char *message)
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is typically "syntax error" */
errmsg("%s at end of input", _(message)),
- errposition(cursorpos)));
+ lexer_errposition()));
}
else
{
@@ -751,7 +782,7 @@ yyerror(const char *message)
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: first %s is typically "syntax error" */
errmsg("%s at or near \"%s\"", _(message), loc),
- errposition(cursorpos)));
+ lexer_errposition()));
}
}
@@ -878,7 +909,7 @@ check_string_escape_warning(unsigned char ychar)
(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("nonstandard use of \\' in a string literal"),
errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),
- errposition(pg_err_position())));
+ lexer_errposition()));
warn_on_first_escape = false; /* warn only once per string */
}
else if (ychar == '\\')
@@ -888,7 +919,7 @@ check_string_escape_warning(unsigned char ychar)
(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("nonstandard use of \\\\ in a string literal"),
errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),
- errposition(pg_err_position())));
+ lexer_errposition()));
warn_on_first_escape = false; /* warn only once per string */
}
else
@@ -903,6 +934,6 @@ check_escape_warning(void)
(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
errmsg("nonstandard use of escape in a string literal"),
errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."),
- errposition(pg_err_position())));
+ lexer_errposition()));
warn_on_first_escape = false; /* warn only once per string */
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index a94d2691e88..78cb8c3f811 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.481 2006/03/05 15:58:40 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.482 2006/03/14 22:48:21 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -501,6 +501,7 @@ pg_parse_and_rewrite(const char *query_string, /* string to execute */
querytree_list = list_concat(querytree_list,
pg_analyze_and_rewrite(parsetree,
+ query_string,
paramTypes,
numParams));
}
@@ -625,7 +626,8 @@ log_after_parse(List *raw_parsetree_list, const char *query_string,
* NOTE: for reasons mentioned above, this must be separate from raw parsing.
*/
List *
-pg_analyze_and_rewrite(Node *parsetree, Oid *paramTypes, int numParams)
+pg_analyze_and_rewrite(Node *parsetree, const char *query_string,
+ Oid *paramTypes, int numParams)
{
List *querytree_list;
@@ -635,7 +637,8 @@ pg_analyze_and_rewrite(Node *parsetree, Oid *paramTypes, int numParams)
if (log_parser_stats)
ResetUsage();
- querytree_list = parse_analyze(parsetree, paramTypes, numParams);
+ querytree_list = parse_analyze(parsetree, query_string,
+ paramTypes, numParams);
if (log_parser_stats)
ShowUsage("PARSE ANALYSIS STATISTICS");
@@ -946,7 +949,8 @@ exec_simple_query(const char *query_string)
*/
oldcontext = MemoryContextSwitchTo(MessageContext);
- querytree_list = pg_analyze_and_rewrite(parsetree, NULL, 0);
+ querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
+ NULL, 0);
plantree_list = pg_plan_queries(querytree_list, NULL, true);
@@ -1257,6 +1261,7 @@ exec_parse_message(const char *query_string, /* string to execute */
ResetUsage();
querytree_list = parse_analyze_varparams(parsetree,
+ query_string,
&paramTypes,
&numParams);
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 030f8c52b2f..9942bcc291b 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -2,7 +2,7 @@
* ruleutils.c - Functions to convert stored expressions/querytrees
* back to source text
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.215 2006/03/11 16:43:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.216 2006/03/14 22:48:22 tgl Exp $
**********************************************************************/
#include "postgres.h"
@@ -4479,7 +4479,7 @@ get_from_clause_coldeflist(List *coldeflist, deparse_context *context)
int32 atttypmod;
attname = n->colname;
- atttypeid = typenameTypeId(n->typename);
+ atttypeid = typenameTypeId(NULL, n->typename);
atttypmod = n->typename->typmod;
if (i > 0)
@@ -4868,13 +4868,16 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
switch (operform->oprkind)
{
case 'b':
- p_result = oper(list_make1(makeString(oprname)), arg1, arg2, true);
+ p_result = oper(NULL, list_make1(makeString(oprname)), arg1, arg2,
+ true, -1);
break;
case 'l':
- p_result = left_oper(list_make1(makeString(oprname)), arg2, true);
+ p_result = left_oper(NULL, list_make1(makeString(oprname)), arg2,
+ true, -1);
break;
case 'r':
- p_result = right_oper(list_make1(makeString(oprname)), arg1, true);
+ p_result = right_oper(NULL, list_make1(makeString(oprname)), arg1,
+ true, -1);
break;
default:
elog(ERROR, "unrecognized oprkind: %d", operform->oprkind);