Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit27a4f06

Browse files
committed
Get rid of crocky use of RangeVar nodes in parser to represent partially
transformed whole-row variables. Cleaner to use regular whole-row Vars.
1 parent94d8da8 commit27a4f06

File tree

6 files changed

+227
-293
lines changed

6 files changed

+227
-293
lines changed

‎src/backend/optimizer/util/clauses.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.167 2004/03/24 22:40:28 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.168 2004/04/02 19:06:57 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -2550,16 +2550,6 @@ expression_tree_walker(Node *node,
25502550
return true;
25512551
}
25522552
break;
2553-
caseT_RangeVar:
2554-
/*
2555-
* Give a useful complaint if someone uses a bare relation name
2556-
* in an expression (see comments in transformColumnRef()).
2557-
*/
2558-
ereport(ERROR,
2559-
(errcode(ERRCODE_SYNTAX_ERROR),
2560-
errmsg("relation reference \"%s\" cannot be used in an expression",
2561-
((RangeVar*)node)->relname)));
2562-
break;
25632553
default:
25642554
elog(ERROR,"unrecognized node type: %d",
25652555
(int)nodeTag(node));
@@ -3031,16 +3021,6 @@ expression_tree_mutator(Node *node,
30313021
return (Node*)newnode;
30323022
}
30333023
break;
3034-
caseT_RangeVar:
3035-
/*
3036-
* Give a useful complaint if someone uses a bare relation name
3037-
* in an expression (see comments in transformColumnRef()).
3038-
*/
3039-
ereport(ERROR,
3040-
(errcode(ERRCODE_SYNTAX_ERROR),
3041-
errmsg("relation reference \"%s\" cannot be used in an expression",
3042-
((RangeVar*)node)->relname)));
3043-
break;
30443024
default:
30453025
elog(ERROR,"unrecognized node type: %d",
30463026
(int)nodeTag(node));

‎src/backend/parser/parse_expr.c

Lines changed: 114 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.167 2004/03/24 22:40:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.168 2004/04/02 19:06:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -40,6 +40,8 @@ boolTransform_null_equals = false;
4040
staticNode*typecast_expression(ParseState*pstate,Node*expr,
4141
TypeName*typename);
4242
staticNode*transformColumnRef(ParseState*pstate,ColumnRef*cref);
43+
staticNode*transformWholeRowRef(ParseState*pstate,char*schemaname,
44+
char*relname);
4345
staticNode*transformIndirection(ParseState*pstate,Node*basenode,
4446
List*indirection);
4547

@@ -932,34 +934,29 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
932934
{
933935
intnumnames=length(cref->fields);
934936
Node*node;
935-
RangeVar*rv;
936937
intlevels_up;
937938

938939
/*----------
939940
* The allowed syntaxes are:
940941
*
941942
* AFirst try to resolve as unqualified column name;
942-
*if no luck, try to resolve asunqual. table name (A.*).
943-
* A.BA is anunqual. table name; B is either a
943+
*if no luck, try to resolve asunqualified table name (A.*).
944+
* A.BA is anunqualified table name; B is either a
944945
*column or function name (trying column name first).
945946
* A.B.Cschema A, table B, col or func name C.
946947
* A.B.C.Dcatalog A, schema B, table C, col or func D.
947-
* A.*A is anunqual. table name; means whole-row value.
948+
* A.*A is anunqualified table name; means whole-row value.
948949
* A.B.*whole-row value of table B in schema A.
949950
* A.B.C.*whole-row value of table C in schema B in catalog A.
950951
*
951952
* We do not need to cope with bare "*"; that will only be accepted by
952953
* the grammar at the top level of a SELECT list, and transformTargetList
953-
* will take care of it before it ever gets here.
954+
* will take care of it before it ever gets here. Also, "A.*" etc will
955+
* be expanded by transformTargetList if they appear at SELECT top level,
956+
* so here we are only going to see them as function or operator inputs.
954957
*
955958
* Currently, if a catalog name is given then it must equal the current
956959
* database name; we check it here and then discard it.
957-
*
958-
* For whole-row references, the result is an untransformed RangeVar,
959-
* which will work as the argument to a function call, but not in any
960-
* other context at present. (We could instead coerce to a whole-row Var,
961-
* but that will fail for subselect and join RTEs, because there is no
962-
* pg_type entry for their rowtypes.)
963960
*----------
964961
*/
965962
switch (numnames)
@@ -1001,16 +998,12 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
1001998
if (cref->indirection==NIL&&
1002999
refnameRangeTblEntry(pstate,NULL,name,
10031000
&levels_up)!=NULL)
1004-
{
1005-
rv=makeNode(RangeVar);
1006-
rv->relname=name;
1007-
rv->inhOpt=INH_DEFAULT;
1008-
node= (Node*)rv;
1009-
}
1001+
node=transformWholeRowRef(pstate,NULL,name);
10101002
else
10111003
ereport(ERROR,
10121004
(errcode(ERRCODE_UNDEFINED_COLUMN),
1013-
errmsg("column \"%s\" does not exist",name)));
1005+
errmsg("column \"%s\" does not exist",
1006+
name)));
10141007
}
10151008
break;
10161009
}
@@ -1022,10 +1015,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
10221015
/* Whole-row reference? */
10231016
if (strcmp(name2,"*")==0)
10241017
{
1025-
rv=makeNode(RangeVar);
1026-
rv->relname=name1;
1027-
rv->inhOpt=INH_DEFAULT;
1028-
node= (Node*)rv;
1018+
node=transformWholeRowRef(pstate,NULL,name1);
10291019
break;
10301020
}
10311021

