Java Code Examples for org.apache.calcite.linq4j.tree.BlockBuilder#add()

The following examples show how to use org.apache.calcite.linq4j.tree.BlockBuilder#add() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ExpressionTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testFor() throws NoSuchFieldException {
  final BlockBuilder builder = new BlockBuilder();
  final ParameterExpression i_ = Expressions.parameter(int.class, "i");
  builder.add(
      Expressions.for_(
          Expressions.declare(
              0, i_, Expressions.constant(0)),
          Expressions.lessThan(i_, Expressions.constant(10)),
          Expressions.postIncrementAssign(i_),
          Expressions.block(
              Expressions.statement(
                  Expressions.call(
                      Expressions.field(
                          null, System.class.getField("out")),
                      "println",
                      i_)))));
  assertEquals(
      "{\n"
          + "  for (int i = 0; i < 10; i++) {\n"
          + "    System.out.println(i);\n"
          + "  }\n"
          + "}\n",
      Expressions.toString(builder.toBlock()));
}
 
Example 2
Source File: InlinerTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
void checkAssignInConditionOptimizedOut(int modifiers, String s) {
  // int t;
  // return (t = 1) != a ? b : c
  final BlockBuilder builder = new BlockBuilder(true);
  final ParameterExpression t =
      Expressions.parameter(int.class, "t");

  builder.add(Expressions.declare(modifiers, t, null));

  Expression v = builder.append("v",
      Expressions.makeTernary(ExpressionType.Conditional,
          Expressions.makeBinary(ExpressionType.NotEqual,
              Expressions.assign(t, Expressions.constant(1)),
              Expressions.parameter(int.class, "a")),
          Expressions.parameter(int.class, "b"),
          Expressions.parameter(int.class, "c")));
  builder.add(Expressions.return_(null, v));
  assertThat(Expressions.toString(builder.toBlock()),
      CoreMatchers.equalTo(s));
}
 
Example 3
Source File: BlockBuilderTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testTestCustomOptimizer() {
  BlockBuilder b = new BlockBuilder() {
    @Override protected Shuttle createOptimizeShuttle() {
      return new OptimizeShuttle() {
        @Override public Expression visit(BinaryExpression binary,
            Expression expression0, Expression expression1) {
          if (binary.getNodeType() == ExpressionType.Add
              && ONE.equals(expression0) && TWO.equals(expression1)) {
            return FOUR;
          }
          return super.visit(binary, expression0, expression1);
        }
      };
    }
  };
  b.add(Expressions.return_(null, Expressions.add(ONE, TWO)));
  assertEquals("{\n  return 4;\n}\n", b.toBlock().toString());
}
 
Example 4
Source File: EnumerableToSparkConverter.java    From calcite with Apache License 2.0 6 votes vote down vote up
public Result implementSpark(Implementor implementor) {
  // Generate:
  //   Enumerable source = ...;
  //   return SparkRuntime.createRdd(sparkContext, source);
  final BlockBuilder list = new BlockBuilder();
  final EnumerableRel child = (EnumerableRel) getInput();
  final PhysType physType =
      PhysTypeImpl.of(
          implementor.getTypeFactory(), getRowType(),
          JavaRowFormat.CUSTOM);
  final Expression source = null; // TODO:
  final Expression sparkContext =
      Expressions.call(
          SparkMethod.GET_SPARK_CONTEXT.method,
          implementor.getRootExpression());
  final Expression rdd =
      list.append(
          "rdd",
          Expressions.call(
              SparkMethod.CREATE_RDD.method,
              sparkContext,
              source));
  list.add(
      Expressions.return_(null, rdd));
  return implementor.result(physType, list.toBlock());
}
 
Example 5
Source File: InlinerTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testMultiPassOptimization() {
  // int t = u + v;
  // boolean b = t > 1 ? true : true; -- optimized out, thus t can be inlined
  // return b ? t : 2
  final BlockBuilder builder = new BlockBuilder(true);
  final ParameterExpression u = Expressions.parameter(int.class, "u");
  final ParameterExpression v = Expressions.parameter(int.class, "v");

  Expression t = builder.append("t", Expressions.add(u, v));
  Expression b = builder.append("b",
      Expressions.condition(Expressions.greaterThan(t, ONE), TRUE, TRUE));

  builder.add(Expressions.return_(null, Expressions.condition(b, t, TWO)));
  assertEquals(
      "{\n"
          + "  return u + v;\n"
          + "}\n",
      Expressions.toString(builder.toBlock()));
}
 
