Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.facebook.presto.sql.relational;
 
 
 import java.util.List;
 
 import static com.facebook.presto.spi.type.BigintType.BIGINT;
 import static com.facebook.presto.spi.type.BooleanType.BOOLEAN;
 import static com.facebook.presto.spi.type.DoubleType.DOUBLE;
 import static com.facebook.presto.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE;
 import static com.facebook.presto.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE;
 import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature;
 import static com.facebook.presto.spi.type.VarcharType.VARCHAR;
 import static com.facebook.presto.sql.relational.Expressions.call;
 import static com.facebook.presto.sql.relational.Expressions.constant;
 import static com.facebook.presto.sql.relational.Expressions.constantNull;
 import static com.facebook.presto.sql.relational.Expressions.field;
 import static com.facebook.presto.sql.relational.Signatures.arithmeticExpressionSignature;
 import static com.facebook.presto.sql.relational.Signatures.arithmeticNegationSignature;
 import static com.facebook.presto.sql.relational.Signatures.arrayConstructorSignature;
 import static com.facebook.presto.sql.relational.Signatures.betweenSignature;
 import static com.facebook.presto.sql.relational.Signatures.castSignature;
 import static com.facebook.presto.sql.relational.Signatures.coalesceSignature;
 import static com.facebook.presto.sql.relational.Signatures.comparisonExpressionSignature;
 import static com.facebook.presto.sql.relational.Signatures.likePatternSignature;
 import static com.facebook.presto.sql.relational.Signatures.likeSignature;
 import static com.facebook.presto.sql.relational.Signatures.logicalExpressionSignature;
 import static com.facebook.presto.sql.relational.Signatures.nullIfSignature;
 import static com.facebook.presto.sql.relational.Signatures.subscriptSignature;
 import static com.facebook.presto.sql.relational.Signatures.switchSignature;
 import static com.facebook.presto.sql.relational.Signatures.tryCastSignature;
 import static com.facebook.presto.sql.relational.Signatures.whenSignature;
 import static com.facebook.presto.type.LikePatternType.LIKE_PATTERN;
 import static com.facebook.presto.util.DateTimeUtils.parseDayTimeInterval;
 import static com.facebook.presto.util.DateTimeUtils.parseTimeWithTimeZone;
 import static com.facebook.presto.util.DateTimeUtils.parseTimeWithoutTimeZone;
 import static com.facebook.presto.util.DateTimeUtils.parseTimestampWithTimeZone;
 import static com.facebook.presto.util.DateTimeUtils.parseTimestampWithoutTimeZone;
