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.gen;
 
 
 import java.util.List;
 
 import static com.facebook.presto.byteCode.expression.ByteCodeExpressions.constantFalse;
 import static com.facebook.presto.byteCode.expression.ByteCodeExpressions.constantTrue;
 
 public class SwitchCodeGenerator
         implements ByteCodeGenerator
 {
     @Override
     public ByteCodeNode generateExpression(Signature signatureByteCodeGeneratorContext generatorContextType returnTypeList<RowExpressionarguments)
     {
         // TODO: compile as
         /*
             hashCode = hashCode(<value>)
 
             // all constant expressions before a non-constant
             switch (hashCode) {
                 case ...:
                     if (<value> == <constant1>) {
                        ...
                     }
                     else if (<value> == <constant2>) {
                        ...
                     }
                     else if (...) {
                     }
                 case ...:
                     ...
             }
 
             if (<value> == <non-constant1>) {
                 ...
             }
             else if (<value> == <non-constant2>) {
                 ...
             }
             ...
 
             // repeat with next sequence of constant expressions
          */
 
         Scope scope = generatorContext.getScope();
 
         // process value, else, and all when clauses
         RowExpression value = arguments.get(0);
         ByteCodeNode valueBytecode = generatorContext.generate(value);
         ByteCodeNode elseValue;
 
         List<RowExpressionwhenClauses;
         RowExpression last = arguments.get(arguments.size() - 1);
         if (last instanceof CallExpression && ((CallExpressionlast).getSignature().getName().equals("WHEN")) {
             whenClauses = arguments.subList(1, arguments.size());
             elseValue = new Block()
                     .append(generatorContext.wasNull().set(constantTrue()))
                     .pushJavaDefault(returnType.getJavaType());
         }
         else {
             whenClauses = arguments.subList(1, arguments.size() - 1);
             elseValue = generatorContext.generate(last);
         }
 
         // determine the type of the value and result
         Class<?> valueType = value.getType().getJavaType();
 
         // evaluate the value and store it in a variable
         LabelNode nullValue = new LabelNode("nullCondition");
         Variable tempVariable = scope.createTempVariable(valueType);
        Block block = new Block()
                .append(valueBytecode)
                .append(ByteCodeUtils.ifWasNullClearPopAndGoto(scopenullValuevoid.classvalueType))
                .putVariable(tempVariable);
        ByteCodeNode getTempVariableNode = VariableInstruction.loadVariable(tempVariable);
        // build the statements
        elseValue = new Block().visitLabel(nullValue).append(elseValue);
        // reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
        for (RowExpression clause : Lists.reverse(whenClauses)) {
            Preconditions.checkArgument(clause instanceof CallExpression && ((CallExpressionclause).getSignature().getName().equals("WHEN"));
            RowExpression operand = ((CallExpressionclause).getArguments().get(0);
            RowExpression result = ((CallExpressionclause).getArguments().get(1);
            // call equals(value, operand)
            FunctionInfo equalsFunction = generatorContext.getRegistry().resolveOperator(., ImmutableList.of(value.getType(), operand.getType()));
            // TODO: what if operand is null? It seems that the call will return "null" (which is cleared below)
            // and the code only does the right thing because the value in the stack for that scenario is
            // Java's default for boolean == false
            // This code should probably be checking for wasNull after the call and "failing" the equality
            // check if wasNull is true
            ByteCodeNode equalsCall = generatorContext.generateCall(
                    equalsFunction,
                    ImmutableList.of(generatorContext.generate(operand), getTempVariableNode));
            Block condition = new Block()
                    .append(equalsCall)
                    .append(generatorContext.wasNull().set(constantFalse()));
            elseValue = new IfStatement("when")
                    .condition(condition)
                    .ifTrue(generatorContext.generate(result))
                    .ifFalse(elseValue);
        }
        return block.append(elseValue);
    }
New to GrepCode? Check out our FAQ X