Example 6
Source File: ExpressionCompiler.java    From attic-apex-malhar with Apache License 2.0 5 votes vote down vote up
/**
 * Create quasi-Java expression from given {@link RexNode}
 *
 * @param node Expression in the form of {@link RexNode}
 * @param inputRowType Input Data type to expression in the form of {@link RelDataType}
 * @param outputRowType Output data type of expression in the form of {@link RelDataType}
 *
 * @return Returns quasi-Java expression
 */
public String getExpression(RexNode node, RelDataType inputRowType, RelDataType outputRowType)
{
  final RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder);
  programBuilder.addProject(node, null);
  final RexProgram program = programBuilder.getProgram();

  final BlockBuilder builder = new BlockBuilder();
  final JavaTypeFactory javaTypeFactory = (JavaTypeFactory)rexBuilder.getTypeFactory();

  final RexToLixTranslator.InputGetter inputGetter = new RexToLixTranslator.InputGetterImpl(ImmutableList
      .of(Pair.<Expression, PhysType>of(Expressions.variable(Object[].class, "inputValues"),
      PhysTypeImpl.of(javaTypeFactory, inputRowType, JavaRowFormat.ARRAY, false))));
  final Function1<String, RexToLixTranslator.InputGetter> correlates =
      new Function1<String, RexToLixTranslator.InputGetter>()
    {
      public RexToLixTranslator.InputGetter apply(String a0)
      {
        throw new UnsupportedOperationException();
      }
    };

  final List<Expression> list = RexToLixTranslator.translateProjects(program, javaTypeFactory, builder,
      PhysTypeImpl.of(javaTypeFactory, outputRowType, JavaRowFormat.ARRAY, false), null, inputGetter, correlates);

  for (int i = 0; i < list.size(); i++) {
    Statement statement = Expressions.statement(list.get(i));
    builder.add(statement);
  }

  return finalizeExpression(builder.toBlock(), inputRowType);
}
 
Example 7
Source File: EnumerableCollect.java    From calcite with Apache License 2.0 5 votes vote down vote up
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
  final BlockBuilder builder = new BlockBuilder();
  final EnumerableRel child = (EnumerableRel) getInput();
  // REVIEW zabetak January 7, 2019: Even if we ask the implementor to provide a result
  // where records are represented as arrays (Prefer.ARRAY) this may not be respected.
  final Result result = implementor.visitChild(this, 0, child, Prefer.ARRAY);
  final PhysType physType =
      PhysTypeImpl.of(
          implementor.getTypeFactory(),
          getRowType(),
          JavaRowFormat.LIST);

  // final Enumerable child = <<child adapter>>;
  // final Enumerable<Object[]> converted = child.select(<<conversion code>>);
  // final List<Object[]> list = converted.toList();
  Expression child_ =
      builder.append(
          "child", result.block);
  // In the internal representation of multisets , every element must be a record. In case the
  // result above is a scalar type we have to wrap it around a physical type capable of
  // representing records. For this reason the following conversion is necessary.
  // REVIEW zabetak January 7, 2019: If we can ensure that the input to this operator
  // has the correct physical type (e.g., respecting the Prefer.ARRAY above) then this conversion
  // can be removed.
  Expression conv_ =
      builder.append(
          "converted", result.physType.convertTo(child_, JavaRowFormat.ARRAY));
  Expression list_ =
      builder.append("list",
          Expressions.call(conv_,
              BuiltInMethod.ENUMERABLE_TO_LIST.method));

  builder.add(
      Expressions.return_(null,
          Expressions.call(
              BuiltInMethod.SINGLETON_ENUMERABLE.method, list_)));
  return implementor.result(physType, builder.toBlock());
}
 
Example 8
Source File: EnumerableRepeatUnion.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public Result implement(EnumerableRelImplementor implementor, Prefer pref) {

    // return repeatUnion(<seedExp>, <iterativeExp>, iterationLimit, all, <comparer>);

    BlockBuilder builder = new BlockBuilder();
    RelNode seed = getSeedRel();
    RelNode iteration = getIterativeRel();

    Result seedResult = implementor.visitChild(this, 0, (EnumerableRel) seed, pref);
    Result iterationResult = implementor.visitChild(this, 1, (EnumerableRel) iteration, pref);

    Expression seedExp = builder.append("seed", seedResult.block);
    Expression iterativeExp = builder.append("iteration", iterationResult.block);

    PhysType physType = PhysTypeImpl.of(
        implementor.getTypeFactory(),
        getRowType(),
        pref.prefer(seedResult.format));

    Expression unionExp = Expressions.call(
        BuiltInMethod.REPEAT_UNION.method,
        seedExp,
        iterativeExp,
        Expressions.constant(iterationLimit, int.class),
        Expressions.constant(all, boolean.class),
        Util.first(physType.comparer(), Expressions.call(BuiltInMethod.IDENTITY_COMPARER.method)));
    builder.add(unionExp);

    return implementor.result(physType, builder.toBlock());
  }
 
