Recursively removed potentially multiple aliases from an expression. This method removes nested aliases and returns [`Transformed`] to signal if the expression was changed. # Example ``` # use datafusion_expr::col; // `foo as "bar"` is unaliased to `foo` let expr = col("foo").alias("bar"); assert_eq!(expr.unalias_nested().data, col("foo")); // `foo as "bar" + baz` is unaliased let expr = col("
(self)
| 1890 | /// assert_eq!(expr.unalias_nested().data, col("foo")); |
| 1891 | /// ``` |
| 1892 | pub fn unalias_nested(self) -> Transformed<Expr> { |
| 1893 | self.transform_down_up( |
| 1894 | |expr| { |
| 1895 | // f_down: skip subqueries. Check in f_down to avoid recursing into them |
| 1896 | let recursion = if matches!( |
| 1897 | expr, |
| 1898 | Expr::Exists { .. } | Expr::ScalarSubquery(_) | Expr::InSubquery(_) |
| 1899 | ) { |
| 1900 | // Subqueries could contain aliases so don't recurse into those |
| 1901 | TreeNodeRecursion::Jump |
| 1902 | } else { |
| 1903 | TreeNodeRecursion::Continue |
| 1904 | }; |
| 1905 | Ok(Transformed::new(expr, false, recursion)) |
| 1906 | }, |
| 1907 | |expr| { |
| 1908 | // f_up: unalias on up so we can remove nested aliases like |
| 1909 | // `(x as foo) as bar` |
| 1910 | if let Expr::Alias(alias) = expr { |
| 1911 | match alias |
| 1912 | .metadata |
| 1913 | .as_ref() |
| 1914 | .map(|h| h.is_empty()) |
| 1915 | .unwrap_or(true) |
| 1916 | { |
| 1917 | true => Ok(Transformed::yes(*alias.expr)), |
| 1918 | false => Ok(Transformed::no(Expr::Alias(alias))), |
| 1919 | } |
| 1920 | } else { |
| 1921 | Ok(Transformed::no(expr)) |
| 1922 | } |
| 1923 | }, |
| 1924 | ) |
| 1925 | // Unreachable code: internal closure doesn't return err |
| 1926 | .unwrap() |
| 1927 | } |
| 1928 | |
| 1929 | /// Return `self IN <list>` if `negated` is false, otherwise |
| 1930 | /// return `self NOT IN <list>`.a |