@@ -1835,8 +1835,17 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
18351835 * the datatype. However we do need a type dependency if there is no such
18361836 * indirect dependency, as for example in Const and CoerceToDomain nodes.
18371837 *
1838- * Similarly, we don't need to create dependencies on collations except where
1839- * the collation is being freshly introduced to the expression.
1838+ * Collations are handled primarily by recording the inputcollid's of node
1839+ * types that have them, as those are the ones that are semantically
1840+ * significant during expression evaluation. We also record the collation of
1841+ * CollateExpr nodes, since those will be needed to print such nodes even if
1842+ * they don't really affect semantics. Collations of leaf nodes such as Vars
1843+ * can be ignored on the grounds that if they're not default, they came from
1844+ * the referenced object (e.g., a table column), so the dependency on that
1845+ * object is enough. (Note: in a post-const-folding expression tree, a
1846+ * CollateExpr's collation could have been absorbed into a Const or
1847+ * RelabelType node. While ruleutils.c prints such collations for clarity,
1848+ * we may ignore them here as they have no semantic effect.)
18401849 */
18411850static bool
18421851find_expr_references_walker (Node * node ,
@@ -1876,29 +1885,6 @@ find_expr_references_walker(Node *node,
18761885/* If it's a plain relation, reference this column */
18771886add_object_address (OCLASS_CLASS ,rte -> relid ,var -> varattno ,
18781887context -> addrs );
1879-
1880- /* Top-level collation if valid */
1881- if (OidIsValid (var -> varcollid ))
1882- add_object_address (OCLASS_COLLATION ,var -> varcollid ,0 ,
1883- context -> addrs );
1884- /* Otherwise, it may be a type with internal collations */
1885- else if (var -> vartype >=FirstNormalObjectId )
1886- {
1887- List * collations ;
1888- ListCell * lc ;
1889-
1890- collations = GetTypeCollations (var -> vartype );
1891-
1892- foreach (lc ,collations )
1893- {
1894- Oid coll = lfirst_oid (lc );
1895-
1896- if (OidIsValid (coll ))
1897- add_object_address (OCLASS_COLLATION ,
1898- lfirst_oid (lc ),0 ,
1899- context -> addrs );
1900- }
1901- }
19021888}
19031889
19041890/*
@@ -1920,15 +1906,6 @@ find_expr_references_walker(Node *node,
19201906add_object_address (OCLASS_TYPE ,con -> consttype ,0 ,
19211907context -> addrs );
19221908
1923- /*
1924- * We must also depend on the constant's collation: it could be
1925- * different from the datatype's, if a CollateExpr was const-folded to
1926- * a simple constant.
1927- */
1928- if (OidIsValid (con -> constcollid ))
1929- add_object_address (OCLASS_COLLATION ,con -> constcollid ,0 ,
1930- context -> addrs );
1931-
19321909/*
19331910 * If it's a regclass or similar literal referring to an existing
19341911 * object, add a reference to that object. (Currently, only the
@@ -2013,17 +1990,16 @@ find_expr_references_walker(Node *node,
20131990/* A parameter must depend on the parameter's datatype */
20141991add_object_address (OCLASS_TYPE ,param -> paramtype ,0 ,
20151992context -> addrs );
2016- /* and its collation, just as for Consts */
2017- if (OidIsValid (param -> paramcollid ))
2018- add_object_address (OCLASS_COLLATION ,param -> paramcollid ,0 ,
2019- context -> addrs );
20201993}
20211994else if (IsA (node ,FuncExpr ))
20221995{
20231996FuncExpr * funcexpr = (FuncExpr * )node ;
20241997
20251998add_object_address (OCLASS_PROC ,funcexpr -> funcid ,0 ,
20261999context -> addrs );
2000+ if (OidIsValid (funcexpr -> inputcollid ))
2001+ add_object_address (OCLASS_COLLATION ,funcexpr -> inputcollid ,0 ,
2002+ context -> addrs );
20272003/* fall through to examine arguments */
20282004}
20292005else if (IsA (node ,OpExpr ))
@@ -2032,6 +2008,9 @@ find_expr_references_walker(Node *node,
20322008
20332009add_object_address (OCLASS_OPERATOR ,opexpr -> opno ,0 ,
20342010context -> addrs );
2011+ if (OidIsValid (opexpr -> inputcollid ))
2012+ add_object_address (OCLASS_COLLATION ,opexpr -> inputcollid ,0 ,
2013+ context -> addrs );
20352014/* fall through to examine arguments */
20362015}
20372016else if (IsA (node ,DistinctExpr ))
@@ -2040,6 +2019,9 @@ find_expr_references_walker(Node *node,
20402019
20412020add_object_address (OCLASS_OPERATOR ,distinctexpr -> opno ,0 ,
20422021context -> addrs );
2022+ if (OidIsValid (distinctexpr -> inputcollid ))
2023+ add_object_address (OCLASS_COLLATION ,distinctexpr -> inputcollid ,0 ,
2024+ context -> addrs );
20432025/* fall through to examine arguments */
20442026}
20452027else if (IsA (node ,NullIfExpr ))
@@ -2048,6 +2030,9 @@ find_expr_references_walker(Node *node,
20482030
20492031add_object_address (OCLASS_OPERATOR ,nullifexpr -> opno ,0 ,
20502032context -> addrs );
2033+ if (OidIsValid (nullifexpr -> inputcollid ))
2034+ add_object_address (OCLASS_COLLATION ,nullifexpr -> inputcollid ,0 ,
2035+ context -> addrs );
20512036/* fall through to examine arguments */
20522037}
20532038else if (IsA (node ,ScalarArrayOpExpr ))
@@ -2056,6 +2041,9 @@ find_expr_references_walker(Node *node,
20562041
20572042add_object_address (OCLASS_OPERATOR ,opexpr -> opno ,0 ,
20582043context -> addrs );
2044+ if (OidIsValid (opexpr -> inputcollid ))
2045+ add_object_address (OCLASS_COLLATION ,opexpr -> inputcollid ,0 ,
2046+ context -> addrs );
20592047/* fall through to examine arguments */
20602048}
20612049else if (IsA (node ,Aggref ))
@@ -2064,6 +2052,9 @@ find_expr_references_walker(Node *node,
20642052
20652053add_object_address (OCLASS_PROC ,aggref -> aggfnoid ,0 ,
20662054context -> addrs );
2055+ if (OidIsValid (aggref -> inputcollid ))
2056+ add_object_address (OCLASS_COLLATION ,aggref -> inputcollid ,0 ,
2057+ context -> addrs );
20672058/* fall through to examine arguments */
20682059}
20692060else if (IsA (node ,WindowFunc ))
@@ -2072,6 +2063,9 @@ find_expr_references_walker(Node *node,
20722063
20732064add_object_address (OCLASS_PROC ,wfunc -> winfnoid ,0 ,
20742065context -> addrs );
2066+ if (OidIsValid (wfunc -> inputcollid ))
2067+ add_object_address (OCLASS_COLLATION ,wfunc -> inputcollid ,0 ,
2068+ context -> addrs );
20752069/* fall through to examine arguments */
20762070}
20772071else if (IsA (node ,SubscriptingRef ))
@@ -2116,10 +2110,6 @@ find_expr_references_walker(Node *node,
21162110else
21172111add_object_address (OCLASS_TYPE ,fselect -> resulttype ,0 ,
21182112context -> addrs );
2119- /* the collation might not be referenced anywhere else, either */
2120- if (OidIsValid (fselect -> resultcollid ))
2121- add_object_address (OCLASS_COLLATION ,fselect -> resultcollid ,0 ,
2122- context -> addrs );
21232113}
21242114else if (IsA (node ,FieldStore ))
21252115{
@@ -2146,10 +2136,6 @@ find_expr_references_walker(Node *node,
21462136/* since there is no function dependency, need to depend on type */
21472137add_object_address (OCLASS_TYPE ,relab -> resulttype ,0 ,
21482138context -> addrs );
2149- /* the collation might not be referenced anywhere else, either */
2150- if (OidIsValid (relab -> resultcollid ))
2151- add_object_address (OCLASS_COLLATION ,relab -> resultcollid ,0 ,
2152- context -> addrs );
21532139}
21542140else if (IsA (node ,CoerceViaIO ))
21552141{
@@ -2158,10 +2144,6 @@ find_expr_references_walker(Node *node,
21582144/* since there is no exposed function, need to depend on type */
21592145add_object_address (OCLASS_TYPE ,iocoerce -> resulttype ,0 ,
21602146context -> addrs );
2161- /* the collation might not be referenced anywhere else, either */
2162- if (OidIsValid (iocoerce -> resultcollid ))
2163- add_object_address (OCLASS_COLLATION ,iocoerce -> resultcollid ,0 ,
2164- context -> addrs );
21652147}
21662148else if (IsA (node ,ArrayCoerceExpr ))
21672149{
@@ -2170,10 +2152,6 @@ find_expr_references_walker(Node *node,
21702152/* as above, depend on type */
21712153add_object_address (OCLASS_TYPE ,acoerce -> resulttype ,0 ,
21722154context -> addrs );
2173- /* the collation might not be referenced anywhere else, either */
2174- if (OidIsValid (acoerce -> resultcollid ))
2175- add_object_address (OCLASS_COLLATION ,acoerce -> resultcollid ,0 ,
2176- context -> addrs );
21772155/* fall through to examine arguments */
21782156}
21792157else if (IsA (node ,ConvertRowtypeExpr ))
@@ -2213,6 +2191,24 @@ find_expr_references_walker(Node *node,
22132191add_object_address (OCLASS_OPFAMILY ,lfirst_oid (l ),0 ,
22142192context -> addrs );
22152193}
2194+ foreach (l ,rcexpr -> inputcollids )
2195+ {
2196+ Oid inputcollid = lfirst_oid (l );
2197+
2198+ if (OidIsValid (inputcollid ))
2199+ add_object_address (OCLASS_COLLATION ,inputcollid ,0 ,
2200+ context -> addrs );
2201+ }
2202+ /* fall through to examine arguments */
2203+ }
2204+ else if (IsA (node ,MinMaxExpr ))
2205+ {
2206+ MinMaxExpr * mmexpr = (MinMaxExpr * )node ;
2207+
2208+ /* minmaxtype will match one of the inputs, so no need to record it */
2209+ if (OidIsValid (mmexpr -> inputcollid ))
2210+ add_object_address (OCLASS_COLLATION ,mmexpr -> inputcollid ,0 ,
2211+ context -> addrs );
22162212/* fall through to examine arguments */
22172213}
22182214else if (IsA (node ,CoerceToDomain ))