Example 9
Source File: EnumerableAggregateBase.java    From calcite with Apache License 2.0 5 votes vote down vote up
protected List<Type> createAggStateTypes(
    final List<Expression> initExpressions,
    final BlockBuilder initBlock,
    final List<AggImpState> aggs,
    JavaTypeFactory typeFactory) {
  final List<Type> aggStateTypes = new ArrayList<>();
  for (final AggImpState agg : aggs) {
    agg.context = new AggContextImpl(agg, typeFactory);
    final List<Type> state = agg.implementor.getStateType(agg.context);

    if (state.isEmpty()) {
      agg.state = ImmutableList.of();
      continue;
    }

    aggStateTypes.addAll(state);

    final List<Expression> decls = new ArrayList<>(state.size());
    for (int i = 0; i < state.size(); i++) {
      String aggName = "a" + agg.aggIdx;
      if (CalciteSystemProperty.DEBUG.value()) {
        aggName = Util.toJavaId(agg.call.getAggregation().getName(), 0)
            .substring("ID$0$".length()) + aggName;
      }
      Type type = state.get(i);
      ParameterExpression pe =
          Expressions.parameter(type,
              initBlock.newName(aggName + "s" + i));
      initBlock.add(Expressions.declare(0, pe, null));
      decls.add(pe);
    }
    agg.state = decls;
    initExpressions.addAll(decls);
    agg.implementor.implementReset(agg.context,
        new AggResultContextImpl(initBlock, agg.call, decls, null, null));
  }
  return aggStateTypes;
}
 
Example 10
Source File: RexExecutorImpl.java    From calcite with Apache License 2.0 5 votes vote down vote up
private static String compile(RexBuilder rexBuilder, List<RexNode> constExps,
    RexToLixTranslator.InputGetter getter, RelDataType rowType) {
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(rowType, rexBuilder);
  for (RexNode node : constExps) {
    programBuilder.addProject(
        node, "c" + programBuilder.getProjectList().size());
  }
  final JavaTypeFactoryImpl javaTypeFactory =
      new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());
  final BlockBuilder blockBuilder = new BlockBuilder();
  final ParameterExpression root0_ =
      Expressions.parameter(Object.class, "root0");
  final ParameterExpression root_ = DataContext.ROOT;
  blockBuilder.add(
      Expressions.declare(
          Modifier.FINAL, root_,
          Expressions.convert_(root0_, DataContext.class)));
  final SqlConformance conformance = SqlConformanceEnum.DEFAULT;
  final RexProgram program = programBuilder.getProgram();
  final List<Expression> expressions =
      RexToLixTranslator.translateProjects(program, javaTypeFactory,
          conformance, blockBuilder, null, root_, getter, null);
  blockBuilder.add(
      Expressions.return_(null,
          Expressions.newArrayInit(Object[].class, expressions)));
  final MethodDeclaration methodDecl =
      Expressions.methodDecl(Modifier.PUBLIC, Object[].class,
          BuiltInMethod.FUNCTION1_APPLY.method.getName(),
          ImmutableList.of(root0_), blockBuilder.toBlock());
  String code = Expressions.toString(methodDecl);
  if (CalciteSystemProperty.DEBUG.value()) {
    Util.debugCode(System.out, code);
  }
  return code;
}
 
Example 11
Source File: EnumerableValues.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
/*
          return Linq4j.asEnumerable(
              new Object[][] {
                  new Object[] {1, 2},
                  new Object[] {3, 4}
              });
*/
    final JavaTypeFactory typeFactory =
        (JavaTypeFactory) getCluster().getTypeFactory();
    final BlockBuilder builder = new BlockBuilder();
    final PhysType physType =
        PhysTypeImpl.of(
            implementor.getTypeFactory(),
            getRowType(),
            pref.preferCustom());
    final Type rowClass = physType.getJavaRowType();

    final List<Expression> expressions = new ArrayList<>();
    final List<RelDataTypeField> fields = rowType.getFieldList();
    for (List<RexLiteral> tuple : tuples) {
      final List<Expression> literals = new ArrayList<>();
      for (Pair<RelDataTypeField, RexLiteral> pair
          : Pair.zip(fields, tuple)) {
        literals.add(
            RexToLixTranslator.translateLiteral(
                pair.right,
                pair.left.getType(),
                typeFactory,
                RexImpTable.NullAs.NULL));
      }
      expressions.add(physType.record(literals));
    }
    builder.add(
        Expressions.return_(
            null,
            Expressions.call(
                BuiltInMethod.AS_ENUMERABLE.method,
                Expressions.newArrayInit(
                    Primitive.box(rowClass), expressions))));
    return implementor.result(physType, builder.toBlock());
  }
 
