| Line | Hits | Source | Commit |
| 1790 |
- |
find_expr_references_walker(Node *node, |
- |
| 1791 |
- |
find_expr_references_context *context) |
- |
| 1792 |
- |
{ |
- |
| 1793 |
- |
if (node == NULL) |
- |
| 1794 |
- |
return false; |
- |
| 1795 |
- |
if (IsA(node, Var)) |
- |
| 1796 |
- |
{ |
- |
| 1797 |
- |
Var *var = (Var *) node; |
- |
| 1798 |
- |
List *rtable; |
- |
| 1799 |
- |
RangeTblEntry *rte; |
- |
| 1800 |
- |
|
- |
| 1801 |
- |
/* Find matching rtable entry, or complain if not found */ |
- |
| 1802 |
- |
if (var->varlevelsup >= list_length(context->rtables)) |
- |
| 1803 |
- |
elog(ERROR, "invalid varlevelsup %d", var->varlevelsup); |
- |
| 1804 |
- |
rtable = (List *) list_nth(context->rtables, var->varlevelsup); |
- |
| 1805 |
- |
if (var->varno <= 0 || var->varno > list_length(rtable)) |
- |
| 1806 |
- |
elog(ERROR, "invalid varno %d", var->varno); |
- |
| 1807 |
- |
rte = rt_fetch(var->varno, rtable); |
- |
| 1808 |
- |
|
- |
| 1809 |
- |
/* |
- |
| 1810 |
- |
* A whole-row Var references no specific columns, so adds no new |
- |
| 1811 |
- |
* dependency. (We assume that there is a whole-table dependency |
- |
| 1812 |
- |
* arising from each underlying rangetable entry. While we could |
- |
| 1813 |
- |
* record such a dependency when finding a whole-row Var that |
- |
| 1814 |
- |
* references a relation directly, it's quite unclear how to extend |
- |
| 1815 |
- |
* that to whole-row Vars for JOINs, so it seems better to leave the |
- |
| 1816 |
- |
* responsibility with the range table. Note that this poses some |
- |
| 1817 |
- |
* risks for identifying dependencies of stand-alone expressions: |
- |
| 1818 |
- |
* whole-table references may need to be created separately.) |
- |
| 1819 |
- |
*/ |
- |
| 1820 |
- |
if (var->varattno == InvalidAttrNumber) |
- |
| 1821 |
- |
return false; |
- |
| 1822 |
- |
if (rte->rtekind == RTE_RELATION) |
- |
| 1823 |
- |
{ |
- |
| 1824 |
- |
/* If it's a plain relation, reference this column */ |
- |
| 1825 |
- |
add_object_address(RelationRelationId, rte->relid, var->varattno, |
- |
| 1826 |
- |
context->addrs); |
- |
| 1827 |
- |
} |
- |
| 1828 |
- |
else if (rte->rtekind == RTE_FUNCTION) |
- |
| 1829 |
- |
{ |
- |
| 1830 |
- |
/* Might need to add a dependency on a composite type's column */ |
- |
| 1831 |
- |
/* (done out of line, because it's a bit bulky) */ |
- |
| 1832 |
- |
process_function_rte_ref(rte, var->varattno, context); |
- |
| 1833 |
- |
} |
- |
| 1834 |
- |
|
- |
| 1835 |
- |
/* |
- |
| 1836 |
- |
* Vars referencing other RTE types require no additional work. In |
- |
| 1837 |
- |
* particular, a join alias Var can be ignored, because it must |
- |
| 1838 |
- |
* reference a merged USING column. The relevant join input columns |
- |
| 1839 |
- |
* will also be referenced in the join qual, and any type coercion |
- |
| 1840 |
- |
* functions involved in the alias expression will be dealt with when |
- |
| 1841 |
- |
* we scan the RTE itself. |
- |
| 1842 |
- |
*/ |
- |
| 1843 |
- |
return false; |
- |
| 1844 |
- |
} |
- |
| 1845 |
- |
else if (IsA(node, Const)) |
- |
| 1846 |
- |
{ |
- |
| 1847 |
- |
Const *con = (Const *) node; |
- |
| 1848 |
- |
Oid objoid; |
- |
| 1849 |
- |
|
- |
| 1850 |
- |
/* A constant must depend on the constant's datatype */ |
- |
| 1851 |
- |
add_object_address(TypeRelationId, con->consttype, 0, |
- |
| 1852 |
- |
context->addrs); |
- |
| 1853 |
- |
|
- |
| 1854 |
- |
/* |
- |
| 1855 |
- |
* We must also depend on the constant's collation: it could be |
- |
| 1856 |
- |
* different from the datatype's, if a CollateExpr was const-folded to |
- |
| 1857 |
- |
* a simple constant. However we can save work in the most common |
- |
| 1858 |
- |
* case where the collation is "default", since we know that's pinned. |
- |
| 1859 |
- |
*/ |
- |
| 1860 |
- |
if (OidIsValid(con->constcollid) && |
- |
| 1861 |
- |
con->constcollid != DEFAULT_COLLATION_OID) |
- |
| 1862 |
- |
add_object_address(CollationRelationId, con->constcollid, 0, |
- |
| 1863 |
- |
context->addrs); |
- |
| 1864 |
- |
|
- |
| 1865 |
- |
/* |
- |
| 1866 |
- |
* If it's a regclass or similar literal referring to an existing |
- |
| 1867 |
- |
* object, add a reference to that object. (Currently, only the |
- |
| 1868 |
- |
* regclass and regconfig cases have any likely use, but we may as |
- |
| 1869 |
- |
* well handle all the OID-alias datatypes consistently.) |
- |
| 1870 |
- |
*/ |
- |
| 1871 |
- |
if (!con->constisnull) |
- |
| 1872 |
- |
{ |
- |
| 1873 |
- |
switch (con->consttype) |
- |
| 1874 |
- |
{ |
- |
| 1875 |
- |
case REGPROCOID: |
- |
| 1876 |
- |
case REGPROCEDUREOID: |
- |
| 1877 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1878 |
- |
if (SearchSysCacheExists1(PROCOID, |
- |
| 1879 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1880 |
- |
add_object_address(ProcedureRelationId, objoid, 0, |
- |
| 1881 |
- |
context->addrs); |
- |
| 1882 |
- |
break; |
- |
| 1883 |
- |
case REGOPEROID: |
- |
| 1884 |
- |
case REGOPERATOROID: |
- |
| 1885 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1886 |
- |
if (SearchSysCacheExists1(OPEROID, |
- |
| 1887 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1888 |
- |
add_object_address(OperatorRelationId, objoid, 0, |
- |
| 1889 |
- |
context->addrs); |
- |
| 1890 |
- |
break; |
- |
| 1891 |
- |
case REGCLASSOID: |
- |
| 1892 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1893 |
- |
if (SearchSysCacheExists1(RELOID, |
- |
| 1894 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1895 |
- |
add_object_address(RelationRelationId, objoid, 0, |
- |
| 1896 |
- |
context->addrs); |
- |
| 1897 |
- |
break; |
- |
| 1898 |
- |
case REGTYPEOID: |
- |
| 1899 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1900 |
- |
if (SearchSysCacheExists1(TYPEOID, |
- |
| 1901 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1902 |
- |
add_object_address(TypeRelationId, objoid, 0, |
- |
| 1903 |
- |
context->addrs); |
- |
| 1904 |
- |
break; |
- |
| 1905 |
- |
case REGCOLLATIONOID: |
- |
| 1906 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1907 |
- |
if (SearchSysCacheExists1(COLLOID, |
- |
| 1908 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1909 |
- |
add_object_address(CollationRelationId, objoid, 0, |
- |
| 1910 |
- |
context->addrs); |
- |
| 1911 |
- |
break; |
- |
| 1912 |
- |
case REGCONFIGOID: |
- |
| 1913 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1914 |
- |
if (SearchSysCacheExists1(TSCONFIGOID, |
- |
| 1915 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1916 |
- |
add_object_address(TSConfigRelationId, objoid, 0, |
- |
| 1917 |
- |
context->addrs); |
- |
| 1918 |
- |
break; |
- |
| 1919 |
- |
case REGDICTIONARYOID: |
- |
| 1920 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1921 |
- |
if (SearchSysCacheExists1(TSDICTOID, |
- |
| 1922 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1923 |
- |
add_object_address(TSDictionaryRelationId, objoid, 0, |
- |
| 1924 |
- |
context->addrs); |
- |
| 1925 |
- |
break; |
- |
| 1926 |
- |
|
- |
| 1927 |
- |
case REGNAMESPACEOID: |
- |
| 1928 |
- |
objoid = DatumGetObjectId(con->constvalue); |
- |
| 1929 |
- |
if (SearchSysCacheExists1(NAMESPACEOID, |
- |
| 1930 |
- |
ObjectIdGetDatum(objoid))) |
- |
| 1931 |
- |
add_object_address(NamespaceRelationId, objoid, 0, |
- |
| 1932 |
- |
context->addrs); |
- |
| 1933 |
- |
break; |
- |
| 1934 |
- |
|
- |
| 1935 |
- |
/* |
- |
| 1936 |
- |
* Dependencies for regrole should be shared among all |
- |
| 1937 |
- |
* databases, so explicitly inhibit to have dependencies. |
- |
| 1938 |
- |
*/ |
- |
| 1939 |
- |
case REGROLEOID: |
- |
| 1940 |
- |
ereport(ERROR, |
- |
| 1941 |
- |
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
- |
| 1942 |
- |
errmsg("constant of the type %s cannot be used here", |
- |
| 1943 |
- |
"regrole"))); |
- |
| 1944 |
- |
break; |
- |
| 1945 |
- |
|
- |
| 1946 |
- |
/* |
- |
| 1947 |
- |
* Dependencies for regdatabase should be shared among all |
- |
| 1948 |
- |
* databases, so explicitly inhibit to have dependencies. |
- |
| 1949 |
- |
*/ |
- |
| 1950 |
- |
case REGDATABASEOID: |
- |
| 1951 |
- |
ereport(ERROR, |
- |
| 1952 |
- |
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
- |
| 1953 |
- |
errmsg("constant of the type %s cannot be used here", |
- |
| 1954 |
- |
"regdatabase"))); |
- |
| 1955 |
- |
break; |
- |
| 1956 |
- |
} |
- |
| 1957 |
- |
} |
- |
| 1958 |
- |
return false; |
- |
| 1959 |
- |
} |
- |
| 1960 |
- |
else if (IsA(node, Param)) |
- |
| 1961 |
- |
{ |
- |
| 1962 |
- |
Param *param = (Param *) node; |
- |
| 1963 |
- |
|
- |
| 1964 |
- |
/* A parameter must depend on the parameter's datatype */ |
- |
| 1965 |
- |
add_object_address(TypeRelationId, param->paramtype, 0, |
- |
| 1966 |
- |
context->addrs); |
- |
| 1967 |
- |
/* and its collation, just as for Consts */ |
- |
| 1968 |
- |
if (OidIsValid(param->paramcollid) && |
- |
| 1969 |
- |
param->paramcollid != DEFAULT_COLLATION_OID) |
- |
| 1970 |
- |
add_object_address(CollationRelationId, param->paramcollid, 0, |
- |
| 1971 |
- |
context->addrs); |
- |
| 1972 |
- |
} |
- |
| 1973 |
- |
else if (IsA(node, FuncExpr)) |
- |
| 1974 |
- |
{ |
- |
| 1975 |
- |
FuncExpr *funcexpr = (FuncExpr *) node; |
- |
| 1976 |
- |
|
- |
| 1977 |
- |
add_object_address(ProcedureRelationId, funcexpr->funcid, 0, |
- |
| 1978 |
- |
context->addrs); |
- |
| 1979 |
- |
/* fall through to examine arguments */ |
- |
| 1980 |
- |
} |
- |
| 1981 |
- |
else if (IsA(node, OpExpr)) |
- |
| 1982 |
- |
{ |
- |
| 1983 |
- |
OpExpr *opexpr = (OpExpr *) node; |
- |
| 1984 |
- |
|
- |
| 1985 |
- |
add_object_address(OperatorRelationId, opexpr->opno, 0, |
- |
| 1986 |
- |
context->addrs); |
- |
| 1987 |
- |
/* fall through to examine arguments */ |
- |
| 1988 |
- |
} |
- |
| 1989 |
- |
else if (IsA(node, DistinctExpr)) |
- |
| 1990 |
- |
{ |
- |
| 1991 |
- |
DistinctExpr *distinctexpr = (DistinctExpr *) node; |
- |
| 1992 |
- |
|
- |
| 1993 |
- |
add_object_address(OperatorRelationId, distinctexpr->opno, 0, |
- |
| 1994 |
- |
context->addrs); |
- |
| 1995 |
- |
/* fall through to examine arguments */ |
- |
| 1996 |
- |
} |
- |
| 1997 |
- |
else if (IsA(node, NullIfExpr)) |
- |
| 1998 |
- |
{ |
- |
| 1999 |
- |
NullIfExpr *nullifexpr = (NullIfExpr *) node; |
- |
| 2000 |
- |
|
- |
| 2001 |
- |
add_object_address(OperatorRelationId, nullifexpr->opno, 0, |
- |
| 2002 |
- |
context->addrs); |
- |
| 2003 |
- |
/* fall through to examine arguments */ |
- |
| 2004 |
- |
} |
- |
| 2005 |
- |
else if (IsA(node, ScalarArrayOpExpr)) |
- |
| 2006 |
- |
{ |
- |
| 2007 |
- |
ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node; |
- |
| 2008 |
- |
|
- |
| 2009 |
- |
add_object_address(OperatorRelationId, opexpr->opno, 0, |
- |
| 2010 |
- |
context->addrs); |
- |
| 2011 |
- |
/* fall through to examine arguments */ |
- |
| 2012 |
- |
} |
- |
| 2013 |
- |
else if (IsA(node, Aggref)) |
- |
| 2014 |
- |
{ |
- |
| 2015 |
- |
Aggref *aggref = (Aggref *) node; |
- |
| 2016 |
- |
|
- |
| 2017 |
- |
add_object_address(ProcedureRelationId, aggref->aggfnoid, 0, |
- |
| 2018 |
- |
context->addrs); |
- |
| 2019 |
- |
/* fall through to examine arguments */ |
- |
| 2020 |
- |
} |
- |
| 2021 |
- |
else if (IsA(node, WindowFunc)) |
- |
| 2022 |
- |
{ |
- |
| 2023 |
- |
WindowFunc *wfunc = (WindowFunc *) node; |
- |
| 2024 |
- |
|
- |
| 2025 |
- |
add_object_address(ProcedureRelationId, wfunc->winfnoid, 0, |
- |
| 2026 |
- |
context->addrs); |
- |
| 2027 |
- |
/* fall through to examine arguments */ |
- |
| 2028 |
- |
} |
- |
| 2029 |
- |
else if (IsA(node, SubscriptingRef)) |
- |
| 2030 |
- |
{ |
- |
| 2031 |
- |
SubscriptingRef *sbsref = (SubscriptingRef *) node; |
- |
| 2032 |
- |
|
- |
| 2033 |
- |
/* |
- |
| 2034 |
- |
* The refexpr should provide adequate dependency on refcontainertype, |
- |
| 2035 |
- |
* and that type in turn depends on refelemtype. However, a custom |
- |
| 2036 |
- |
* subscripting handler might set refrestype to something different |
- |
| 2037 |
- |
* from either of those, in which case we'd better record it. |
- |
| 2038 |
- |
*/ |
- |
| 2039 |
- |
if (sbsref->refrestype != sbsref->refcontainertype && |
- |
| 2040 |
- |
sbsref->refrestype != sbsref->refelemtype) |
- |
| 2041 |
- |
add_object_address(TypeRelationId, sbsref->refrestype, 0, |
- |
| 2042 |
- |
context->addrs); |
- |
| 2043 |
- |
/* fall through to examine arguments */ |
- |
| 2044 |
- |
} |
- |
| 2045 |
- |
else if (IsA(node, SubPlan)) |
- |
| 2046 |
- |
{ |
- |
| 2047 |
- |
/* Extra work needed here if we ever need this case */ |
- |
| 2048 |
- |
elog(ERROR, "already-planned subqueries not supported"); |
- |
| 2049 |
- |
} |
- |
| 2050 |
- |
else if (IsA(node, FieldSelect)) |
- |
| 2051 |
- |
{ |
- |
| 2052 |
- |
FieldSelect *fselect = (FieldSelect *) node; |
- |
| 2053 |
- |
Oid argtype = getBaseType(exprType((Node *) fselect->arg)); |
- |
| 2054 |
- |
Oid reltype = get_typ_typrelid(argtype); |
- |
| 2055 |
- |
|
- |
| 2056 |
- |
/* |
- |
| 2057 |
- |
* We need a dependency on the specific column named in FieldSelect, |
- |
| 2058 |
- |
* assuming we can identify the pg_class OID for it. (Probably we |
- |
| 2059 |
- |
* always can at the moment, but in future it might be possible for |
- |
| 2060 |
- |
* argtype to be RECORDOID.) If we can make a column dependency then |
- |
| 2061 |
- |
* we shouldn't need a dependency on the column's type; but if we |
- |
| 2062 |
- |
* can't, make a dependency on the type, as it might not appear |
- |
| 2063 |
- |
* anywhere else in the expression. |
- |
| 2064 |
- |
*/ |
- |
| 2065 |
- |
if (OidIsValid(reltype)) |
- |
| 2066 |
- |
add_object_address(RelationRelationId, reltype, fselect->fieldnum, |
- |
| 2067 |
- |
context->addrs); |
- |
| 2068 |
- |
else |
- |
| 2069 |
- |
add_object_address(TypeRelationId, fselect->resulttype, 0, |
- |
| 2070 |
- |
context->addrs); |
- |
| 2071 |
- |
/* the collation might not be referenced anywhere else, either */ |
- |
| 2072 |
- |
if (OidIsValid(fselect->resultcollid) && |
- |
| 2073 |
- |
fselect->resultcollid != DEFAULT_COLLATION_OID) |
- |
| 2074 |
- |
add_object_address(CollationRelationId, fselect->resultcollid, 0, |
- |
| 2075 |
- |
context->addrs); |
- |
| 2076 |
- |
} |
- |
| 2077 |
- |
else if (IsA(node, FieldStore)) |
- |
| 2078 |
- |
{ |
- |
| 2079 |
- |
FieldStore *fstore = (FieldStore *) node; |
- |
| 2080 |
- |
Oid reltype = get_typ_typrelid(fstore->resulttype); |
- |
| 2081 |
- |
|
- |
| 2082 |
- |
/* similar considerations to FieldSelect, but multiple column(s) */ |
- |
| 2083 |
- |
if (OidIsValid(reltype)) |
- |
| 2084 |
- |
{ |
- |
| 2085 |
- |
ListCell *l; |
- |
| 2086 |
- |
|
- |
| 2087 |
- |
foreach(l, fstore->fieldnums) |
- |
| 2088 |
- |
add_object_address(RelationRelationId, reltype, lfirst_int(l), |
- |
| 2089 |
- |
context->addrs); |
- |
| 2090 |
- |
} |
- |
| 2091 |
- |
else |
- |
| 2092 |
- |
add_object_address(TypeRelationId, fstore->resulttype, 0, |
- |
| 2093 |
- |
context->addrs); |
- |
| 2094 |
- |
} |
- |
| 2095 |
- |
else if (IsA(node, RelabelType)) |
- |
| 2096 |
- |
{ |
- |
| 2097 |
- |
RelabelType *relab = (RelabelType *) node; |
- |
| 2098 |
- |
|
- |
| 2099 |
- |
/* since there is no function dependency, need to depend on type */ |
- |
| 2100 |
- |
add_object_address(TypeRelationId, relab->resulttype, 0, |
- |
| 2101 |
- |
context->addrs); |
- |
| 2102 |
- |
/* the collation might not be referenced anywhere else, either */ |
- |
| 2103 |
- |
if (OidIsValid(relab->resultcollid) && |
- |
| 2104 |
- |
relab->resultcollid != DEFAULT_COLLATION_OID) |
- |
| 2105 |
- |
add_object_address(CollationRelationId, relab->resultcollid, 0, |
- |
| 2106 |
- |
context->addrs); |
- |
| 2107 |
- |
} |
- |
| 2108 |
- |
else if (IsA(node, CoerceViaIO)) |
- |
| 2109 |
- |
{ |
- |
| 2110 |
- |
CoerceViaIO *iocoerce = (CoerceViaIO *) node; |
- |
| 2111 |
- |
|
- |
| 2112 |
- |
/* since there is no exposed function, need to depend on type */ |
- |
| 2113 |
- |
add_object_address(TypeRelationId, iocoerce->resulttype, 0, |
- |
| 2114 |
- |
context->addrs); |
- |
| 2115 |
- |
/* the collation might not be referenced anywhere else, either */ |
- |
| 2116 |
- |
if (OidIsValid(iocoerce->resultcollid) && |
- |
| 2117 |
- |
iocoerce->resultcollid != DEFAULT_COLLATION_OID) |
- |
| 2118 |
- |
add_object_address(CollationRelationId, iocoerce->resultcollid, 0, |
- |
| 2119 |
- |
context->addrs); |
- |
| 2120 |
- |
} |
- |
| 2121 |
- |
else if (IsA(node, ArrayCoerceExpr)) |
- |
| 2122 |
- |
{ |
- |
| 2123 |
- |
ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; |
- |
| 2124 |
- |
|
- |
| 2125 |
- |
/* as above, depend on type */ |
- |
| 2126 |
- |
add_object_address(TypeRelationId, acoerce->resulttype, 0, |
- |
| 2127 |
- |
context->addrs); |
- |
| 2128 |
- |
/* the collation might not be referenced anywhere else, either */ |
- |
| 2129 |
- |
if (OidIsValid(acoerce->resultcollid) && |
- |
| 2130 |
- |
acoerce->resultcollid != DEFAULT_COLLATION_OID) |
- |
| 2131 |
- |
add_object_address(CollationRelationId, acoerce->resultcollid, 0, |
- |
| 2132 |
- |
context->addrs); |
- |
| 2133 |
- |
/* fall through to examine arguments */ |
- |
| 2134 |
- |
} |
- |
| 2135 |
- |
else if (IsA(node, ConvertRowtypeExpr)) |
- |
| 2136 |
- |
{ |
- |
| 2137 |
- |
ConvertRowtypeExpr *cvt = (ConvertRowtypeExpr *) node; |
- |
| 2138 |
- |
|
- |
| 2139 |
- |
/* since there is no function dependency, need to depend on type */ |
- |
| 2140 |
- |
add_object_address(TypeRelationId, cvt->resulttype, 0, |
- |
| 2141 |
- |
context->addrs); |
- |
| 2142 |
- |
} |
- |
| 2143 |
- |
else if (IsA(node, CollateExpr)) |
- |
| 2144 |
- |
{ |
- |
| 2145 |
- |
CollateExpr *coll = (CollateExpr *) node; |
- |
| 2146 |
- |
|
- |
| 2147 |
- |
add_object_address(CollationRelationId, coll->collOid, 0, |
- |
| 2148 |
- |
context->addrs); |
- |
| 2149 |
- |
} |
- |
| 2150 |
- |
else if (IsA(node, RowExpr)) |
- |
| 2151 |
- |
{ |
- |
| 2152 |
- |
RowExpr *rowexpr = (RowExpr *) node; |
- |
| 2153 |
- |
|
- |
| 2154 |
- |
add_object_address(TypeRelationId, rowexpr->row_typeid, 0, |
- |
| 2155 |
- |
context->addrs); |
- |
| 2156 |
- |
} |
- |
| 2157 |
- |
else if (IsA(node, RowCompareExpr)) |
- |
| 2158 |
- |
{ |
- |
| 2159 |
- |
RowCompareExpr *rcexpr = (RowCompareExpr *) node; |
- |
| 2160 |
- |
ListCell *l; |
- |
| 2161 |
- |
|
- |
| 2162 |
- |
foreach(l, rcexpr->opnos) |
- |
| 2163 |
- |
{ |
- |
| 2164 |
- |
add_object_address(OperatorRelationId, lfirst_oid(l), 0, |
- |
| 2165 |
- |
context->addrs); |
- |
| 2166 |
- |
} |
- |
| 2167 |
- |
foreach(l, rcexpr->opfamilies) |
- |
| 2168 |
- |
{ |
- |
| 2169 |
- |
add_object_address(OperatorFamilyRelationId, lfirst_oid(l), 0, |
- |
| 2170 |
- |
context->addrs); |
- |
| 2171 |
- |
} |
- |
| 2172 |
- |
/* fall through to examine arguments */ |
- |
| 2173 |
- |
} |
- |
| 2174 |
- |
else if (IsA(node, CoerceToDomain)) |
- |
| 2175 |
- |
{ |
- |
| 2176 |
- |
CoerceToDomain *cd = (CoerceToDomain *) node; |
- |
| 2177 |
- |
|
- |
| 2178 |
- |
add_object_address(TypeRelationId, cd->resulttype, 0, |
- |
| 2179 |
- |
context->addrs); |
- |
| 2180 |
- |
} |
- |
| 2181 |
- |
else if (IsA(node, NextValueExpr)) |
- |
| 2182 |
- |
{ |
- |
| 2183 |
- |
NextValueExpr *nve = (NextValueExpr *) node; |
- |
| 2184 |
- |
|
- |
| 2185 |
- |
add_object_address(RelationRelationId, nve->seqid, 0, |
- |
| 2186 |
- |
context->addrs); |
- |
| 2187 |
- |
} |
- |
| 2188 |
- |
else if (IsA(node, OnConflictExpr)) |
- |
| 2189 |
- |
{ |
- |
| 2190 |
- |
OnConflictExpr *onconflict = (OnConflictExpr *) node; |
- |
| 2191 |
- |
|
- |
| 2192 |
- |
if (OidIsValid(onconflict->constraint)) |
- |
| 2193 |
- |
add_object_address(ConstraintRelationId, onconflict->constraint, 0, |
- |
| 2194 |
- |
context->addrs); |
- |
| 2195 |
- |
/* fall through to examine arguments */ |
- |
| 2196 |
- |
} |
- |
| 2197 |
- |
else if (IsA(node, SortGroupClause)) |
- |
| 2198 |
- |
{ |
- |
| 2199 |
- |
SortGroupClause *sgc = (SortGroupClause *) node; |
- |
| 2200 |
- |
|
- |
| 2201 |
- |
add_object_address(OperatorRelationId, sgc->eqop, 0, |
- |
| 2202 |
- |
context->addrs); |
- |
| 2203 |
- |
if (OidIsValid(sgc->sortop)) |
- |
| 2204 |
- |
add_object_address(OperatorRelationId, sgc->sortop, 0, |
- |
| 2205 |
- |
context->addrs); |
- |
| 2206 |
- |
return false; |
- |
| 2207 |
- |
} |
- |
| 2208 |
- |
else if (IsA(node, WindowClause)) |
- |
| 2209 |
- |
{ |
- |
| 2210 |
- |
WindowClause *wc = (WindowClause *) node; |
- |
| 2211 |
- |
|
- |
| 2212 |
- |
if (OidIsValid(wc->startInRangeFunc)) |
- |
| 2213 |
- |
add_object_address(ProcedureRelationId, wc->startInRangeFunc, 0, |
- |
| 2214 |
- |
context->addrs); |
- |
| 2215 |
- |
if (OidIsValid(wc->endInRangeFunc)) |
- |
| 2216 |
- |
add_object_address(ProcedureRelationId, wc->endInRangeFunc, 0, |
- |
| 2217 |
- |
context->addrs); |
- |
| 2218 |
- |
if (OidIsValid(wc->inRangeColl) && |
- |
| 2219 |
- |
wc->inRangeColl != DEFAULT_COLLATION_OID) |
- |
| 2220 |
- |
add_object_address(CollationRelationId, wc->inRangeColl, 0, |
- |
| 2221 |
- |
context->addrs); |
- |
| 2222 |
- |
/* fall through to examine substructure */ |
- |
| 2223 |
- |
} |
- |
| 2224 |
- |
else if (IsA(node, CTECycleClause)) |
- |
| 2225 |
- |
{ |
- |
| 2226 |
- |
CTECycleClause *cc = (CTECycleClause *) node; |
- |
| 2227 |
- |
|
- |
| 2228 |
- |
if (OidIsValid(cc->cycle_mark_type)) |
- |
| 2229 |
- |
add_object_address(TypeRelationId, cc->cycle_mark_type, 0, |
- |
| 2230 |
- |
context->addrs); |
- |
| 2231 |
- |
if (OidIsValid(cc->cycle_mark_collation)) |
- |
| 2232 |
- |
add_object_address(CollationRelationId, cc->cycle_mark_collation, 0, |
- |
| 2233 |
- |
context->addrs); |
- |
| 2234 |
- |
if (OidIsValid(cc->cycle_mark_neop)) |
- |
| 2235 |
- |
add_object_address(OperatorRelationId, cc->cycle_mark_neop, 0, |
- |
| 2236 |
- |
context->addrs); |
- |
| 2237 |
- |
/* fall through to examine substructure */ |
- |
| 2238 |
- |
} |
- |
| 2239 |
- |
else if (IsA(node, Query)) |
- |
| 2240 |
- |
{ |
- |
| 2241 |
- |
/* Recurse into RTE subquery or not-yet-planned sublink subquery */ |
- |
| 2242 |
- |
Query *query = (Query *) node; |
- |
| 2243 |
- |
ListCell *lc; |
- |
| 2244 |
- |
bool result; |
- |
| 2245 |
- |
|
- |
| 2246 |
- |
/* |
- |
| 2247 |
- |
* Add whole-relation refs for each plain relation mentioned in the |
- |
| 2248 |
- |
* subquery's rtable, and ensure we add refs for any type-coercion |
- |
| 2249 |
- |
* functions used in join alias lists. |
- |
| 2250 |
- |
* |
- |
| 2251 |
- |
* Note: query_tree_walker takes care of recursing into RTE_FUNCTION |
- |
| 2252 |
- |
* RTEs, subqueries, etc, so no need to do that here. But we must |
- |
| 2253 |
- |
* tell it not to visit join alias lists, or we'll add refs for join |
- |
| 2254 |
- |
* input columns whether or not they are actually used in our query. |
- |
| 2255 |
- |
* |
- |
| 2256 |
- |
* Note: we don't need to worry about collations mentioned in |
- |
| 2257 |
- |
* RTE_VALUES or RTE_CTE RTEs, because those must just duplicate |
- |
| 2258 |
- |
* collations referenced in other parts of the Query. We do have to |
- |
| 2259 |
- |
* worry about collations mentioned in RTE_FUNCTION, but we take care |
- |
| 2260 |
- |
* of those when we recurse to the RangeTblFunction node(s). |
- |
| 2261 |
- |
*/ |
- |
| 2262 |
- |
foreach(lc, query->rtable) |
- |
| 2263 |
- |
{ |
- |
| 2264 |
- |
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); |
- |
| 2265 |
- |
|
- |
| 2266 |
- |
switch (rte->rtekind) |
- |
| 2267 |
- |
{ |
- |
| 2268 |
- |
case RTE_RELATION: |
- |
| 2269 |
- |
case RTE_GRAPH_TABLE: |
86c14eaWIP: SQL Property Graph Queries (SQL/PGQ) |
| 2270 |
- |
add_object_address(RelationRelationId, rte->relid, 0, |
- |
| 2271 |
- |
context->addrs); |
- |
| 2272 |
- |
break; |
- |
| 2273 |
- |
case RTE_JOIN: |
- |
| 2274 |
- |
|
- |
| 2275 |
- |
/* |
- |
| 2276 |
- |
* Examine joinaliasvars entries only for merged JOIN |
- |
| 2277 |
- |
* USING columns. Only those entries could contain |
- |
| 2278 |
- |
* type-coercion functions. Also, their join input |
- |
| 2279 |
- |
* columns must be referenced in the join quals, so this |
- |
| 2280 |
- |
* won't accidentally add refs to otherwise-unused join |
- |
| 2281 |
- |
* input columns. (We want to ref the type coercion |
- |
| 2282 |
- |
* functions even if the merged column isn't explicitly |
- |
| 2283 |
- |
* used anywhere, to protect possible expansion of the |
- |
| 2284 |
- |
* join RTE as a whole-row var, and because it seems like |
- |
| 2285 |
- |
* a bad idea to allow dropping a function that's present |
- |
| 2286 |
- |
* in our query tree, whether or not it could get called.) |
- |
| 2287 |
- |
*/ |
- |
| 2288 |
- |
context->rtables = lcons(query->rtable, context->rtables); |
- |
| 2289 |
- |
for (int i = 0; i < rte->joinmergedcols; i++) |
- |
| 2290 |
- |
{ |
- |
| 2291 |
- |
Node *aliasvar = list_nth(rte->joinaliasvars, i); |
- |
| 2292 |
- |
|
- |
| 2293 |
- |
if (!IsA(aliasvar, Var)) |
- |
| 2294 |
- |
find_expr_references_walker(aliasvar, context); |
- |
| 2295 |
- |
} |
- |
| 2296 |
- |
context->rtables = list_delete_first(context->rtables); |
- |
| 2297 |
- |
break; |
- |
| 2298 |
- |
case RTE_NAMEDTUPLESTORE: |
- |
| 2299 |
- |
|
- |
| 2300 |
- |
/* |
- |
| 2301 |
- |
* Cataloged objects cannot depend on tuplestores, because |
- |
| 2302 |
- |
* those have no cataloged representation. For now we can |
- |
| 2303 |
- |
* call the tuplestore a "transition table" because that's |
- |
| 2304 |
- |
* the only kind exposed to SQL, but someday we might have |
- |
| 2305 |
- |
* to work harder. |
- |
| 2306 |
- |
*/ |
- |
| 2307 |
- |
ereport(ERROR, |
- |
| 2308 |
- |
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
- |
| 2309 |
- |
errmsg("transition table \"%s\" cannot be referenced in a persistent object", |
- |
| 2310 |
- |
rte->eref->aliasname))); |
- |
| 2311 |
- |
break; |
- |
| 2312 |
- |
default: |
- |
| 2313 |
- |
/* Other RTE types can be ignored here */ |
- |
| 2314 |
- |
break; |
- |
| 2315 |
- |
} |
- |
| 2316 |
- |
} |
- |
| 2317 |
- |
|
- |
| 2318 |
- |
/* |
- |
| 2319 |
- |
* If the query is an INSERT or UPDATE, we should create a dependency |
- |
| 2320 |
- |
* on each target column, to prevent the specific target column from |
- |
| 2321 |
- |
* being dropped. Although we will visit the TargetEntry nodes again |
- |
| 2322 |
- |
* during query_tree_walker, we won't have enough context to do this |
- |
| 2323 |
- |
* conveniently, so do it here. |
- |
| 2324 |
- |
*/ |
- |
| 2325 |
- |
if (query->commandType == CMD_INSERT || |
- |
| 2326 |
- |
query->commandType == CMD_UPDATE) |
- |
| 2327 |
- |
{ |
- |
| 2328 |
- |
RangeTblEntry *rte; |
- |
| 2329 |
- |
|
- |
| 2330 |
- |
if (query->resultRelation <= 0 || |
- |
| 2331 |
- |
query->resultRelation > list_length(query->rtable)) |
- |
| 2332 |
- |
elog(ERROR, "invalid resultRelation %d", |
- |
| 2333 |
- |
query->resultRelation); |
- |
| 2334 |
- |
rte = rt_fetch(query->resultRelation, query->rtable); |
- |
| 2335 |
- |
if (rte->rtekind == RTE_RELATION) |
- |
| 2336 |
- |
{ |
- |
| 2337 |
- |
foreach(lc, query->targetList) |
- |
| 2338 |
- |
{ |
- |
| 2339 |
- |
TargetEntry *tle = (TargetEntry *) lfirst(lc); |
- |
| 2340 |
- |
|
- |
| 2341 |
- |
if (tle->resjunk) |
- |
| 2342 |
- |
continue; /* ignore junk tlist items */ |
- |
| 2343 |
- |
add_object_address(RelationRelationId, rte->relid, tle->resno, |
- |
| 2344 |
- |
context->addrs); |
- |
| 2345 |
- |
} |
- |
| 2346 |
- |
} |
- |
| 2347 |
- |
} |
- |
| 2348 |
- |
|
- |
| 2349 |
- |
/* |
- |
| 2350 |
- |
* Add dependencies on constraints listed in query's constraintDeps |
- |
| 2351 |
- |
*/ |
- |
| 2352 |
- |
foreach(lc, query->constraintDeps) |
- |
| 2353 |
- |
{ |
- |
| 2354 |
- |
add_object_address(ConstraintRelationId, lfirst_oid(lc), 0, |
- |
| 2355 |
- |
context->addrs); |
- |
| 2356 |
- |
} |
- |
| 2357 |
- |
|
- |
| 2358 |
- |
/* Examine substructure of query */ |
- |
| 2359 |
- |
context->rtables = lcons(query->rtable, context->rtables); |
- |
| 2360 |
- |
result = query_tree_walker(query, |
- |
| 2361 |
- |
find_expr_references_walker, |
- |
| 2362 |
- |
context, |
- |
| 2363 |
- |
QTW_IGNORE_JOINALIASES | |
- |
| 2364 |
- |
QTW_EXAMINE_SORTGROUP); |
- |
| 2365 |
- |
context->rtables = list_delete_first(context->rtables); |
- |
| 2366 |
- |
return result; |
- |
| 2367 |
- |
} |
- |
| 2368 |
- |
else if (IsA(node, SetOperationStmt)) |
- |
| 2369 |
- |
{ |
- |
| 2370 |
- |
SetOperationStmt *setop = (SetOperationStmt *) node; |
- |
| 2371 |
- |
|
- |
| 2372 |
- |
/* we need to look at the groupClauses for operator references */ |
- |
| 2373 |
- |
find_expr_references_walker((Node *) setop->groupClauses, context); |
- |
| 2374 |
- |
/* fall through to examine child nodes */ |
- |
| 2375 |
- |
} |
- |
| 2376 |
- |
else if (IsA(node, RangeTblFunction)) |
- |
| 2377 |
- |
{ |
- |
| 2378 |
- |
RangeTblFunction *rtfunc = (RangeTblFunction *) node; |
- |
| 2379 |
- |
ListCell *ct; |
- |
| 2380 |
- |
|
- |
| 2381 |
- |
/* |
- |
| 2382 |
- |
* Add refs for any datatypes and collations used in a column |
- |
| 2383 |
- |
* definition list for a RECORD function. (For other cases, it should |
- |
| 2384 |
- |
* be enough to depend on the function itself.) |
- |
| 2385 |
- |
*/ |
- |
| 2386 |
- |
foreach(ct, rtfunc->funccoltypes) |
- |
| 2387 |
- |
{ |
- |
| 2388 |
- |
add_object_address(TypeRelationId, lfirst_oid(ct), 0, |
- |
| 2389 |
- |
context->addrs); |
- |
| 2390 |
- |
} |
- |
| 2391 |
- |
foreach(ct, rtfunc->funccolcollations) |
- |
| 2392 |
- |
{ |
- |
| 2393 |
- |
Oid collid = lfirst_oid(ct); |
- |
| 2394 |
- |
|
- |
| 2395 |
- |
if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID) |
- |
| 2396 |
- |
add_object_address(CollationRelationId, collid, 0, |
- |
| 2397 |
- |
context->addrs); |
- |
| 2398 |
- |
} |
- |
| 2399 |
- |
} |
- |
| 2400 |
- |
else if (IsA(node, TableFunc)) |
- |
| 2401 |
- |
{ |
- |
| 2402 |
- |
TableFunc *tf = (TableFunc *) node; |
- |
| 2403 |
- |
ListCell *ct; |
- |
| 2404 |
- |
|
- |
| 2405 |
- |
/* |
- |
| 2406 |
- |
* Add refs for the datatypes and collations used in the TableFunc. |
- |
| 2407 |
- |
*/ |
- |
| 2408 |
- |
foreach(ct, tf->coltypes) |
- |
| 2409 |
- |
{ |
- |
| 2410 |
- |
add_object_address(TypeRelationId, lfirst_oid(ct), 0, |
- |
| 2411 |
- |
context->addrs); |
- |
| 2412 |
- |
} |
- |
| 2413 |
- |
foreach(ct, tf->colcollations) |
- |
| 2414 |
- |
{ |
- |
| 2415 |
- |
Oid collid = lfirst_oid(ct); |
- |
| 2416 |
- |
|
- |
| 2417 |
- |
if (OidIsValid(collid) && collid != DEFAULT_COLLATION_OID) |
- |
| 2418 |
- |
add_object_address(CollationRelationId, collid, 0, |
- |
| 2419 |
- |
context->addrs); |
- |
| 2420 |
- |
} |
- |
| 2421 |
- |
} |
- |
| 2422 |
- |
else if (IsA(node, TableSampleClause)) |
- |
| 2423 |
- |
{ |
- |
| 2424 |
- |
TableSampleClause *tsc = (TableSampleClause *) node; |
- |
| 2425 |
- |
|
- |
| 2426 |
- |
add_object_address(ProcedureRelationId, tsc->tsmhandler, 0, |
- |
| 2427 |
- |
context->addrs); |
- |
| 2428 |
- |
/* fall through to examine arguments */ |
- |
| 2429 |
- |
} |
- |
| 2430 |
- |
|
- |
| 2431 |
- |
return expression_tree_walker(node, find_expr_references_walker, |
- |
| 2432 |
- |
context); |
- |
| 2433 |
- |
} |
- |