import static com.facebook.presto.util.DateTimeUtils.parseYearMonthInterval;
import static com.facebook.presto.util.ImmutableCollectors.toImmutableList;
public final class SqlToRowExpressionTranslator
    private SqlToRowExpressionTranslator() {}
    public static RowExpression translate(
            Expression expression,
            IdentityHashMap<ExpressionTypetypes,
            FunctionRegistry functionRegistry,
            TypeManager typeManager,
            Session session,
            boolean optimize)
    {
        RowExpression result = new Visitor(typestypeManagersession.getTimeZoneKey()).process(expressionnull);
        Preconditions.checkNotNull(result"translated expression is null");
        if (optimize) {
            ExpressionOptimizer optimizer = new ExpressionOptimizer(functionRegistrytypeManagersession);
            return optimizer.optimize(result);
        }
        return result;
    }
    private static class Visitor
            extends AstVisitor<RowExpressionVoid>
    {
        private final IdentityHashMap<ExpressionTypetypes;
        private final TypeManager typeManager;
        private final TimeZoneKey timeZoneKey;
        private Visitor(IdentityHashMap<ExpressionTypetypesTypeManager typeManagerTimeZoneKey timeZoneKey)
        {
            this. = types;
            this. = typeManager;
            this. = timeZoneKey;
        }
        @Override
        protected RowExpression visitExpression(Expression nodeVoid context)
        {
            throw new UnsupportedOperationException("not yet implemented: expression translator for " + node.getClass().getName());
        }
        @Override
        protected RowExpression visitInputReference(InputReference nodeVoid context)
        {
            return field(node.getChannel(), .get(node));
        }
        @Override
        protected RowExpression visitNullLiteral(NullLiteral nodeVoid context)
        {
            return constantNull(.);
        }
        @Override
        protected RowExpression visitBooleanLiteral(BooleanLiteral nodeVoid context)
        {
            return constant(node.getValue(), );
        }
        @Override
        protected RowExpression visitLongLiteral(LongLiteral nodeVoid context)
        {
            return constant(node.getValue(), );
        }
        @Override
        protected RowExpression visitDoubleLiteral(DoubleLiteral nodeVoid context)
        {
            return constant(node.getValue(), );
        }
        @Override
        protected RowExpression visitStringLiteral(StringLiteral nodeVoid context)
        {
            return constant(node.getSlice(), );
        }
        @Override
        protected RowExpression visitGenericLiteral(GenericLiteral nodeVoid context)
        {
            Type type = .getType(parseTypeSignature(node.getType()));
            if (type == null) {
                throw new IllegalArgumentException("Unsupported type: " + node.getType());
            }
            return call(
                    castSignature(.get(node), ),
                    .get(node),
                    constant(Slices.copiedBuffer(node.getValue(), .), ));
        }
        @Override
        protected RowExpression visitTimeLiteral(TimeLiteral nodeVoid context)
        {
            long value;
            if (.get(node).equals()) {
                value = parseTimeWithTimeZone(node.getValue());
            }
            else {
                // parse in time zone of client
                value = parseTimeWithoutTimeZone(node.getValue());
            }
            return constant(value.get(node));
        }
        @Override
        protected RowExpression visitTimestampLiteral(TimestampLiteral nodeVoid context)
        {
            long value;
            if (.get(node).equals()) {
                value = parseTimestampWithTimeZone(node.getValue());
            }
            else {
                // parse in time zone of client
                value = parseTimestampWithoutTimeZone(node.getValue());
            }
            return constant(value.get(node));
        }
        @Override
        protected RowExpression visitIntervalLiteral(IntervalLiteral nodeVoid context)
        {
            long value;
            if (node.isYearToMonth()) {
                value = node.getSign().multiplier() * parseYearMonthInterval(node.getValue(), node.getStartField(), node.getEndField());
            }
            else {
                value = node.getSign().multiplier() * parseDayTimeInterval(node.getValue(), node.getStartField(), node.getEndField());
            }
            return constant(value.get(node));
        }
        @Override
        protected RowExpression visitComparisonExpression(ComparisonExpression nodeVoid context)
        {
            RowExpression left = process(node.getLeft(), context);
            RowExpression right = process(node.getRight(), context);
            return call(
                    comparisonExpressionSignature(node.getType(), left.getType(), right.getType()),
                    ,
                    left,
                    right);
        }
        @Override
        protected RowExpression visitFunctionCall(FunctionCall nodeVoid context)
        {
            List<RowExpressionarguments = node.getArguments().stream()
                    .map(value -> process(valuecontext))
                    .collect(toImmutableList());
            List<TypeSignatureargumentTypes = FluentIterable.from(arguments)
                    .transform(RowExpression::getType)
                    .transform(Type::getTypeSignature)
                    .toList();
            Signature signature = new Signature(node.getName().getSuffix(), .get(node).getTypeSignature(), argumentTypes);
            return call(signature.get(node), arguments);
        }
        @Override
        protected RowExpression visitArithmeticBinary(ArithmeticBinaryExpression nodeVoid context)
        {
            RowExpression left = process(node.getLeft(), context);
            RowExpression right = process(node.getRight(), context);
            return call(
                    arithmeticExpressionSignature(node.getType(), .get(node), left.getType(), right.getType()),
                    .get(node),
                    left,
                    right);
        }
        @Override
        protected RowExpression visitArithmeticUnary(ArithmeticUnaryExpression nodeVoid context)
        {
            RowExpression expression = process(node.getValue(), context);
            switch (node.getSign()) {
                case :
                    return expression;
                case :
                    return call(
                            arithmeticNegationSignature(.get(node), expression.getType()),
                            .get(node),
                            expression);
            }
            throw new UnsupportedOperationException("Unsupported unary operator: " + node.getSign());
        }
        @Override
        protected RowExpression visitLogicalBinaryExpression(LogicalBinaryExpression nodeVoid context)
        {
            return call(
                    logicalExpressionSignature(node.getType()),
                    ,
                    process(node.getLeft(), context),
                    process(node.getRight(), context));
        }
        @Override
        protected RowExpression visitCast(Cast nodeVoid context)
        {
            RowExpression value = process(node.getExpression(), context);
            if (node.isSafe()) {
                return call(tryCastSignature(.get(node), value.getType()), .get(node), value);
            }
            return call(castSignature(.get(node), value.getType()), .get(node), value);
        }
        @Override
        protected RowExpression visitCoalesceExpression(CoalesceExpression nodeVoid context)
        {
            List<RowExpressionarguments = node.getOperands().stream()
                            .map(value -> process(valuecontext))
                            .collect(toImmutableList());
            List<TypeargumentTypes = FluentIterable.from(arguments).transform(RowExpression::getType).toList();
            return call(coalesceSignature(.get(node), argumentTypes), .get(node), arguments);
        }
        @Override
        protected RowExpression visitSimpleCaseExpression(SimpleCaseExpression nodeVoid context)
        {
            ImmutableList.Builder<RowExpressionarguments = ImmutableList.builder();
            arguments.add(process(node.getOperand(), context));
            for (WhenClause clause : node.getWhenClauses()) {
                arguments.add(call(whenSignature(.get(clause)),
                        .get(clause),
                        process(clause.getOperand(), context),
                        process(clause.getResult(), context)));
            }
            Type returnType = .get(node);
            arguments.add(node.getDefaultValue()
                    .map((value) -> process(valuecontext))
                    .orElse(constantNull(returnType)));
            return call(switchSignature(returnType), returnTypearguments.build());
        }
        @Override
        protected RowExpression visitSearchedCaseExpression(SearchedCaseExpression nodeVoid context)
        {
            /*
                Translates an expression like:
                    case when cond1 then value1
                         when cond2 then value2
                         when cond3 then value3
                         else value4
                    end
                To:
                    IF(cond1,
                        value1,
                        IF(cond2,
                            value2,
                                If(cond3,
                                    value3,
                                    value4)))
             */
            RowExpression expression = node.getDefaultValue()
                    .map((value) -> process(valuecontext))
                    .orElse(constantNull(.get(node)));
            for (WhenClause clause : Lists.reverse(node.getWhenClauses())) {
                expression = call(
                        Signatures.ifSignature(.get(node)),
                        .get(node),
                        process(clause.getOperand(), context),
                        process(clause.getResult(), context),
                        expression);
            }
            return expression;
        }
        @Override
        protected RowExpression visitIfExpression(IfExpression nodeVoid context)
        {
            ImmutableList.Builder<RowExpressionarguments = ImmutableList.builder();
            arguments.add(process(node.getCondition(), context))
                    .add(process(node.getTrueValue(), context));
            if (node.getFalseValue().isPresent()) {
                arguments.add(process(node.getFalseValue().get(), context));
            }
            else {
                arguments.add(constantNull(.get(node)));
            }
            return call(Signatures.ifSignature(.get(node)), .get(node), arguments.build());
        }
        @Override
        protected RowExpression visitInPredicate(InPredicate nodeVoid context)
        {
            ImmutableList.Builder<RowExpressionarguments = ImmutableList.builder();
            arguments.add(process(node.getValue(), context));
            InListExpression values = (InListExpressionnode.getValueList();
            for (Expression value : values.getValues()) {
                arguments.add(process(valuecontext));
            }
            return call(Signatures.inSignature(), arguments.build());
        }
        @Override
        protected RowExpression visitIsNotNullPredicate(IsNotNullPredicate nodeVoid context)
        {
            RowExpression expression = process(node.getValue(), context);
            return call(
                    Signatures.notSignature(),
                    ,
                    call(Signatures.isNullSignature(expression.getType()), , ImmutableList.of(expression)));
        }
        @Override
        protected RowExpression visitIsNullPredicate(IsNullPredicate nodeVoid context)
        {
            RowExpression expression = process(node.getValue(), context);
            return call(Signatures.isNullSignature(expression.getType()), expression);
        }
        @Override
        protected RowExpression visitNotExpression(NotExpression nodeVoid context)
        {
            return call(Signatures.notSignature(), process(node.getValue(), context));
        }
        @Override
        protected RowExpression visitNullIfExpression(NullIfExpression nodeVoid context)
        {
            RowExpression first = process(node.getFirst(), context);
            RowExpression second = process(node.getSecond(), context);
            return call(
                    nullIfSignature(.get(node), first.getType(), second.getType()),
                    .get(node),
                    first,
                    second);
        }
        @Override
        protected RowExpression visitBetweenPredicate(BetweenPredicate nodeVoid context)
        {
            RowExpression value = process(node.getValue(), context);
            RowExpression min = process(node.getMin(), context);
            RowExpression max = process(node.getMax(), context);
            return call(
                    betweenSignature(value.getType(), min.getType(), max.getType()),
                    ,
                    value,
                    min,
                    max);
        }
        @Override
        protected RowExpression visitLikePredicate(LikePredicate nodeVoid context)
        {
            RowExpression value = process(node.getValue(), context);
            RowExpression pattern = process(node.getPattern(), context);
            if (node.getEscape() != null) {
                RowExpression escape = process(node.getEscape(), context);
                return call(likeSignature(), valuecall(likePatternSignature(), patternescape));
            }
            return call(likeSignature(), valuecall(castSignature(), pattern));
        }
        @Override
        protected RowExpression visitSubscriptExpression(SubscriptExpression nodeVoid context)
        {
            RowExpression base = process(node.getBase(), context);
            RowExpression index = process(node.getIndex(), context);
            return call(
                    subscriptSignature(.get(node), base.getType(), index.getType()),
                    .get(node),
                    base,
                    index);
        }
        @Override
        protected RowExpression visitArrayConstructor(ArrayConstructor nodeVoid context)
        {
            List<RowExpressionarguments = node.getValues().stream()
                    .map(value -> process(valuecontext))
                    .collect(toImmutableList());
            List<TypeargumentTypes = FluentIterable.from(arguments)
                    .transform(RowExpression::getType)
                    .toList();
            return call(arrayConstructorSignature(.get(node), argumentTypes), .get(node), arguments);
        }
    }
New to GrepCode? Check out our FAQ X