Example 12
Source File: PhysTypeImpl.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Expression generateComparator(RelCollation collation) {
  // int c;
  // c = Utilities.compare(v0, v1);
  // if (c != 0) return c; // or -c if descending
  // ...
  // return 0;
  BlockBuilder body = new BlockBuilder();
  final Type javaRowClass = Primitive.box(this.javaRowClass);
  final ParameterExpression parameterV0 =
      Expressions.parameter(javaRowClass, "v0");
  final ParameterExpression parameterV1 =
      Expressions.parameter(javaRowClass, "v1");
  final ParameterExpression parameterC =
      Expressions.parameter(int.class, "c");
  final int mod =
      collation.getFieldCollations().size() == 1 ? Modifier.FINAL : 0;
  body.add(Expressions.declare(mod, parameterC, null));
  for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
    final int index = fieldCollation.getFieldIndex();
    final RelDataType fieldType = rowType.getFieldList().get(index).getType();
    final Expression fieldComparator = generateCollatorExpression(fieldType.getCollation());
    Expression arg0 = fieldReference(parameterV0, index);
    Expression arg1 = fieldReference(parameterV1, index);
    switch (Primitive.flavor(fieldClass(index))) {
    case OBJECT:
      arg0 = EnumUtils.convert(arg0, Comparable.class);
      arg1 = EnumUtils.convert(arg1, Comparable.class);
    }
    final boolean nullsFirst =
        fieldCollation.nullDirection
            == RelFieldCollation.NullDirection.FIRST;
    final boolean descending =
        fieldCollation.getDirection()
            == RelFieldCollation.Direction.DESCENDING;
    body.add(
        Expressions.statement(
            Expressions.assign(
                parameterC,
                Expressions.call(
                    Utilities.class,
                    fieldNullable(index)
                        ? (nullsFirst != descending
                        ? "compareNullsFirst"
                        : "compareNullsLast")
                        : "compare",
                    Expressions.list(
                        arg0,
                        arg1)
                        .appendIfNotNull(fieldComparator)))));
    body.add(
        Expressions.ifThen(
            Expressions.notEqual(
                parameterC, Expressions.constant(0)),
            Expressions.return_(
                null,
                descending
                    ? Expressions.negate(parameterC)
                    : parameterC)));
  }
  body.add(
      Expressions.return_(null, Expressions.constant(0)));

  final List<MemberDeclaration> memberDeclarations =
      Expressions.list(
          Expressions.methodDecl(
              Modifier.PUBLIC,
              int.class,
              "compare",
              ImmutableList.of(parameterV0, parameterV1),
              body.toBlock()));

  if (EnumerableRules.BRIDGE_METHODS) {
    final ParameterExpression parameterO0 =
        Expressions.parameter(Object.class, "o0");
    final ParameterExpression parameterO1 =
        Expressions.parameter(Object.class, "o1");
    BlockBuilder bridgeBody = new BlockBuilder();
    bridgeBody.add(
        Expressions.return_(
            null,
            Expressions.call(
                Expressions.parameter(
                    Comparable.class, "this"),
                BuiltInMethod.COMPARATOR_COMPARE.method,
                Expressions.convert_(
                    parameterO0,
                    javaRowClass),
                Expressions.convert_(
                    parameterO1,
                    javaRowClass))));
    memberDeclarations.add(
        overridingMethodDecl(
            BuiltInMethod.COMPARATOR_COMPARE.method,
            ImmutableList.of(parameterO0, parameterO1),
            bridgeBody.toBlock()));
  }
  return Expressions.new_(
      Comparator.class,
      ImmutableList.of(),
      memberDeclarations);
}
 
