1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-27 07:42:10 +03:00

Improve parser so that we can show an error cursor position for errors

during parse analysis, not only errors detected in the flex/bison stages.
This is per my earlier proposal.  This commit includes all the basic
infrastructure, but locations are only tracked and reported for errors
involving column references, function calls, and operators.  More could
be done later but this seems like a good set to start with.  I've also
moved the ReportSyntaxErrorPosition logic out of psql and into libpq,
which should make it available to more people --- even within psql this
is an improvement because warnings weren't handled by ReportSyntaxErrorPosition.
This commit is contained in:
Tom Lane
2006-03-14 22:48:25 +00:00
parent 48fb696753
commit 20ab467d76
80 changed files with 1347 additions and 997 deletions

View File

@@ -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;

View File

@@ -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),

View File

@@ -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),

View File

@@ -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),

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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));
}
/*

View File

@@ -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;
typename = makeTypeNameFromNameList(names);
/* Lock the type table */
rel = heap_open(TypeRelationId, RowExclusiveLock);
/* 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()))

View File

@@ -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;