88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.50 2006/03/05 15:58:22 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.51 2006/03/16 00:31:54 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -850,11 +850,6 @@ doDeletion(const ObjectAddress *object)
850850 *
851851 * rtable is the rangetable to be used to interpret Vars with varlevelsup=0.
852852 * It can be NIL if no such variables are expected.
853- *
854- * XXX is it important to create dependencies on the datatypes mentioned in
855- * the expression? In most cases this would be redundant (eg, a ref to an
856- * operator indirectly references its input and output datatypes), but I'm
857- * not quite convinced there are no cases where we need it.
858853 */
859854void
860855recordDependencyOnExpr (const ObjectAddress * depender ,
@@ -975,6 +970,13 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
975970 * To do so, we do not scan the joinaliasvars list of a join RTE while
976971 * scanning the query rangetable, but instead scan each individual entry
977972 * of the alias list when we find a reference to it.
973+ *
974+ * Note: in many cases we do not need to create dependencies on the datatypes
975+ * involved in an expression, because we'll have an indirect dependency via
976+ * some other object. For instance Var nodes depend on a column which depends
977+ * on the datatype, and OpExpr nodes depend on the operator which depends on
978+ * the datatype. However we do need a type dependency if there is no such
979+ * indirect dependency, as for example in Const and CoerceToDomain nodes.
978980 */
979981static bool
980982find_expr_references_walker (Node * node ,
@@ -1033,6 +1035,10 @@ find_expr_references_walker(Node *node,
10331035 Const * con = (Const * ) node ;
10341036 Oid objoid ;
10351037
1038+ /* A constant must depend on the constant's datatype */
1039+ add_object_address (OCLASS_TYPE , con -> consttype , 0 ,
1040+ & context -> addrs );
1041+
10361042 /*
10371043 * If it's a regclass or similar literal referring to an existing
10381044 * object, add a reference to that object. (Currently, only the
@@ -1081,6 +1087,14 @@ find_expr_references_walker(Node *node,
10811087 }
10821088 return false;
10831089 }
1090+ if (IsA (node , Param ))
1091+ {
1092+ Param * param = (Param * ) node ;
1093+
1094+ /* A parameter must depend on the parameter's datatype */
1095+ add_object_address (OCLASS_TYPE , param -> paramtype , 0 ,
1096+ & context -> addrs );
1097+ }
10841098 if (IsA (node , FuncExpr ))
10851099 {
10861100 FuncExpr * funcexpr = (FuncExpr * ) node ;
@@ -1134,6 +1148,29 @@ find_expr_references_walker(Node *node,
11341148 /* Extra work needed here if we ever need this case */
11351149 elog (ERROR , "already-planned subqueries not supported" );
11361150 }
1151+ if (IsA (node , RelabelType ))
1152+ {
1153+ RelabelType * relab = (RelabelType * ) node ;
1154+
1155+ /* since there is no function dependency, need to depend on type */
1156+ add_object_address (OCLASS_TYPE , relab -> resulttype , 0 ,
1157+ & context -> addrs );
1158+ }
1159+ if (IsA (node , ConvertRowtypeExpr ))
1160+ {
1161+ ConvertRowtypeExpr * cvt = (ConvertRowtypeExpr * ) node ;
1162+
1163+ /* since there is no function dependency, need to depend on type */
1164+ add_object_address (OCLASS_TYPE , cvt -> resulttype , 0 ,
1165+ & context -> addrs );
1166+ }
1167+ if (IsA (node , RowExpr ))
1168+ {
1169+ RowExpr * rowexpr = (RowExpr * ) node ;
1170+
1171+ add_object_address (OCLASS_TYPE , rowexpr -> row_typeid , 0 ,
1172+ & context -> addrs );
1173+ }
11371174 if (IsA (node , RowCompareExpr ))
11381175 {
11391176 RowCompareExpr * rcexpr = (RowCompareExpr * ) node ;
@@ -1151,6 +1188,13 @@ find_expr_references_walker(Node *node,
11511188 }
11521189 /* fall through to examine arguments */
11531190 }
1191+ if (IsA (node , CoerceToDomain ))
1192+ {
1193+ CoerceToDomain * cd = (CoerceToDomain * ) node ;
1194+
1195+ add_object_address (OCLASS_TYPE , cd -> resulttype , 0 ,
1196+ & context -> addrs );
1197+ }
11541198 if (IsA (node , Query ))
11551199 {
11561200 /* Recurse into RTE subquery or not-yet-planned sublink subquery */
@@ -1160,17 +1204,32 @@ find_expr_references_walker(Node *node,
11601204
11611205 /*
11621206 * Add whole-relation refs for each plain relation mentioned in the
1163- * subquery's rtable. (Note: query_tree_walker takes care of
1164- * recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need to do
1165- * that here. But keep it from looking at join alias lists.)
1207+ * subquery's rtable, as well as datatype refs for any datatypes used
1208+ * as a RECORD function's output. (Note: query_tree_walker takes care
1209+ * of recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need to
1210+ * do that here. But keep it from looking at join alias lists.)
11661211 */
11671212 foreach (rtable , query -> rtable )
11681213 {
11691214 RangeTblEntry * rte = (RangeTblEntry * ) lfirst (rtable );
1215+ ListCell * ct ;
11701216
1171- if (rte -> rtekind == RTE_RELATION )
1172- add_object_address (OCLASS_CLASS , rte -> relid , 0 ,
1173- & context -> addrs );
1217+ switch (rte -> rtekind )
1218+ {
1219+ case RTE_RELATION :
1220+ add_object_address (OCLASS_CLASS , rte -> relid , 0 ,
1221+ & context -> addrs );
1222+ break ;
1223+ case RTE_FUNCTION :
1224+ foreach (ct , rte -> funccoltypes )
1225+ {
1226+ add_object_address (OCLASS_TYPE , lfirst_oid (ct ), 0 ,
1227+ & context -> addrs );
1228+ }
1229+ break ;
1230+ default :
1231+ break ;
1232+ }
11741233 }
11751234
11761235 /* Examine substructure of query */
0 commit comments