Example 13
Source File: ExpressionTest.java    From calcite with Apache License 2.0 4 votes vote down vote up
@Test void testBlockBuilder3() {
/*
    int a = 1;
    int b = a + 2;
    int c = a + 3;
    int d = a + 4;
    int e = {
      int b = a + 3;
      foo(b);
    }
    bar(a, b, c, d, e);
*/
    BlockBuilder builder0 = new BlockBuilder();
    final Expression a = builder0.append("_a", Expressions.constant(1));
    final Expression b =
        builder0.append("_b", Expressions.add(a, Expressions.constant(2)));
    final Expression c =
        builder0.append("_c", Expressions.add(a, Expressions.constant(3)));
    final Expression d =
        builder0.append("_d", Expressions.add(a, Expressions.constant(4)));

    BlockBuilder builder1 = new BlockBuilder();
    final Expression b1 =
        builder1.append("_b", Expressions.add(a, Expressions.constant(3)));
    builder1.add(
        Expressions.statement(
            Expressions.call(ExpressionTest.class, "foo", b1)));
    final Expression e = builder0.append("e", builder1.toBlock());
    builder0.add(
        Expressions.statement(
            Expressions.call(ExpressionTest.class, "bar", a, b, c, d, e)));
    // With the bug in BlockBuilder.append(String, BlockExpression),
    //    bar(1, _b, _c, _d, foo(_d));
    // Correct result is
    //    bar(1, _b, _c, _d, foo(_c));
    // because _c has the same expression (a + 3) as inner b.
    BlockStatement expression = builder0.toBlock();
    assertEquals(
        "{\n"
            + "  final int _b = 1 + 2;\n"
            + "  final int _c = 1 + 3;\n"
            + "  final int _d = 1 + 4;\n"
            + "  final int _b0 = 1 + 3;\n"
            + "  org.apache.calcite.linq4j.test.ExpressionTest.bar(1, _b, _c, _d, org.apache.calcite.linq4j.test.ExpressionTest.foo(_b0));\n"
            + "}\n",
        Expressions.toString(expression));
    expression.accept(new Shuttle());
  }
 
Example 14
Source File: JaninoRexCompiler.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Scalar compile(List<RexNode> nodes, RelDataType inputRowType) {
  final RexProgramBuilder programBuilder =
      new RexProgramBuilder(inputRowType, rexBuilder);
  for (RexNode node : nodes) {
    programBuilder.addProject(node, null);
  }
  final RexProgram program = programBuilder.getProgram();

  final BlockBuilder builder = new BlockBuilder();
  final ParameterExpression context_ =
      Expressions.parameter(Context.class, "context");
  final ParameterExpression outputValues_ =
      Expressions.parameter(Object[].class, "outputValues");
  final JavaTypeFactoryImpl javaTypeFactory =
      new JavaTypeFactoryImpl(rexBuilder.getTypeFactory().getTypeSystem());

  // public void execute(Context, Object[] outputValues)
  final RexToLixTranslator.InputGetter inputGetter =
      new RexToLixTranslator.InputGetterImpl(
          ImmutableList.of(
              Pair.of(
                  Expressions.field(context_,
                      BuiltInMethod.CONTEXT_VALUES.field),
                  PhysTypeImpl.of(javaTypeFactory, inputRowType,
                      JavaRowFormat.ARRAY, false))));
  final Function1<String, RexToLixTranslator.InputGetter> correlates = a0 -> {
    throw new UnsupportedOperationException();
  };
  final Expression root =
      Expressions.field(context_, BuiltInMethod.CONTEXT_ROOT.field);
  final SqlConformance conformance =
      SqlConformanceEnum.DEFAULT; // TODO: get this from implementor
  final List<Expression> list =
      RexToLixTranslator.translateProjects(program, javaTypeFactory,
          conformance, builder, null, root, inputGetter, correlates);
  for (int i = 0; i < list.size(); i++) {
    builder.add(
        Expressions.statement(
            Expressions.assign(
                Expressions.arrayIndex(outputValues_,
                    Expressions.constant(i)),
                list.get(i))));
  }
  return baz(context_, outputValues_, builder.toBlock());
}
 
