Skip to content

Commit b084cc3

Browse files
committed
Cause schema-qualified FROM items and schema-qualified variable references
to behave according to SQL92 (or according to my current understanding of same, anyway). Per pghackers discussion way back in March 2002: thread 'Do FROM items of different schemas conflict?'
1 parent e42f8e3 commit b084cc3

File tree

8 files changed

+375
-86
lines changed

8 files changed

+375
-86
lines changed

src/backend/catalog/namespace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.28 2002/08/06 05:40:44 ishii Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.29 2002/08/08 01:44:30 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1080,7 +1080,7 @@ DeconstructQualifiedName(List *names,
10801080
* Returns the namespace OID. Raises elog if any problem.
10811081
*/
10821082
Oid
1083-
LookupExplicitNamespace(char *nspname)
1083+
LookupExplicitNamespace(const char *nspname)
10841084
{
10851085
Oid namespaceId;
10861086
AclResult aclresult;

src/backend/parser/parse_expr.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.124 2002/08/04 06:46:12 thomas Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.125 2002/08/08 01:44:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -709,18 +709,23 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
709709

710710
/* Try to identify as an unqualified column */
711711
node = colnameToVar(pstate, name);
712+
712713
if (node == NULL)
713714
{
714715
/*
715716
* Not known as a column of any range-table entry, so
716717
* try to find the name as a relation ... but not if
717718
* subscripts appear. Note also that only relations
718719
* already entered into the rangetable will be recognized.
720+
*
721+
* This is a hack for backwards compatibility with PostQUEL-
722+
* inspired syntax. The preferred form now is "rel.*".
719723
*/
720724
int levels_up;
721725

722726
if (cref->indirection == NIL &&
723-
refnameRangeTblEntry(pstate, name, &levels_up) != NULL)
727+
refnameRangeTblEntry(pstate, NULL, name,
728+
&levels_up) != NULL)
724729
{
725730
rv = makeNode(RangeVar);
726731
rv->relname = name;
@@ -748,7 +753,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
748753
}
749754

750755
/* Try to identify as a once-qualified column */
751-
node = qualifiedNameToVar(pstate, name1, name2, true);
756+
node = qualifiedNameToVar(pstate, NULL, name1, name2, true);
752757
if (node == NULL)
753758
{
754759
/*
@@ -784,8 +789,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
784789
}
785790

786791
/* Try to identify as a twice-qualified column */
787-
/* XXX do something with schema name here */
788-
node = qualifiedNameToVar(pstate, name2, name3, true);
792+
node = qualifiedNameToVar(pstate, name1, name2, name3, true);
789793
if (node == NULL)
790794
{
791795
/* Try it as a function call */
@@ -825,8 +829,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
825829
}
826830

827831
/* Try to identify as a twice-qualified column */
828-
/* XXX do something with schema name here */
829-
node = qualifiedNameToVar(pstate, name3, name4, true);
832+
node = qualifiedNameToVar(pstate, name2, name3, name4, true);
830833
if (node == NULL)
831834
{
832835
/* Try it as a function call */

src/backend/parser/parse_func.c

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.133 2002/08/02 18:15:07 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.134 2002/08/08 01:44:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -51,6 +51,8 @@ static int match_argtypes(int nargs,
5151
static FieldSelect *setup_field_select(Node *input, char *attname, Oid relid);
5252
static FuncCandidateList func_select_candidate(int nargs, Oid *input_typeids,
5353
FuncCandidateList candidates);
54+
static void unknown_attribute(const char *schemaname, const char *relname,
55+
const char *attname);
5456

5557

5658
/*
@@ -80,7 +82,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
8082
Oid funcid;
8183
List *i;
8284
Node *first_arg = NULL;
83-
char *refname;
8485
int nargs = length(fargs);
8586
int argn;
8687
Oid oid_array[FUNC_MAX_ARGS];
@@ -121,10 +122,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
121122
if (IsA(first_arg, RangeVar))
122123
{
123124
/* First arg is a relation. This could be a projection. */
124-
refname = ((RangeVar *) first_arg)->relname;
125-
126-
/* XXX WRONG: ignores possible qualification of argument */
127-
retval = qualifiedNameToVar(pstate, refname, cname, true);
125+
retval = qualifiedNameToVar(pstate,
126+
((RangeVar *) first_arg)->schemaname,
127+
((RangeVar *) first_arg)->relname,
128+
cname,
129+
true);
128130
if (retval)
129131
return retval;
130132
}
@@ -156,16 +158,19 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
156158

157159
if (IsA(arg, RangeVar))
158160
{
161+
char *schemaname;
162+
char *relname;
159163
RangeTblEntry *rte;
160164
int vnum;
161165
int sublevels_up;
162166

163167
/*
164-
* a relation
168+
* a relation: look it up in the range table, or add if needed
165169
*/
166-
refname = ((RangeVar *) arg)->relname;
170+
schemaname = ((RangeVar *) arg)->schemaname;
171+
relname = ((RangeVar *) arg)->relname;
167172

168-
rte = refnameRangeTblEntry(pstate, refname,
173+
rte = refnameRangeTblEntry(pstate, schemaname, relname,
169174
&sublevels_up);
170175

171176
if (rte == NULL)
@@ -199,11 +204,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
199204
* named tuple type
200205
*/
201206
if (is_column)
202-
elog(ERROR, "No such attribute %s.%s",
203-
refname, strVal(lfirst(funcname)));
207+
unknown_attribute(schemaname, relname,
208+
strVal(lfirst(funcname)));
204209
else
205210
elog(ERROR, "Cannot pass result of sub-select or join %s to a function",
206-
refname);
211+
relname);
207212
toid = InvalidOid; /* keep compiler quiet */
208213
break;
209214
}
@@ -268,8 +273,9 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
268273

269274
Assert(nargs == 1);
270275
if (IsA(first_arg, RangeVar))
271-
elog(ERROR, "No such attribute %s.%s",
272-
((RangeVar *) first_arg)->relname, colname);
276+
unknown_attribute(((RangeVar *) first_arg)->schemaname,
277+
((RangeVar *) first_arg)->relname,
278+
colname);
273279
relTypeId = exprType(first_arg);
274280
if (!ISCOMPLEX(relTypeId))
275281
elog(ERROR, "Attribute notation .%s applied to type %s, which is not a complex type",
@@ -1225,6 +1231,21 @@ ParseComplexProjection(ParseState *pstate,
12251231
return (Node *) fselect;
12261232
}
12271233

1234+
/*
1235+
* Simple helper routine for delivering "No such attribute" error message
1236+
*/
1237+
static void
1238+
unknown_attribute(const char *schemaname, const char *relname,
1239+
const char *attname)
1240+
{
1241+
if (schemaname)
1242+
elog(ERROR, "No such attribute %s.%s.%s",
1243+
schemaname, relname, attname);
1244+
else
1245+
elog(ERROR, "No such attribute %s.%s",
1246+
relname, attname);
1247+
}
1248+
12281249
/*
12291250
* Error message when function lookup fails that gives details of the
12301251
* argument types

0 commit comments

Comments
 (0)