| 870 | var _ Visitor = &fastIsConstVisitor{} |
| 871 | |
| 872 | func (v *fastIsConstVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { |
| 873 | if v.visited { |
| 874 | if _, ok := expr.(*CastExpr); ok { |
| 875 | // We recurse one more time for cast expressions, since the |
| 876 | // NormalizeVisitor may have wrapped a NULL. |
| 877 | return true, expr |
| 878 | } |
| 879 | if _, ok := expr.(Datum); !ok || isVar(v.ctx, expr, true /*allowConstPlaceholders*/) { |
| 880 | // If the child expression is not a const Datum, the parent expression is |
| 881 | // not constant. Note that all constant literals have already been |
| 882 | // normalized to Datum in TypeCheck. |
| 883 | v.isConst = false |
| 884 | } |
| 885 | return false, expr |
| 886 | } |
| 887 | v.visited = true |
| 888 | |
| 889 | // If the parent expression is a variable or impure function, we know that it |
| 890 | // is not constant. |
| 891 | |
| 892 | if isVar(v.ctx, expr, true /*allowConstPlaceholders*/) { |
| 893 | v.isConst = false |
| 894 | return false, expr |
| 895 | } |
| 896 | |
| 897 | switch t := expr.(type) { |
| 898 | case *FuncExpr: |
| 899 | if t.IsImpure() { |
| 900 | v.isConst = false |
| 901 | return false, expr |
| 902 | } |
| 903 | } |
| 904 | |
| 905 | return true, expr |
| 906 | } |
| 907 | |
| 908 | func (*fastIsConstVisitor) VisitPost(expr Expr) Expr { return expr } |
| 909 | |