Example 15
Source File: EnumerableAggregateBase.java    From calcite with Apache License 2.0 4 votes vote down vote up
protected void createAccumulatorAdders(
    final ParameterExpression inParameter,
    final List<AggImpState> aggs,
    final PhysType accPhysType,
    final ParameterExpression accExpr,
    final PhysType inputPhysType,
    final BlockBuilder builder,
    EnumerableRelImplementor implementor,
    JavaTypeFactory typeFactory) {
  for (int i = 0, stateOffset = 0; i < aggs.size(); i++) {
    final BlockBuilder builder2 = new BlockBuilder();
    final AggImpState agg = aggs.get(i);

    final int stateSize = agg.state.size();
    final List<Expression> accumulator = new ArrayList<>(stateSize);
    for (int j = 0; j < stateSize; j++) {
      accumulator.add(accPhysType.fieldReference(accExpr, j + stateOffset));
    }
    agg.state = accumulator;

    stateOffset += stateSize;

    AggAddContext addContext =
        new AggAddContextImpl(builder2, accumulator) {
          public List<RexNode> rexArguments() {
            List<RelDataTypeField> inputTypes =
                inputPhysType.getRowType().getFieldList();
            List<RexNode> args = new ArrayList<>();
            for (int index : agg.call.getArgList()) {
              args.add(RexInputRef.of(index, inputTypes));
            }
            return args;
          }

          public RexNode rexFilterArgument() {
            return agg.call.filterArg < 0
                ? null
                : RexInputRef.of(agg.call.filterArg,
                    inputPhysType.getRowType());
          }

          public RexToLixTranslator rowTranslator() {
            return RexToLixTranslator.forAggregation(typeFactory,
                currentBlock(),
                new RexToLixTranslator.InputGetterImpl(
                    Collections.singletonList(
                        Pair.of(inParameter, inputPhysType))),
                implementor.getConformance())
                .setNullable(currentNullables());
          }
        };

    agg.implementor.implementAdd(agg.context, addContext);
    builder2.add(accExpr);
    agg.accumulatorAdder = builder.append("accumulatorAdder",
        Expressions.lambda(Function2.class, builder2.toBlock(), accExpr,
            inParameter));
  }
}
 