@@ -1038,12 +1028,10 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
10381028
* try it as a function call. Here, we will create an
10391029
* implicit RTE for tables not already entered.
10401030
*/
1041-
rv=makeNode(RangeVar);
1042-
rv->relname=name1;
1043-
rv->inhOpt=INH_DEFAULT;
1031+
node=transformWholeRowRef(pstate,NULL,name1);
10441032
node=ParseFuncOrColumn(pstate,
10451033
makeList1(makeString(name2)),
1046-
makeList1(rv),
1034+
makeList1(node),
10471035
false, false, true);
10481036
}
10491037
break;
@@ -1057,11 +1045,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
10571045
/* Whole-row reference? */
10581046
if (strcmp(name3,"*")==0)
10591047
{
1060-
rv=makeNode(RangeVar);
1061-
rv->schemaname=name1;
1062-
rv->relname=name2;
1063-
rv->inhOpt=INH_DEFAULT;
1064-
node= (Node*)rv;
1048+
node=transformWholeRowRef(pstate,name1,name2);
10651049
break;
10661050
}
10671051

@@ -1070,13 +1054,10 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
10701054
if (node==NULL)
10711055
{
10721056
/* Try it as a function call */
1073-
rv=makeNode(RangeVar);
1074-
rv->schemaname=name1;
1075-
rv->relname=name2;
1076-
rv->inhOpt=INH_DEFAULT;
1057+
node=transformWholeRowRef(pstate,name1,name2);
10771058
node=ParseFuncOrColumn(pstate,
10781059
makeList1(makeString(name3)),
1079-
makeList1(rv),
1060+
makeList1(node),
10801061
false, false, true);
10811062
}
10821063
break;
@@ -1100,11 +1081,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
11001081
/* Whole-row reference? */
11011082
if (strcmp(name4,"*")==0)
11021083
{
1103-
rv=makeNode(RangeVar);
1104-
rv->schemaname=name2;
1105-
rv->relname=name3;
1106-
rv->inhOpt=INH_DEFAULT;
1107-
node= (Node*)rv;
1084+
node=transformWholeRowRef(pstate,name2,name3);
11081085
break;
11091086
}
11101087

@@ -1113,13 +1090,10 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
11131090
if (node==NULL)
11141091
{
11151092
/* Try it as a function call */
1116-
rv=makeNode(RangeVar);
1117-
rv->schemaname=name2;
1118-
rv->relname=name3;
1119-
rv->inhOpt=INH_DEFAULT;
1093+
node=transformWholeRowRef(pstate,name2,name3);
11201094
node=ParseFuncOrColumn(pstate,
11211095
makeList1(makeString(name4)),
1122-
makeList1(rv),
1096+
makeList1(node),
11231097
false, false, true);
11241098
}
11251099
break;
@@ -1136,6 +1110,99 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
11361110
returntransformIndirection(pstate,node,cref->indirection);
11371111
}
11381112

