private Expression simplifyExpression(Expression input) {
   IdentityHashMap<Expression, Type> expressionTypes =
       getExpressionTypes(session, metadata, sqlParser, types, input);
   ExpressionInterpreter interpreter =
       ExpressionInterpreter.expressionOptimizer(input, metadata, session, expressionTypes);
   return LiteralInterpreter.toExpression(
       interpreter.optimize(NoOpSymbolResolver.INSTANCE), expressionTypes.get(input));
 }
    @Override
    public ActualProperties visitProject(ProjectNode node, List<ActualProperties> inputProperties) {
      ActualProperties properties = Iterables.getOnlyElement(inputProperties);

      Map<Symbol, Symbol> identities = computeIdentityTranslations(node.getAssignments());

      ActualProperties translatedProperties =
          properties.translate(column -> Optional.ofNullable(identities.get(column)));

      // Extract additional constants
      Map<Symbol, NullableValue> constants = new HashMap<>();
      for (Map.Entry<Symbol, Expression> assignment : node.getAssignments().entrySet()) {
        Expression expression = assignment.getValue();

        IdentityHashMap<Expression, Type> expressionTypes =
            getExpressionTypes(
                session,
                metadata,
                parser,
                types,
                expression,
                emptyList() /* parameters already replaced */);
        Type type = requireNonNull(expressionTypes.get(expression));
        ExpressionInterpreter optimizer =
            ExpressionInterpreter.expressionOptimizer(
                expression, metadata, session, expressionTypes);
        // TODO:
        // We want to use a symbol resolver that looks up in the constants from the input subplan
        // to take advantage of constant-folding for complex expressions
        // However, that currently causes errors when those expressions operate on arrays or row
        // types
        // ("ROW comparison not supported for fields with null elements", etc)
        Object value = optimizer.optimize(NoOpSymbolResolver.INSTANCE);

        if (value instanceof SymbolReference) {
          Symbol symbol = Symbol.from((SymbolReference) value);
          NullableValue existingConstantValue = constants.get(symbol);
          if (existingConstantValue != null) {
            constants.put(assignment.getKey(), new NullableValue(type, value));
          }
        } else if (!(value instanceof Expression)) {
          constants.put(assignment.getKey(), new NullableValue(type, value));
        }
      }
      constants.putAll(translatedProperties.getConstants());

      return ActualProperties.builderFrom(translatedProperties).constants(constants).build();
    }
Beispiel #3
0
 /** Evaluates an expression's response to binding the specified input symbols to NULL */
 private Object nullInputEvaluator(final Collection<Symbol> nullSymbols, Expression expression) {
   return ExpressionInterpreter.expressionOptimizer(expression, metadata, session)
       .optimize(
           new SymbolResolver() {
             @Override
             public Object getValue(Symbol symbol) {
               return nullSymbols.contains(symbol)
                   ? null
                   : new QualifiedNameReference(symbol.toQualifiedName());
             }
           });
 }