Package net.hydromatic.linq4j.expressions

Examples of net.hydromatic.linq4j.expressions.Expression


    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
      final JavaTypeFactory typeFactory = implementor.getTypeFactory();
      final EnumerableRel child = (EnumerableRel) getChild();
      final BlockBuilder builder = new BlockBuilder();
      final Result result = implementor.visitChild(this, 0, child, pref);
      Expression source_ = builder.append("source", result.block);

      final List<Expression> translatedConstants =
          new ArrayList<Expression>(constants.size());
      for (RexLiteral constant : constants) {
        translatedConstants.add(RexToLixTranslator.translateLiteral(
            constant, constant.getType(),
            typeFactory,
            RexImpTable.NullAs.NULL));
      }

      PhysType inputPhysType = result.physType;

      ParameterExpression prevStart =
          Expressions.parameter(int.class, builder.newName("prevStart"));
      ParameterExpression prevEnd =
          Expressions.parameter(int.class, builder.newName("prevEnd"));

      builder.add(Expressions.declare(0, prevStart, null));
      builder.add(Expressions.declare(0, prevEnd, null));

      for (int windowIdx = 0; windowIdx < windows.size(); windowIdx++) {
        Window window = windows.get(windowIdx);
        // Comparator:
        // final Comparator<JdbcTest.Employee> comparator =
        //    new Comparator<JdbcTest.Employee>() {
        //      public int compare(JdbcTest.Employee o1,
        //          JdbcTest.Employee o2) {
        //        return Integer.compare(o1.empid, o2.empid);
        //      }
        //    };
        final Expression comparator_ =
            builder.append(
                "comparator",
                inputPhysType.generateComparator(
                    window.collation()));

        Pair<Expression, Expression> partitionIterator =
            getPartitionIterator(builder, source_, inputPhysType, window,
                comparator_);
        final Expression collectionExpr = partitionIterator.left;
        final Expression iterator_ = partitionIterator.right;

        List<AggImpState> aggs = new ArrayList<AggImpState>();
        List<AggregateCall> aggregateCalls = window.getAggregateCalls(this);
        for (int aggIdx = 0; aggIdx < aggregateCalls.size(); aggIdx++) {
          AggregateCall call = aggregateCalls.get(aggIdx);
          aggs.add(new AggImpState(aggIdx, call, true));
        }

        // The output from this stage is the input plus the aggregate functions.
        final RelDataTypeFactory.FieldInfoBuilder typeBuilder =
            typeFactory.builder();
        typeBuilder.addAll(inputPhysType.getRowType().getFieldList());
        for (AggImpState agg : aggs) {
          typeBuilder.add(agg.call.name, agg.call.type);
        }
        RelDataType outputRowType = typeBuilder.build();
        final PhysType outputPhysType =
            PhysTypeImpl.of(
                typeFactory, outputRowType, pref.prefer(result.format));

        final Expression list_ =
            builder.append(
                "list",
                Expressions.new_(
                    ArrayList.class,
                    Expressions.call(
                        collectionExpr, BuiltinMethod.COLLECTION_SIZE.method)),
                false);

        Pair<Expression, Expression> collationKey =
            getRowCollationKey(builder, inputPhysType, window, windowIdx);
        Expression keySelector = collationKey.left;
        Expression keyComparator = collationKey.right;
        final BlockBuilder builder3 = new BlockBuilder();
        final Expression rows_ =
            builder3.append(
                "rows",
                Expressions.convert_(
                    Expressions.call(
                        iterator_, BuiltinMethod.ITERATOR_NEXT.method),
                    Object[].class),
                false);

        builder3.add(Expressions.statement(
            Expressions.assign(prevStart, Expressions.constant(-1))));
        builder3.add(Expressions.statement(
            Expressions.assign(prevEnd,
                Expressions.constant(Integer.MAX_VALUE))));

        final BlockBuilder builder4 = new BlockBuilder();

        final ParameterExpression i_ =
            Expressions.parameter(int.class, builder4.newName("i"));

        final Expression row_ =
            builder4.append(
                "row",
                RexToLixTranslator.convert(
                    Expressions.arrayIndex(rows_, i_),
                    inputPhysType.getJavaRowType()));

        final RexToLixTranslator.InputGetter inputGetter =
            new WindowRelInputGetter(row_, inputPhysType,
                result.physType.getRowType().getFieldCount(),
                translatedConstants);

        final RexToLixTranslator translator =
            RexToLixTranslator.forAggregation(typeFactory, builder4,
                inputGetter);

        final List<Expression> outputRow = new ArrayList<Expression>();
        int fieldCountWithAggResults =
          inputPhysType.getRowType().getFieldCount();
        for (int i = 0; i < fieldCountWithAggResults; i++) {
          outputRow.add(
              inputPhysType.fieldReference(
                  row_, i,
                  outputPhysType.getJavaFieldType(i)));
        }

        declareAndResetState(typeFactory, builder, result, windowIdx, aggs,
            outputPhysType, outputRow);

        // There are assumptions that minX==0. If ever change this, look for
        // frameRowCount, bounds checking, etc
        final Expression minX = Expressions.constant(0);
        final Expression partitionRowCount =
            builder3.append("partRows", Expressions.field(rows_, "length"));
        final Expression maxX = builder3.append("maxX",
            Expressions.subtract(
                partitionRowCount, Expressions.constant(1)));

        final Expression startUnchecked = builder4.append("start",
            translateBound(translator, i_, row_, minX, maxX, rows_,
                window, true,
                inputPhysType, comparator_, keySelector, keyComparator));
        final Expression endUnchecked = builder4.append("end",
            translateBound(translator, i_, row_, minX, maxX, rows_,
                window, false,
                inputPhysType, comparator_, keySelector, keyComparator));

        final Expression startX;
        final Expression endX;
        final Expression hasRows;
        if (window.isAlwaysNonEmpty()) {
          startX = startUnchecked;
          endX = endUnchecked;
          hasRows = Expressions.constant(true);
        } else {
          Expression startTmp =
              window.lowerBound.isUnbounded() || startUnchecked == i_
                  ? startUnchecked
                  : builder4.append("startTmp",
                      Expressions.call(null, BuiltinMethod.MATH_MAX.method,
                          startUnchecked, minX));
          Expression endTmp =
              window.upperBound.isUnbounded() || endUnchecked == i_
                  ? endUnchecked
                  : builder4.append("endTmp",
                      Expressions.call(null, BuiltinMethod.MATH_MIN.method,
                          endUnchecked, maxX));

          ParameterExpression startPe = Expressions.parameter(0, int.class,
              builder4.newName("startChecked"));
          ParameterExpression endPe = Expressions.parameter(0, int.class,
              builder4.newName("endChecked"));
          builder4.add(Expressions.declare(Modifier.FINAL, startPe, null));
          builder4.add(Expressions.declare(Modifier.FINAL, endPe, null));

          hasRows = builder4.append("hasRows",
              Expressions.lessThanOrEqual(startTmp, endTmp));
          builder4.add(Expressions.ifThenElse(
              hasRows,
              Expressions.block(
                  Expressions.statement(
                      Expressions.assign(startPe, startTmp)),
                  Expressions.statement(
                    Expressions.assign(endPe, endTmp))
            ),
              Expressions.block(
                  Expressions.statement(
                      Expressions.assign(startPe, Expressions.constant(-1))),
                  Expressions.statement(
                      Expressions.assign(endPe, Expressions.constant(-1))))));
          startX = startPe;
          endX = endPe;
        }

        final BlockBuilder builder5 = new BlockBuilder(true, builder4);

        BinaryExpression rowCountWhenNonEmpty = Expressions.add(
            startX == minX ? endX : Expressions.subtract(endX, startX),
            Expressions.constant(1));

        final Expression frameRowCount;

        if (hasRows.equals(Expressions.constant(true))) {
          frameRowCount =
              builder4.append("totalRows", rowCountWhenNonEmpty);
        } else {
          frameRowCount =
              builder4.append("totalRows", Expressions.condition(hasRows,
                  rowCountWhenNonEmpty, Expressions.constant(0)));
        }

        ParameterExpression actualStart = Expressions.parameter(
            0, int.class, builder5.newName("actualStart"));

        final BlockBuilder builder6 = new BlockBuilder(true, builder5);
        builder6.add(Expressions.statement(
            Expressions.assign(actualStart, startX)));

        for (final AggImpState agg : aggs) {
          agg.implementor.implementReset(agg.context,
              new WinAggResetContextImpl(builder6, agg.state, i_, startX, endX,
                  hasRows, partitionRowCount, frameRowCount));
        }

        Expression lowerBoundCanChange =
            window.lowerBound.isUnbounded() && window.lowerBound.isPreceding()
            ? Expressions.constant(false)
            : Expressions.notEqual(startX, prevStart);
        Expression needRecomputeWindow = Expressions.orElse(
            lowerBoundCanChange,
            Expressions.lessThan(endX, prevEnd));

        BlockStatement resetWindowState = builder6.toBlock();
        if (resetWindowState.statements.size() == 1) {
View Full Code Here


          WinAggFrameResultContext>() {
        public WinAggFrameResultContext apply(
            final BlockBuilder block) {
          return new WinAggFrameResultContext() {
            public RexToLixTranslator rowTranslator(Expression rowIndex) {
              Expression row =
                  getRow(rowIndex);
              final RexToLixTranslator.InputGetter inputGetter =
                  new WindowRelInputGetter(row, inputPhysType,
                      result.physType.getRowType().getFieldCount(),
                      translatedConstants);

              return RexToLixTranslator.forAggregation(typeFactory,
                  block, inputGetter);
            }

            public Expression computeIndex(Expression offset,
                WinAggImplementor.SeekType seekType) {
              Expression index;
              if (seekType == WinAggImplementor.SeekType.AGG_INDEX) {
                index = jDecl.parameter;
              } else if (seekType == WinAggImplementor.SeekType.SET) {
                index = i_;
              } else if (seekType == WinAggImplementor.SeekType.START) {
                index = startX;
              } else if (seekType == WinAggImplementor.SeekType.END) {
                index = endX;
              } else {
                throw new IllegalArgumentException("SeekSet " + seekType
                    + " is not supported");
              }
              if (!Expressions.constant(0).equals(offset)) {
                index = block.append("idx", Expressions.add(index, offset));
              }
              return index;
            }

            private Expression checkBounds(Expression rowIndex,
                Expression minIndex, Expression maxIndex) {
              if (rowIndex == i_ || rowIndex == startX || rowIndex == endX) {
                // No additional bounds check required
                return hasRows;
              }

              //noinspection UnnecessaryLocalVariable
              Expression res = block.append("rowInFrame", Expressions.foldAnd(
                  ImmutableList.of(hasRows,
                      Expressions.greaterThanOrEqual(rowIndex, minIndex),
                      Expressions.lessThanOrEqual(rowIndex, maxIndex))));

              return res;
View Full Code Here

        //       source.into(new ArrayList<Employee>());
        //   Iterator<Employee[]> iterator =
        //       SortedMultiMap.singletonArrayIterator(comparator, tempList);
        //   final List<Xxx> list = new ArrayList<Xxx>(tempList.size());

        final Expression tempList_ = builder.append(
            "tempList",
            Expressions.convert_(
                Expressions.call(
                    source_,
                    BuiltinMethod.INTO.method,
                    Expressions.new_(ArrayList.class)),
                List.class));
        return Pair.of(tempList_,
            builder.append(
              "iterator",
              Expressions.call(
                  null,
                  BuiltinMethod.SORTED_MULTI_MAP_SINGLETON.method,
                  comparator_,
                  tempList_)));
      }
      Expression multiMap_ =
          builder.append(
              "multiMap", Expressions.new_(SortedMultiMap.class));
      final BlockBuilder builder2 = new BlockBuilder();
      final ParameterExpression v_ =
          Expressions.parameter(inputPhysType.getJavaRowType(),
View Full Code Here

          // Regular aggregates do not change when the windowing frame keeps
          // the same. Ths
          continue;
        }
        nonEmpty = true;
        Expression res = agg.implementor.implementResult(agg.context,
            new WinAggResultContextImpl(builder, agg.state, frame) {
              public List<RexNode> rexArguments() {
                return rexArguments.apply(agg);
              }
            });
        // Several count(a) and count(b) might share the result
        Expression aggRes = builder.append("a" + agg.aggIdx + "res",
            RexToLixTranslator.convert(res, agg.result.getType()));
        builder.add(Expressions.statement(
            Expressions.assign(agg.result, aggRes)));
      }
      return nonEmpty;
View Full Code Here

      if (window.isRows) {
        if (bound.isCurrentRow()) {
          return i_;
        }
        RexNode node = bound.getOffset();
        Expression offs = translator.translate(node);
        // Floating offset does not make sense since we refer to array index.
        // Nulls do not make sense as well.
        offs = RexToLixTranslator.convert(offs, int.class);

        Expression b = i_;
        if (bound.isFollowing()) {
          b = Expressions.add(b, offs);
        } else {
          b = Expressions.subtract(b, offs);
        }
        return b;
      }
      Expression searchLower = min_;
      Expression searchUpper = max_;
      if (bound.isCurrentRow()) {
        if (lower) {
          searchUpper = i_;
        } else {
          searchLower = i_;
        }
      }

      List<RelFieldCollation> fieldCollations =
          window.collation().getFieldCollations();
      if (bound.isCurrentRow() && fieldCollations.size() != 1) {
        return Expressions.call(
            (lower
                ? BuiltinMethod.BINARY_SEARCH5_LOWER
                : BuiltinMethod.BINARY_SEARCH5_UPPER).method,
            rows_, row_, searchLower, searchUpper, keySelector, keyComparator);
      }
      assert fieldCollations.size() == 1
          : "When using range window specification, ORDER BY should have"
            + " exactly one expression."
            + " Actual collation is " + window.collation();
      // isRange
      int orderKey =
          fieldCollations.get(0).getFieldIndex();
      RelDataType keyType =
          physType.getRowType().getFieldList().get(orderKey).getType();
      Type desiredKeyType = translator.typeFactory.getJavaClass(keyType);
      if (bound.getOffset() == null) {
        desiredKeyType = Primitive.box(desiredKeyType);
      }
      Expression val = translator.translate(new RexInputRef(orderKey,
              keyType), desiredKeyType);
      if (!bound.isCurrentRow()) {
        RexNode node = bound.getOffset();
        Expression offs = translator.translate(node);
        // TODO: support date + interval somehow
        if (bound.isFollowing()) {
          val = Expressions.add(val, offs);
        } else {
          val = Expressions.subtract(val, offs);
View Full Code Here

    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
      BlockBuilder builder = new BlockBuilder();
      final Result leftResult =
          implementor.visitChild(this, 0, (EnumerableRel) left, pref);
      Expression leftExpression =
          builder.append(
              "left", leftResult.block);
      final Result rightResult =
          implementor.visitChild(this, 1, (EnumerableRel) right, pref);
      Expression rightExpression =
          builder.append(
              "right", rightResult.block);
      final PhysType physType =
          PhysTypeImpl.of(
              implementor.getTypeFactory(), getRowType(), pref.preferArray());
View Full Code Here

            Expressions.parameter(inputPhysType.getJavaRowType(),
                LEFT_RIGHT[ord.i]);
        parameters.add(parameter);
        final int fieldCount = inputPhysType.getRowType().getFieldCount();
        for (int i = 0; i < fieldCount; i++) {
          Expression expression =
              inputPhysType.fieldReference(parameter, i,
                  physType.getJavaFieldType(i));
          if (joinType.generatesNullsOn(ord.i)) {
            expression =
                Expressions.condition(
View Full Code Here

    public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
      BlockBuilder builder = new BlockBuilder();
      final Result leftResult =
          implementor.visitChild(this, 0, (EnumerableRel) left, pref);
      Expression leftExpression =
          builder.append(
              "left", leftResult.block);
      final Result rightResult =
          implementor.visitChild(this, 1, (EnumerableRel) right, pref);
      Expression rightExpression =
          builder.append(
              "right", rightResult.block);
      final PhysType physType = leftResult.physType;
      return implementor.result(
          physType,
View Full Code Here

      assert getConvention() instanceof EnumerableConvention;
      this.elementType = elementType;
    }

    private Expression getExpression() {
      Expression expression = table.getExpression(Queryable.class);
      final Type type = expression.getType();
      if (Types.isArray(type)) {
        if (Types.toClass(type).getComponentType().isPrimitive()) {
          expression =
              Expressions.call(
                  BuiltinMethod.AS_LIST.method,
View Full Code Here

      final PhysType physType =
          PhysTypeImpl.of(
              implementor.getTypeFactory(),
              getRowType(),
              format());
      final Expression expression = getExpression();
      return implementor.result(physType, Blocks.toBlock(expression));
    }
View Full Code Here

TOP

Related Classes of net.hydromatic.linq4j.expressions.Expression

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.