Example 16
Source File: JaninoRexCompiler.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Given a method that implements {@link Scalar#execute(Context, Object[])},
 * adds a bridge method that implements {@link Scalar#execute(Context)}, and
 * compiles. */
static Scalar baz(ParameterExpression context_,
    ParameterExpression outputValues_, BlockStatement block) {
  final List<MemberDeclaration> declarations = new ArrayList<>();

  // public void execute(Context, Object[] outputValues)
  declarations.add(
      Expressions.methodDecl(Modifier.PUBLIC, void.class,
          BuiltInMethod.SCALAR_EXECUTE2.method.getName(),
          ImmutableList.of(context_, outputValues_), block));

  // public Object execute(Context)
  final BlockBuilder builder = new BlockBuilder();
  final Expression values_ = builder.append("values",
      Expressions.newArrayBounds(Object.class, 1,
          Expressions.constant(1)));
  builder.add(
      Expressions.statement(
          Expressions.call(
              Expressions.parameter(Scalar.class, "this"),
              BuiltInMethod.SCALAR_EXECUTE2.method, context_, values_)));
  builder.add(
      Expressions.return_(null,
          Expressions.arrayIndex(values_, Expressions.constant(0))));
  declarations.add(
      Expressions.methodDecl(Modifier.PUBLIC, Object.class,
          BuiltInMethod.SCALAR_EXECUTE1.method.getName(),
          ImmutableList.of(context_), builder.toBlock()));

  final ClassDeclaration classDeclaration =
      Expressions.classDecl(Modifier.PUBLIC, "Buzz", null,
          ImmutableList.of(Scalar.class), declarations);
  String s = Expressions.toString(declarations, "\n", false);
  if (CalciteSystemProperty.DEBUG.value()) {
    Util.debugCode(System.out, s);
  }
  try {
    return getScalar(classDeclaration, s);
  } catch (CompileException | IOException e) {
    throw new RuntimeException(e);
  }
}
 
Example 17
Source File: RexToLixTranslator.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Case statements of the form:
 * {@code CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END}.
 * When {@code a = true}, returns {@code b};
 * when {@code c = true}, returns {@code d};
 * else returns {@code e}.
 *
 * <p>We generate code that looks like:
 *
 * <blockquote><pre>
 *      int case_when_value;
 *      ......code for a......
 *      if (!a_isNull && a_value) {
 *          ......code for b......
 *          case_when_value = res(b_isNull, b_value);
 *      } else {
 *          ......code for c......
 *          if (!c_isNull && c_value) {
 *              ......code for d......
 *              case_when_value = res(d_isNull, d_value);
 *          } else {
 *              ......code for e......
 *              case_when_value = res(e_isNull, e_value);
 *          }
 *      }
 * </pre></blockquote>
 */
private void implementRecursively(final RexToLixTranslator currentTranslator,
    final List<RexNode> operandList, final ParameterExpression valueVariable, int pos) {
  final BlockBuilder currentBlockBuilder = currentTranslator.getBlockBuilder();
  final List<Type> storageTypes = EnumUtils.internalTypes(operandList);
  // [ELSE] clause
  if (pos == operandList.size() - 1) {
    Expression res = implementCallOperand2(operandList.get(pos),
        storageTypes.get(pos), currentTranslator);
    currentBlockBuilder.add(
        Expressions.statement(
            Expressions.assign(valueVariable,
                EnumUtils.convert(res, valueVariable.getType()))));
    return;
  }
  // Condition code: !a_isNull && a_value
  final RexNode testerNode = operandList.get(pos);
  final Result testerResult = implementCallOperand(testerNode,
      storageTypes.get(pos), currentTranslator);
  final Expression tester = Expressions.andAlso(
      Expressions.not(testerResult.isNullVariable),
      testerResult.valueVariable);
  // Code for {if} branch
  final RexNode ifTrueNode = operandList.get(pos + 1);
  final BlockBuilder ifTrueBlockBuilder =
      new BlockBuilder(true, currentBlockBuilder);
  final RexToLixTranslator ifTrueTranslator =
      currentTranslator.setBlock(ifTrueBlockBuilder);
  final Expression ifTrueRes = implementCallOperand2(ifTrueNode,
      storageTypes.get(pos + 1), ifTrueTranslator);
  // Assign the value: case_when_value = ifTrueRes
  ifTrueBlockBuilder.add(
      Expressions.statement(
          Expressions.assign(valueVariable,
              EnumUtils.convert(ifTrueRes, valueVariable.getType()))));
  final BlockStatement ifTrue = ifTrueBlockBuilder.toBlock();
  // There is no [ELSE] clause
  if (pos + 1 == operandList.size() - 1) {
    currentBlockBuilder.add(
        Expressions.ifThen(tester, ifTrue));
    return;
  }
  // Generate code for {else} branch recursively
  final BlockBuilder ifFalseBlockBuilder =
      new BlockBuilder(true, currentBlockBuilder);
  final RexToLixTranslator ifFalseTranslator =
      currentTranslator.setBlock(ifFalseBlockBuilder);
  implementRecursively(ifFalseTranslator, operandList, valueVariable, pos + 2);
  final BlockStatement ifFalse = ifFalseBlockBuilder.toBlock();
  currentBlockBuilder.add(
      Expressions.ifThenElse(tester, ifTrue, ifFalse));
}
 
Example 18
Source File: RexImpTable.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Expression implementResult(AggContext info,
    AggResultContext result) {
  WinAggResultContext winResult = (WinAggResultContext) result;

  List<RexNode> rexArgs = winResult.rexArguments();

  ParameterExpression res = Expressions.parameter(0, info.returnType(),
      result.currentBlock().newName(isLead ? "lead" : "lag"));

  Expression offset;
  RexToLixTranslator currentRowTranslator =
      winResult.rowTranslator(
          winResult.computeIndex(Expressions.constant(0), SeekType.SET));
  if (rexArgs.size() >= 2) {
    // lead(x, offset) or lead(x, offset, default)
    offset = currentRowTranslator.translate(
        rexArgs.get(1), int.class);
  } else {
    offset = Expressions.constant(1);
  }
  if (!isLead) {
    offset = Expressions.negate(offset);
  }
  Expression dstIndex = winResult.computeIndex(offset, SeekType.SET);

  Expression rowInRange = winResult.rowInPartition(dstIndex);

  BlockBuilder thenBlock = result.nestBlock();
  Expression lagResult = winResult.rowTranslator(dstIndex).translate(
      rexArgs.get(0), res.type);
  thenBlock.add(Expressions.statement(Expressions.assign(res, lagResult)));
  result.exitBlock();
  BlockStatement thenBranch = thenBlock.toBlock();

  Expression defaultValue = rexArgs.size() == 3
      ? currentRowTranslator.translate(rexArgs.get(2), res.type)
      : getDefaultValue(res.type);

  result.currentBlock().add(Expressions.declare(0, res, null));
  result.currentBlock().add(
      Expressions.ifThenElse(rowInRange, thenBranch,
          Expressions.statement(Expressions.assign(res, defaultValue))));
  return res;
}
 
Example 19
Source File: EnumerableUncollect.java    From calcite with Apache License 2.0 4 votes vote down vote up
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
  final BlockBuilder builder = new BlockBuilder();
  final EnumerableRel child = (EnumerableRel) getInput();
  final Result result = implementor.visitChild(this, 0, child, pref);
  final PhysType physType =
      PhysTypeImpl.of(
          implementor.getTypeFactory(),
          getRowType(),
          JavaRowFormat.LIST);

  // final Enumerable<List<Employee>> child = <<child adapter>>;
  // return child.selectMany(FLAT_PRODUCT);
  final Expression child_ =
      builder.append(
          "child", result.block);

  final List<Integer> fieldCounts = new ArrayList<>();
  final List<FlatProductInputType> inputTypes = new ArrayList<>();

  Expression lambdaForStructWithSingleItem = null;
  for (RelDataTypeField field : child.getRowType().getFieldList()) {
    final RelDataType type = field.getType();
    if (type instanceof MapSqlType) {
      fieldCounts.add(2);
      inputTypes.add(FlatProductInputType.MAP);
    } else {
      final RelDataType elementType = type.getComponentType();
      if (elementType.isStruct()) {
        if (elementType.getFieldCount() == 1 && child.getRowType().getFieldList().size() == 1
            && !withOrdinality) {
          // Solves CALCITE-4063: if we are processing a single field, which is a struct with a
          // single item inside, and no ordinality; the result must be a scalar, hence use a
          // special lambda that does not return lists, but the (single) items within those lists
          lambdaForStructWithSingleItem = Expressions.call(BuiltInMethod.FLAT_LIST.method);
        } else {
          fieldCounts.add(elementType.getFieldCount());
          inputTypes.add(FlatProductInputType.LIST);
        }
      } else {
        fieldCounts.add(-1);
        inputTypes.add(FlatProductInputType.SCALAR);
      }
    }
  }

  final Expression lambda = lambdaForStructWithSingleItem != null
      ? lambdaForStructWithSingleItem
      : Expressions.call(BuiltInMethod.FLAT_PRODUCT.method,
          Expressions.constant(Ints.toArray(fieldCounts)),
          Expressions.constant(withOrdinality),
          Expressions.constant(
              inputTypes.toArray(new FlatProductInputType[0])));
  builder.add(
      Expressions.return_(null,
          Expressions.call(child_,
              BuiltInMethod.SELECT_MANY.method,
              lambda)));
  return implementor.result(physType, builder.toBlock());
}
 
Example 20
Source File: JdbcToEnumerableConverter.java    From calcite with Apache License 2.0 4 votes vote down vote up
private void generateGet(EnumerableRelImplementor implementor,
    PhysType physType, BlockBuilder builder, ParameterExpression resultSet_,
    int i, Expression target, Expression calendar_,
    SqlDialect.CalendarPolicy calendarPolicy) {
  final Primitive primitive = Primitive.ofBoxOr(physType.fieldClass(i));
  final RelDataType fieldType =
      physType.getRowType().getFieldList().get(i).getType();
  final List<Expression> dateTimeArgs = new ArrayList<>();
  dateTimeArgs.add(Expressions.constant(i + 1));
  SqlTypeName sqlTypeName = fieldType.getSqlTypeName();
  boolean offset = false;
  switch (calendarPolicy) {
  case LOCAL:
    dateTimeArgs.add(calendar_);
    break;
  case NULL:
    // We don't specify a calendar at all, so we don't add an argument and
    // instead use the version of the getXXX that doesn't take a Calendar
    break;
  case DIRECT:
    sqlTypeName = SqlTypeName.ANY;
    break;
  case SHIFT:
    switch (sqlTypeName) {
    case TIMESTAMP:
    case DATE:
      offset = true;
    }
    break;
  }
  final Expression source;
  switch (sqlTypeName) {
  case DATE:
  case TIME:
  case TIMESTAMP:
    source = Expressions.call(
        getMethod(sqlTypeName, fieldType.isNullable(), offset),
        Expressions.<Expression>list()
            .append(
                Expressions.call(resultSet_,
                    getMethod2(sqlTypeName), dateTimeArgs))
        .appendIf(offset, getTimeZoneExpression(implementor)));
    break;
  case ARRAY:
    final Expression x = Expressions.convert_(
        Expressions.call(resultSet_, jdbcGetMethod(primitive),
            Expressions.constant(i + 1)),
        java.sql.Array.class);
    source = Expressions.call(BuiltInMethod.JDBC_ARRAY_TO_LIST.method, x);
    break;
  default:
    source = Expressions.call(
        resultSet_, jdbcGetMethod(primitive), Expressions.constant(i + 1));
  }
  builder.add(
      Expressions.statement(
          Expressions.assign(
              target, source)));

  // [CALCITE-596] If primitive type columns contain null value, returns null
  // object
  if (primitive != null) {
    builder.add(
        Expressions.ifThen(
            Expressions.call(resultSet_, "wasNull"),
            Expressions.statement(
                Expressions.assign(target,
                    Expressions.constant(null)))));
  }
}