1113+
/*
1114+
* Construct a whole-row reference to represent the notation "relation.*".
1115+
*
1116+
* In simple cases, this will be a Var with varno set to the correct range
1117+
* table entry, and varattno == 0 to signal that it references the whole
1118+
* tuple. (Use of zero here is unclean, since it could easily be confused
1119+
* with error cases, but it's not worth changing now.) The vartype indicates
1120+
* a rowtype; either a named composite type, or RECORD.
1121+
*
1122+
* We also need the ability to build a row-constructor expression, but the
1123+
* infrastructure for that doesn't exist just yet.
1124+
*/
1125+
staticNode*
1126+
transformWholeRowRef(ParseState*pstate,char*schemaname,char*relname)
1127+
{
1128+
Node*result;
1129+
RangeTblEntry*rte;
1130+
intvnum;
1131+
intsublevels_up;
1132+
Oidtoid;
1133+
1134+
/* Look up the referenced RTE, creating it if needed */
1135+
1136+
rte=refnameRangeTblEntry(pstate,schemaname,relname,
1137+
&sublevels_up);
1138+
1139+
if (rte==NULL)
1140+
rte=addImplicitRTE(pstate,makeRangeVar(schemaname,relname));
1141+
1142+
vnum=RTERangeTablePosn(pstate,rte,&sublevels_up);
1143+
1144+
/* Build the appropriate referencing node */
1145+
1146+
switch (rte->rtekind)
1147+
{
1148+
caseRTE_RELATION:
1149+
/* relation: the rowtype is a named composite type */
1150+
toid=get_rel_type_id(rte->relid);
1151+
if (!OidIsValid(toid))
1152+
elog(ERROR,"could not find type OID for relation %u",
1153+
rte->relid);
1154+
result= (Node*)makeVar(vnum,
1155+
InvalidAttrNumber,
1156+
toid,
1157+
-1,
1158+
sublevels_up);
1159+
break;
1160+
caseRTE_FUNCTION:
1161+
toid=exprType(rte->funcexpr);
1162+
if (toid==RECORDOID||get_typtype(toid)=='c')
1163+
{
1164+
/* func returns composite; same as relation case */
1165+
result= (Node*)makeVar(vnum,
1166+
InvalidAttrNumber,
1167+
toid,
1168+
-1,
1169+
sublevels_up);
1170+
}
1171+
else
1172+
{
1173+
/*
1174+
* func returns scalar; instead of making a whole-row Var,
1175+
* just reference the function's scalar output. (XXX this
1176+
* seems a tad inconsistent, especially if "f.*" was
1177+
* explicitly written ...)
1178+
*/
1179+
result= (Node*)makeVar(vnum,
1180+
1,
1181+
toid,
1182+
-1,
1183+
sublevels_up);
1184+
}
1185+
break;
1186+
default:
1187+
/*
1188+
* RTE is a join or subselect. For the moment we represent this
1189+
* as a whole-row Var of RECORD type, but this will not actually
1190+
* work; need a row-constructor expression instead.
1191+
*
1192+
* XXX after fixing, be sure that unknown_attribute still
1193+
* does the right thing.
1194+
*/
1195+
result= (Node*)makeVar(vnum,
1196+
InvalidAttrNumber,
1197+
RECORDOID,
1198+
-1,
1199+
sublevels_up);
1200+
break;
1201+
}
1202+
1203+
returnresult;
1204+
}
1205+
11391206
/*
11401207
*exprType -
11411208
* returns the Oid of the type of the expression. (Used for typechecking.)
@@ -1294,19 +1361,6 @@ exprType(Node *expr)
12941361
caseT_SetToDefault:
12951362
type= ((SetToDefault*)expr)->typeId;
12961363
break;
1297-
caseT_RangeVar:
1298-
1299-
/*
1300-
* If someone uses a bare relation name in an expression, we
1301-
* will likely first notice a problem here (see comments in
1302-
* transformColumnRef()). Issue an appropriate error message.
1303-
*/
1304-
ereport(ERROR,
1305-
(errcode(ERRCODE_SYNTAX_ERROR),
1306-
errmsg("relation reference \"%s\" cannot be used in an expression",
1307-
((RangeVar*)expr)->relname)));
1308-
type=InvalidOid;/* keep compiler quiet */
1309-
break;
13101364
default:
13111365
elog(ERROR,"unrecognized node type: %d", (int)nodeTag(expr));
13121366
type=InvalidOid;/* keep compiler quiet */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp