http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java deleted file mode 100644 index 5b5c418..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.adapter.enumerable.impl.WinAggAddContextImpl; -import org.apache.calcite.adapter.enumerable.impl.WinAggResetContextImpl; -import org.apache.calcite.adapter.enumerable.impl.WinAggResultContextImpl; -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.linq4j.tree.BinaryExpression; -import org.apache.calcite.linq4j.tree.BlockBuilder; -import org.apache.calcite.linq4j.tree.BlockStatement; -import org.apache.calcite.linq4j.tree.DeclarationStatement; -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.linq4j.tree.Expressions; -import org.apache.calcite.linq4j.tree.ParameterExpression; -import org.apache.calcite.linq4j.tree.Primitive; -import org.apache.calcite.linq4j.tree.Statement; -import org.apache.calcite.linq4j.tree.Types; -import org.apache.calcite.plan.RelOptCluster; -import org.apache.calcite.plan.RelOptCost; -import org.apache.calcite.plan.RelOptPlanner; -import org.apache.calcite.plan.RelTraitSet; -import org.apache.calcite.prepare.CalcitePrepareImpl; -import org.apache.calcite.rel.RelFieldCollation; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.core.AggregateCall; -import org.apache.calcite.rel.core.Window; -import org.apache.calcite.rel.metadata.RelMetadataQuery; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.rel.type.RelDataTypeFactory; -import org.apache.calcite.rex.RexInputRef; -import org.apache.calcite.rex.RexLiteral; -import org.apache.calcite.rex.RexNode; -import org.apache.calcite.rex.RexWindowBound; -import org.apache.calcite.runtime.SortedMultiMap; -import org.apache.calcite.sql.SqlAggFunction; -import org.apache.calcite.util.BuiltInMethod; -import org.apache.calcite.util.Pair; -import org.apache.calcite.util.Util; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; - -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -/** Implementation of {@link org.apache.calcite.rel.core.Window} in - * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}. */ -public class EnumerableWindow extends Window implements EnumerableRel { - /** Creates an EnumerableWindowRel. */ - EnumerableWindow(RelOptCluster cluster, RelTraitSet traits, RelNode child, - List<RexLiteral> constants, RelDataType rowType, List<Group> groups) { - super(cluster, traits, child, constants, rowType, groups); - } - - @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { - return new EnumerableWindow(getCluster(), traitSet, sole(inputs), - constants, rowType, groups); - } - - public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { - return super.computeSelfCost(planner, mq) - .multiplyBy(EnumerableConvention.COST_MULTIPLIER); - } - - /** Implementation of {@link RexToLixTranslator.InputGetter} - * suitable for generating implementations of windowed aggregate - * functions. */ - private static class WindowRelInputGetter - implements RexToLixTranslator.InputGetter { - private final Expression row; - private final PhysType rowPhysType; - private final int actualInputFieldCount; - private final List<Expression> constants; - - private WindowRelInputGetter(Expression row, - PhysType rowPhysType, int actualInputFieldCount, - List<Expression> constants) { - this.row = row; - this.rowPhysType = rowPhysType; - this.actualInputFieldCount = actualInputFieldCount; - this.constants = constants; - } - - public Expression field(BlockBuilder list, int index, Type storageType) { - if (index < actualInputFieldCount) { - Expression current = list.append("current", row); - return rowPhysType.fieldReference(current, index, storageType); - } - return constants.get(index - actualInputFieldCount); - } - } - - private void sampleOfTheGeneratedWindowedAggregate() { - // Here's overview of the generated code - // For each list of rows that have the same partitioning key, evaluate - // all of the windowed aggregate functions. - - // builder - Iterator<Integer[]> iterator = null; - - // builder3 - Integer[] rows = iterator.next(); - - int prevStart = -1; - int prevEnd = -1; - - for (int i = 0; i < rows.length; i++) { - // builder4 - Integer row = rows[i]; - - int start = 0; - int end = 100; - if (start != prevStart || end != prevEnd) { - // builder5 - int actualStart = 0; - if (start != prevStart || end < prevEnd) { - // builder6 - // recompute - actualStart = start; - // implementReset - } else { // must be start == prevStart && end > prevEnd - actualStart = prevEnd + 1; - } - prevStart = start; - prevEnd = end; - - if (start != -1) { - for (int j = actualStart; j <= end; j++) { - // builder7 - // implementAdd - } - } - // implementResult - // list.add(new Xxx(row.deptno, row.empid, sum, count)); - } - } - // multiMap.clear(); // allows gc - // source = Linq4j.asEnumerable(list); - } - - public Result implement(EnumerableRelImplementor implementor, Prefer pref) { - final JavaTypeFactory typeFactory = implementor.getTypeFactory(); - final EnumerableRel child = (EnumerableRel) getInput(); - 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 < groups.size(); windowIdx++) { - Group group = groups.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( - group.collation())); - - Pair<Expression, Expression> partitionIterator = - getPartitionIterator(builder, source_, inputPhysType, group, - comparator_); - final Expression collectionExpr = partitionIterator.left; - final Expression iterator_ = partitionIterator.right; - - List<AggImpState> aggs = new ArrayList<AggImpState>(); - List<AggregateCall> aggregateCalls = group.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, group, 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_, - group, true, - inputPhysType, comparator_, keySelector, keyComparator)); - final Expression endUnchecked = builder4.append("end", - translateBound(translator, i_, row_, minX, maxX, rows_, - group, false, - inputPhysType, comparator_, keySelector, keyComparator)); - - final Expression startX; - final Expression endX; - final Expression hasRows; - if (group.isAlwaysNonEmpty()) { - startX = startUnchecked; - endX = endUnchecked; - hasRows = Expressions.constant(true); - } else { - Expression startTmp = - group.lowerBound.isUnbounded() || startUnchecked == i_ - ? startUnchecked - : builder4.append("startTmp", - Expressions.call(null, BuiltInMethod.MATH_MAX.method, - startUnchecked, minX)); - Expression endTmp = - group.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 = - group.lowerBound.isUnbounded() && group.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) { - builder5.add( - Expressions.declare(0, actualStart, - Expressions.condition(needRecomputeWindow, startX, - Expressions.add(prevEnd, Expressions.constant(1))))); - } else { - builder5.add( - Expressions.declare(0, actualStart, null)); - builder5.add( - Expressions.ifThenElse(needRecomputeWindow, - resetWindowState, - Expressions.statement( - Expressions.assign(actualStart, - Expressions.add(prevEnd, Expressions.constant(1)))))); - } - - if (lowerBoundCanChange instanceof BinaryExpression) { - builder5.add( - Expressions.statement(Expressions.assign(prevStart, startX))); - } - builder5.add( - Expressions.statement(Expressions.assign(prevEnd, endX))); - - final BlockBuilder builder7 = new BlockBuilder(true, builder5); - final DeclarationStatement jDecl = - Expressions.declare(0, "j", actualStart); - - final PhysType inputPhysTypeFinal = inputPhysType; - final Function<BlockBuilder, WinAggFrameResultContext> - resultContextBuilder = - getBlockBuilderWinAggFrameResultContextFunction(typeFactory, result, - translatedConstants, comparator_, rows_, i_, startX, endX, - minX, maxX, - hasRows, frameRowCount, partitionRowCount, - jDecl, inputPhysTypeFinal); - - final Function<AggImpState, List<RexNode>> rexArguments = - new Function<AggImpState, List<RexNode>>() { - public List<RexNode> apply(AggImpState agg) { - List<Integer> argList = agg.call.getArgList(); - List<RelDataType> inputTypes = - EnumUtils.fieldRowTypes( - result.physType.getRowType(), - constants, - argList); - List<RexNode> args = new ArrayList<RexNode>( - inputTypes.size()); - for (int i = 0; i < argList.size(); i++) { - Integer idx = argList.get(i); - args.add(new RexInputRef(idx, inputTypes.get(i))); - } - return args; - } - }; - - implementAdd(aggs, builder7, resultContextBuilder, rexArguments, jDecl); - - BlockStatement forBlock = builder7.toBlock(); - if (!forBlock.statements.isEmpty()) { - // For instance, row_number does not use for loop to compute the value - Statement forAggLoop = Expressions.for_( - Arrays.asList(jDecl), - Expressions.lessThanOrEqual(jDecl.parameter, endX), - Expressions.preIncrementAssign(jDecl.parameter), - forBlock); - if (!hasRows.equals(Expressions.constant(true))) { - forAggLoop = Expressions.ifThen(hasRows, forAggLoop); - } - builder5.add(forAggLoop); - } - - if (implementResult(aggs, builder5, resultContextBuilder, rexArguments, - true)) { - builder4.add( - Expressions.ifThen( - Expressions.orElse(lowerBoundCanChange, - Expressions.notEqual(endX, prevEnd)), - builder5.toBlock())); - } - - implementResult(aggs, builder4, resultContextBuilder, rexArguments, - false); - - builder4.add( - Expressions.statement( - Expressions.call( - list_, - BuiltInMethod.COLLECTION_ADD.method, - outputPhysType.record(outputRow)))); - - builder3.add( - Expressions.for_( - Expressions.declare(0, i_, Expressions.constant(0)), - Expressions.lessThan( - i_, - Expressions.field(rows_, "length")), - Expressions.preIncrementAssign(i_), - builder4.toBlock())); - - builder.add( - Expressions.while_( - Expressions.call( - iterator_, - BuiltInMethod.ITERATOR_HAS_NEXT.method), - builder3.toBlock())); - builder.add( - Expressions.statement( - Expressions.call( - collectionExpr, - BuiltInMethod.MAP_CLEAR.method))); - - // We're not assigning to "source". For each group, create a new - // final variable called "source" or "sourceN". - source_ = - builder.append( - "source", - Expressions.call( - BuiltInMethod.AS_ENUMERABLE.method, list_)); - - inputPhysType = outputPhysType; - } - - // return Linq4j.asEnumerable(list); - builder.add( - Expressions.return_(null, source_)); - return implementor.result(inputPhysType, builder.toBlock()); - } - - private Function<BlockBuilder, WinAggFrameResultContext> - getBlockBuilderWinAggFrameResultContextFunction( - final JavaTypeFactory typeFactory, final Result result, - final List<Expression> translatedConstants, - final Expression comparator_, - final Expression rows_, final ParameterExpression i_, - final Expression startX, final Expression endX, - final Expression minX, final Expression maxX, - final Expression hasRows, final Expression frameRowCount, - final Expression partitionRowCount, - final DeclarationStatement jDecl, - final PhysType inputPhysType) { - return new Function<BlockBuilder, - 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; - } - - public Expression rowInFrame(Expression rowIndex) { - return checkBounds(rowIndex, startX, endX); - } - - public Expression rowInPartition(Expression rowIndex) { - return checkBounds(rowIndex, minX, maxX); - } - - public Expression compareRows(Expression a, Expression b) { - return Expressions.call(comparator_, - BuiltInMethod.COMPARATOR_COMPARE.method, - getRow(a), getRow(b)); - } - - public Expression getRow(Expression rowIndex) { - return block.append( - "jRow", - RexToLixTranslator.convert( - Expressions.arrayIndex(rows_, rowIndex), - inputPhysType.getJavaRowType())); - } - - public Expression index() { - return i_; - } - - public Expression startIndex() { - return startX; - } - - public Expression endIndex() { - return endX; - } - - public Expression hasRows() { - return hasRows; - } - - public Expression getFrameRowCount() { - return frameRowCount; - } - - public Expression getPartitionRowCount() { - return partitionRowCount; - } - }; - } - }; - } - - private Pair<Expression, Expression> getPartitionIterator( - BlockBuilder builder, - Expression source_, - PhysType inputPhysType, - Group group, - Expression comparator_) { - // Populate map of lists, one per partition - // final Map<Integer, List<Employee>> multiMap = - // new SortedMultiMap<Integer, List<Employee>>(); - // source.foreach( - // new Function1<Employee, Void>() { - // public Void apply(Employee v) { - // final Integer k = v.deptno; - // multiMap.putMulti(k, v); - // return null; - // } - // }); - // final List<Xxx> list = new ArrayList<Xxx>(multiMap.size()); - // Iterator<Employee[]> iterator = multiMap.arrays(comparator); - // - if (group.keys.isEmpty()) { - // If partition key is empty, no need to partition. - // - // final List<Employee> tempList = - // 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(), - builder2.newName("v")); - - Pair<Type, List<Expression>> selector = - inputPhysType.selector(v_, group.keys.asList(), JavaRowFormat.CUSTOM); - final ParameterExpression key_; - if (selector.left instanceof Types.RecordType) { - Types.RecordType keyJavaType = (Types.RecordType) selector.left; - List<Expression> initExpressions = selector.right; - key_ = Expressions.parameter(keyJavaType, "key"); - builder2.add(Expressions.declare(0, key_, null)); - builder2.add( - Expressions.statement( - Expressions.assign(key_, Expressions.new_(keyJavaType)))); - List<Types.RecordField> fieldList = keyJavaType.getRecordFields(); - for (int i = 0; i < initExpressions.size(); i++) { - Expression right = initExpressions.get(i); - builder2.add( - Expressions.statement( - Expressions.assign( - Expressions.field(key_, fieldList.get(i)), right))); - } - } else { - DeclarationStatement declare = - Expressions.declare(0, "key", selector.right.get(0)); - builder2.add(declare); - key_ = declare.parameter; - } - builder2.add( - Expressions.statement( - Expressions.call( - multiMap_, - BuiltInMethod.SORTED_MULTI_MAP_PUT_MULTI.method, - key_, - v_))); - builder2.add( - Expressions.return_( - null, Expressions.constant(null))); - - builder.add( - Expressions.statement( - Expressions.call( - source_, - BuiltInMethod.ENUMERABLE_FOREACH.method, - Expressions.lambda( - builder2.toBlock(), v_)))); - - return Pair.of(multiMap_, - builder.append( - "iterator", - Expressions.call( - multiMap_, - BuiltInMethod.SORTED_MULTI_MAP_ARRAYS.method, - comparator_))); - } - - private Pair<Expression, Expression> getRowCollationKey( - BlockBuilder builder, PhysType inputPhysType, - Group group, int windowIdx) { - if (!(group.isRows || (group.upperBound.isUnbounded() - && group.lowerBound.isUnbounded()))) { - Pair<Expression, Expression> pair = - inputPhysType.generateCollationKey( - group.collation().getFieldCollations()); - // optimize=false to prevent inlining of object create into for-loops - return Pair.of( - builder.append("keySelector" + windowIdx, pair.left, false), - builder.append("keyComparator" + windowIdx, pair.right, false)); - } else { - return Pair.of(null, null); - } - } - - private void declareAndResetState(final JavaTypeFactory typeFactory, - BlockBuilder builder, final Result result, int windowIdx, - List<AggImpState> aggs, PhysType outputPhysType, - List<Expression> outputRow) { - for (final AggImpState agg : aggs) { - agg.context = - new WinAggContext() { - public SqlAggFunction aggregation() { - return agg.call.getAggregation(); - } - - public RelDataType returnRelType() { - return agg.call.type; - } - - public Type returnType() { - return EnumUtils.javaClass(typeFactory, returnRelType()); - } - - public List<? extends Type> parameterTypes() { - return EnumUtils.fieldTypes(typeFactory, - parameterRelTypes()); - } - - public List<? extends RelDataType> parameterRelTypes() { - return EnumUtils.fieldRowTypes(result.physType.getRowType(), - constants, agg.call.getArgList()); - } - }; - String aggName = "a" + agg.aggIdx; - if (CalcitePrepareImpl.DEBUG) { - aggName = Util.toJavaId(agg.call.getAggregation().getName(), 0) - .substring("ID$0$".length()) + aggName; - } - List<Type> state = agg.implementor.getStateType(agg.context); - final List<Expression> decls = - new ArrayList<Expression>(state.size()); - for (int i = 0; i < state.size(); i++) { - Type type = state.get(i); - ParameterExpression pe = - Expressions.parameter(type, - builder.newName(aggName - + "s" + i + "w" + windowIdx)); - builder.add(Expressions.declare(0, pe, null)); - decls.add(pe); - } - agg.state = decls; - Type aggHolderType = agg.context.returnType(); - Type aggStorageType = - outputPhysType.getJavaFieldType(outputRow.size()); - if (Primitive.is(aggHolderType) && !Primitive.is(aggStorageType)) { - aggHolderType = Primitive.box(aggHolderType); - } - ParameterExpression aggRes = Expressions.parameter(0, - aggHolderType, - builder.newName(aggName + "w" + windowIdx)); - - builder.add( - Expressions.declare(0, aggRes, - Expressions.constant(Primitive.is(aggRes.getType()) - ? Primitive.of(aggRes.getType()).defaultValue - : null, - aggRes.getType()))); - agg.result = aggRes; - outputRow.add(aggRes); - agg.implementor.implementReset(agg.context, - new WinAggResetContextImpl(builder, agg.state, - null, null, null, null, null, null)); - } - } - - private void implementAdd(List<AggImpState> aggs, - final BlockBuilder builder7, - final Function<BlockBuilder, WinAggFrameResultContext> frame, - final Function<AggImpState, List<RexNode>> rexArguments, - final DeclarationStatement jDecl) { - for (final AggImpState agg : aggs) { - final WinAggAddContext addContext = - new WinAggAddContextImpl(builder7, agg.state, frame) { - public Expression currentPosition() { - return jDecl.parameter; - } - - public List<RexNode> rexArguments() { - return rexArguments.apply(agg); - } - - public RexNode rexFilterArgument() { - return null; // REVIEW - } - }; - agg.implementor.implementAdd(agg.context, addContext); - } - } - - private boolean implementResult(List<AggImpState> aggs, - final BlockBuilder builder, - final Function<BlockBuilder, WinAggFrameResultContext> frame, - final Function<AggImpState, List<RexNode>> rexArguments, - boolean cachedBlock) { - boolean nonEmpty = false; - for (final AggImpState agg : aggs) { - boolean needCache = true; - if (agg.implementor instanceof WinAggImplementor) { - WinAggImplementor imp = (WinAggImplementor) agg.implementor; - needCache = imp.needCacheWhenFrameIntact(); - } - if (needCache ^ cachedBlock) { - // 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; - } - - private Expression translateBound(RexToLixTranslator translator, - ParameterExpression i_, Expression row_, Expression min_, - Expression max_, Expression rows_, Group group, - boolean lower, - PhysType physType, Expression rowComparator, - Expression keySelector, Expression keyComparator) { - RexWindowBound bound = lower ? group.lowerBound : group.upperBound; - if (bound.isUnbounded()) { - return bound.isPreceding() ? min_ : max_; - } - if (group.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 = - group.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 " + group.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); - } - } - return Expressions.call( - (lower - ? BuiltInMethod.BINARY_SEARCH6_LOWER - : BuiltInMethod.BINARY_SEARCH6_UPPER).method, - rows_, val, searchLower, searchUpper, keySelector, keyComparator); - } -} - -// End EnumerableWindow.java
http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java deleted file mode 100644 index a295470..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindowRule.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.plan.Convention; -import org.apache.calcite.plan.RelTraitSet; -import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.convert.ConverterRule; -import org.apache.calcite.rel.logical.LogicalWindow; - -/** - * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalWindow} to - * an {@link org.apache.calcite.adapter.enumerable.EnumerableWindow}. - */ -class EnumerableWindowRule extends ConverterRule { - EnumerableWindowRule() { - super(LogicalWindow.class, Convention.NONE, EnumerableConvention.INSTANCE, - "EnumerableWindowRule"); - } - - public RelNode convert(RelNode rel) { - final LogicalWindow winAgg = (LogicalWindow) rel; - final RelTraitSet traitSet = - winAgg.getTraitSet().replace(EnumerableConvention.INSTANCE); - final RelNode child = winAgg.getInput(); - final RelNode convertedChild = - convert(child, - child.getTraitSet().replace(EnumerableConvention.INSTANCE)); - return new EnumerableWindow(rel.getCluster(), traitSet, convertedChild, - winAgg.getConstants(), winAgg.getRowType(), winAgg.groups); - } -} - -// End EnumerableWindowRule.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java deleted file mode 100644 index c4209a3..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRelImplementor.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.DataContext; -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.linq4j.tree.ParameterExpression; -import org.apache.calcite.plan.RelImplementor; -import org.apache.calcite.rex.RexBuilder; - -/** - * Abstract base class for implementations of {@link RelImplementor} - * that generate java code. - */ -public abstract class JavaRelImplementor implements RelImplementor { - private final RexBuilder rexBuilder; - - public JavaRelImplementor(RexBuilder rexBuilder) { - this.rexBuilder = rexBuilder; - assert rexBuilder.getTypeFactory() instanceof JavaTypeFactory - : "Type factory of rexBuilder should be a JavaTypeFactory"; - } - - public RexBuilder getRexBuilder() { - return rexBuilder; - } - - public JavaTypeFactory getTypeFactory() { - return (JavaTypeFactory) rexBuilder.getTypeFactory(); - } - - /** - * Returns the expression used to access - * {@link org.apache.calcite.DataContext}. - * - * @return expression used to access {@link org.apache.calcite.DataContext}. - */ - public ParameterExpression getRootExpression() { - return DataContext.ROOT; - } -} - -// End JavaRelImplementor.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java deleted file mode 100644 index 86f0002..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/JavaRowFormat.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.adapter.java.JavaTypeFactory; -import org.apache.calcite.interpreter.Row; -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.linq4j.tree.Expressions; -import org.apache.calcite.linq4j.tree.IndexExpression; -import org.apache.calcite.linq4j.tree.MemberExpression; -import org.apache.calcite.linq4j.tree.MethodCallExpression; -import org.apache.calcite.linq4j.tree.Types; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.runtime.FlatLists; -import org.apache.calcite.runtime.Unit; -import org.apache.calcite.util.BuiltInMethod; - -import java.lang.reflect.Type; -import java.util.List; - -/** - * How a row is represented as a Java value. - */ -public enum JavaRowFormat { - CUSTOM { - Type javaRowClass( - JavaTypeFactory typeFactory, - RelDataType type) { - assert type.getFieldCount() > 1; - return typeFactory.getJavaClass(type); - } - - @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index) { - return typeFactory.getJavaClass(type.getFieldList().get(index).getType()); - } - - public Expression record( - Type javaRowClass, List<Expression> expressions) { - switch (expressions.size()) { - case 0: - assert javaRowClass == Unit.class; - return Expressions.field(null, javaRowClass, "INSTANCE"); - default: - return Expressions.new_(javaRowClass, expressions); - } - } - - public MemberExpression field(Expression expression, int field, - Type fromType, Type fieldType) { - final Type type = expression.getType(); - if (type instanceof Types.RecordType) { - Types.RecordType recordType = (Types.RecordType) type; - Types.RecordField recordField = - recordType.getRecordFields().get(field); - return Expressions.field(expression, recordField.getDeclaringClass(), - recordField.getName()); - } else { - return Expressions.field(expression, Types.nthField(field, type)); - } - } - }, - - SCALAR { - Type javaRowClass( - JavaTypeFactory typeFactory, - RelDataType type) { - assert type.getFieldCount() == 1; - return typeFactory.getJavaClass( - type.getFieldList().get(0).getType()); - } - - @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index) { - return javaRowClass(typeFactory, type); - } - - public Expression record(Type javaRowClass, List<Expression> expressions) { - assert expressions.size() == 1; - return expressions.get(0); - } - - public Expression field(Expression expression, int field, Type fromType, - Type fieldType) { - assert field == 0; - return expression; - } - }, - - /** A list that is comparable and immutable. Useful for records with 0 fields - * (empty list is a good singleton) but sometimes also for records with 2 or - * more fields that you need to be comparable, say as a key in a lookup. */ - LIST { - Type javaRowClass( - JavaTypeFactory typeFactory, - RelDataType type) { - return FlatLists.ComparableList.class; - } - - @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index) { - return Object.class; - } - - public Expression record( - Type javaRowClass, List<Expression> expressions) { - switch (expressions.size()) { - case 0: - return Expressions.field( - null, - FlatLists.class, - "COMPARABLE_EMPTY_LIST"); - case 2: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST2.method, - expressions), - List.class); - case 3: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST3.method, - expressions), - List.class); - case 4: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST4.method, - expressions), - List.class); - case 5: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST5.method, - expressions), - List.class); - case 6: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST6.method, - expressions), - List.class); - default: - return Expressions.convert_( - Expressions.call( - List.class, - null, - BuiltInMethod.LIST_N.method, - Expressions.newArrayInit( - Comparable.class, - expressions)), - List.class); - } - } - - public Expression field(Expression expression, int field, Type fromType, - Type fieldType) { - final MethodCallExpression e = Expressions.call(expression, - BuiltInMethod.LIST_GET.method, Expressions.constant(field)); - if (fromType == null) { - fromType = e.getType(); - } - return RexToLixTranslator.convert(e, fromType, fieldType); - } - }, - - /** - * See {@link org.apache.calcite.interpreter.Row} - */ - ROW { - @Override Type javaRowClass(JavaTypeFactory typeFactory, RelDataType type) { - return Row.class; - } - - @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index) { - return Object.class; - } - - @Override public Expression record(Type javaRowClass, - List<Expression> expressions) { - return Expressions.call(BuiltInMethod.ROW_AS_COPY.method, expressions); - } - - public Expression field(Expression expression, int field, Type fromType, - Type fieldType) { - final Expression e = Expressions.call(expression, - BuiltInMethod.ROW_VALUE.method, Expressions.constant(field)); - if (fromType == null) { - fromType = e.getType(); - } - return RexToLixTranslator.convert(e, fromType, fieldType); - } - }, - - ARRAY { - Type javaRowClass( - JavaTypeFactory typeFactory, - RelDataType type) { - return Object[].class; - } - - @Override Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index) { - return Object.class; - } - - public Expression record(Type javaRowClass, List<Expression> expressions) { - return Expressions.newArrayInit(Object.class, expressions); - } - - @Override public Expression comparer() { - return Expressions.call(BuiltInMethod.ARRAY_COMPARER.method); - } - - public Expression field(Expression expression, int field, Type fromType, - Type fieldType) { - final IndexExpression e = Expressions.arrayIndex(expression, - Expressions.constant(field)); - if (fromType == null) { - fromType = e.getType(); - } - return RexToLixTranslator.convert(e, fromType, fieldType); - } - }; - - public JavaRowFormat optimize(RelDataType rowType) { - switch (rowType.getFieldCount()) { - case 0: - return LIST; - case 1: - return SCALAR; - default: - if (this == SCALAR) { - return LIST; - } - return this; - } - } - - abstract Type javaRowClass(JavaTypeFactory typeFactory, RelDataType type); - - /** - * Returns the java class that is used to physically store the given field. - * For instance, a non-null int field can still be stored in a field of type - * {@code Object.class} in {@link JavaRowFormat#ARRAY} case. - * - * @param typeFactory type factory to resolve java types - * @param type row type - * @param index field index - * @return java type used to store the field - */ - abstract Type javaFieldClass(JavaTypeFactory typeFactory, RelDataType type, - int index); - - public abstract Expression record( - Type javaRowClass, List<Expression> expressions); - - public Expression comparer() { - return null; - } - - /** Returns a reference to a particular field. - * - * <p>{@code fromType} may be null; if null, uses the natural type of the - * field. - */ - public abstract Expression field(Expression expression, int field, - Type fromType, Type fieldType); -} - -// End JavaRowFormat.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java deleted file mode 100644 index c78a25c..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilder.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.linq4j.tree.BlockBuilder; -import org.apache.calcite.rex.RexNode; - -import java.util.Map; - -/** - * Allows to build nested code blocks with tracking of current context and the - * nullability of particular {@link org.apache.calcite.rex.RexNode} expressions. - * - * @see org.apache.calcite.adapter.enumerable.StrictAggImplementor#implementAdd(AggContext, AggAddContext) - */ -public interface NestedBlockBuilder { - /** - * Starts nested code block. The resulting block can optimize expressions - * and reuse already calculated values from the parent blocks. - * @return new code block that can optimize expressions and reuse already - * calculated values from the parent blocks. - */ - BlockBuilder nestBlock(); - - /** - * Uses given block as the new code context. - * The current block will be restored after {@link #exitBlock()} call. - * @param block new code block - * @see #exitBlock() - */ - void nestBlock(BlockBuilder block); - - /** - * Uses given block as the new code context and the map of nullability. - * The current block will be restored after {@link #exitBlock()} call. - * @param block new code block - * @param nullables map of expression to its nullability state - * @see #exitBlock() - */ - void nestBlock(BlockBuilder block, - Map<RexNode, Boolean> nullables); - - /** - * Returns the current code block - * @return current code block - */ - BlockBuilder currentBlock(); - - /** - * Returns the current nullability state of rex nodes. - * The resulting value is the summary of all the maps in the block hierarchy. - * @return current nullability state of rex nodes - */ - Map<RexNode, Boolean> currentNullables(); - - /** - * Leaves the current code block. - * @see #nestBlock() - */ - void exitBlock(); -} - -// End NestedBlockBuilder.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java deleted file mode 100644 index 1caa47e..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NestedBlockBuilderImpl.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.linq4j.tree.BlockBuilder; -import org.apache.calcite.rex.RexNode; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Allows to build nested code blocks with tracking of current context and the - * nullability of particular {@link org.apache.calcite.rex.RexNode} expressions. - * - * @see org.apache.calcite.adapter.enumerable.StrictAggImplementor#implementAdd(AggContext, AggAddContext) - */ -public class NestedBlockBuilderImpl implements NestedBlockBuilder { - private final List<BlockBuilder> blocks = new ArrayList<BlockBuilder>(); - private final List<Map<RexNode, Boolean>> nullables = - new ArrayList<Map<RexNode, Boolean>>(); - - /** - * Constructs nested block builders starting of a given code block. - * @param block root code block - */ - public NestedBlockBuilderImpl(BlockBuilder block) { - nestBlock(block); - } - - /** - * Starts nested code block. The resulting block can optimize expressions - * and reuse already calculated values from the parent blocks. - * @return new code block that can optimize expressions and reuse already - * calculated values from the parent blocks. - */ - public final BlockBuilder nestBlock() { - BlockBuilder block = new BlockBuilder(true, currentBlock()); - nestBlock(block, Collections.<RexNode, Boolean>emptyMap()); - return block; - } - - /** - * Uses given block as the new code context. - * The current block will be restored after {@link #exitBlock()} call. - * @param block new code block - * @see #exitBlock() - */ - public final void nestBlock(BlockBuilder block) { - nestBlock(block, Collections.<RexNode, Boolean>emptyMap()); - } - - /** - * Uses given block as the new code context and the map of nullability. - * The current block will be restored after {@link #exitBlock()} call. - * @param block new code block - * @param nullables map of expression to its nullability state - * @see #exitBlock() - */ - public final void nestBlock(BlockBuilder block, - Map<RexNode, Boolean> nullables) { - blocks.add(block); - Map<RexNode, Boolean> prev = this.nullables.isEmpty() - ? Collections.<RexNode, Boolean>emptyMap() - : this.nullables.get(this.nullables.size() - 1); - Map<RexNode, Boolean> next; - if (nullables == null || nullables.isEmpty()) { - next = prev; - } else { - next = new HashMap<RexNode, Boolean>(nullables); - next.putAll(prev); - next = Collections.unmodifiableMap(next); - } - this.nullables.add(next); - } - - /** - * Returns the current code block - * @return current code block - */ - public final BlockBuilder currentBlock() { - return blocks.get(blocks.size() - 1); - } - - /** - * Returns the current nullability state of rex nodes. - * The resulting value is the summary of all the maps in the block hierarchy. - * @return current nullability state of rex nodes - */ - public final Map<RexNode, Boolean> currentNullables() { - return nullables.get(nullables.size() - 1); - } - - /** - * Leaves the current code block. - * @see #nestBlock() - */ - public final void exitBlock() { - blocks.remove(blocks.size() - 1); - nullables.remove(nullables.size() - 1); - } -} - -// End NestedBlockBuilderImpl.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java deleted file mode 100644 index 0144d3a..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NotNullImplementor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.rex.RexCall; - -import java.util.List; - -/** - * Simplified version of - * {@link org.apache.calcite.adapter.enumerable.CallImplementor} - * that does not know about null semantics. - * - * @see org.apache.calcite.adapter.enumerable.RexImpTable - * @see org.apache.calcite.adapter.enumerable.CallImplementor - */ -public interface NotNullImplementor { - /** - * Implements a call with assumption that all the null-checking is - * implemented by caller. - * - * @param translator translator to implement the code - * @param call call to implement - * @param translatedOperands arguments of a call - * @return expression that implements given call - */ - Expression implement( - RexToLixTranslator translator, - RexCall call, - List<Expression> translatedOperands); -} - -// End NotNullImplementor.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java deleted file mode 100644 index dedf300..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/NullPolicy.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -/** - * Describes when a function/operator will return null. - * - * <p>STRICT and ANY are similar. STRICT says f(a0, a1) will NEVER return - * null if a0 and a1 are not null. This means that we can check whether f - * returns null just by checking its arguments. Use STRICT in preference to - * ANY whenever possible.</p> - */ -public enum NullPolicy { - /** Returns null if and only if one of the arguments are null. */ - STRICT, - /** If any of the arguments are null, return null. */ - ANY, - /** If any of the arguments are false, result is false; else if any - * arguments are null, result is null; else true. */ - AND, - /** If any of the arguments are true, result is true; else if any - * arguments are null, result is null; else false. */ - OR, - /** If any argument is true, result is false; else if any argument is null, - * result is null; else true. */ - NOT, - NONE -} - -// End NullPolicy.java http://git-wip-us.apache.org/repos/asf/calcite-avatica/blob/fc7b26c8/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java deleted file mode 100644 index 20ae559..0000000 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/PhysType.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you 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 org.apache.calcite.adapter.enumerable; - -import org.apache.calcite.linq4j.tree.Expression; -import org.apache.calcite.linq4j.tree.ParameterExpression; -import org.apache.calcite.rel.RelCollation; -import org.apache.calcite.rel.RelFieldCollation; -import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.util.Pair; - -import java.lang.reflect.Type; -import java.util.List; - -/** - * Physical type of a row. - * - * <p>Consists of the SQL row type (returned by {@link #getRowType()}), the Java - * type of the row (returned by {@link #getJavaRowType()}), and methods to - * generate expressions to access fields, generate records, and so forth. - * Together, the records encapsulate how the logical type maps onto the physical - * type.</p> - */ -public interface PhysType { - /** Returns the Java type (often a Class) that represents a row. For - * example, in one row format, always returns {@code Object[].class}. */ - Type getJavaRowType(); - - /** - * Returns the Java class that is used to store the field with the given - * ordinal. - * - * <p>For instance, when the java row type is {@code Object[]}, the java - * field type is {@code Object} even if the field is not nullable.</p> */ - Type getJavaFieldType(int field); - - /** Returns the physical type of a field. */ - PhysType field(int ordinal); - - /** Returns the physical type of a given field's component type. */ - PhysType component(int field); - - /** Returns the SQL row type. */ - RelDataType getRowType(); - - /** Returns the Java class of the field with the given ordinal. */ - Class fieldClass(int field); - - /** Returns whether a given field allows null values. */ - boolean fieldNullable(int index); - - /** Generates a reference to a given field in an expression. - * - * <p>For example given {@code expression=employee} and {@code field=2}, - * generates</p> - * - * <pre>{@code employee.deptno}</pre> - * - * @param expression Expression - * @param field Ordinal of field - * @return Expression to access the field of the expression - */ - Expression fieldReference(Expression expression, int field); - - /** Generates a reference to a given field in an expression. - * - * <p>This method optimizes for the target storage type (i.e. avoids - * casts).</p> - * - * <p>For example given {@code expression=employee} and {@code field=2}, - * generates</p> - * - * <pre>{@code employee.deptno}</pre> - * - * @param expression Expression - * @param field Ordinal of field - * @param storageType optional hint for storage class - * @return Expression to access the field of the expression - */ - Expression fieldReference(Expression expression, int field, - Type storageType); - - /** Generates an accessor function for a given list of fields. The resulting - * object is a {@link List} (implementing {@link Object#hashCode()} and - * {@link Object#equals(Object)} per that interface) and also implements - * {@link Comparable}. - * - * <p>For example:</p> - * - * <pre>{@code - * new Function1<Employee, Object[]> { - * public Object[] apply(Employee v1) { - * return FlatLists.of(v1.<fieldN>, v1.<fieldM>); - * } - * } - * }</pre> - */ - Expression generateAccessor(List<Integer> fields); - - /** Generates a selector for the given fields from an expression, with the - * default row format. */ - Expression generateSelector( - ParameterExpression parameter, - List<Integer> fields); - - /** Generates a lambda expression that is a selector for the given fields from - * an expression. */ - Expression generateSelector( - ParameterExpression parameter, - List<Integer> fields, - JavaRowFormat targetFormat); - - /** Generates a lambda expression that is a selector for the given fields from - * an expression. - * - * <p>{@code usedFields} must be a subset of {@code fields}. - * For each field, there is a corresponding indicator field. - * If a field is used, its value is assigned and its indicator is left - * {@code false}. - * If a field is not used, its value is not assigned and its indicator is - * set to {@code true}; - * This will become a value of 1 when {@code GROUPING(field)} is called. */ - Expression generateSelector( - ParameterExpression parameter, - List<Integer> fields, - List<Integer> usedFields, - JavaRowFormat targetFormat); - - /** Generates a selector for the given fields from an expression. - * Only used by EnumerableWindow. */ - Pair<Type, List<Expression>> selector( - ParameterExpression parameter, - List<Integer> fields, - JavaRowFormat targetFormat); - - /** Projects a given collection of fields from this input record, into - * a particular preferred output format. The output format is optimized - * if there are 0 or 1 fields. */ - PhysType project( - List<Integer> integers, - JavaRowFormat format); - - /** Projects a given collection of fields from this input record, optionally - * with indicator fields, into a particular preferred output format. - * - * <p>The output format is optimized if there are 0 or 1 fields - * and indicators are disabled. */ - PhysType project( - List<Integer> integers, - boolean indicator, - JavaRowFormat format); - - /** Returns a lambda to create a collation key and a comparator. The - * comparator is sometimes null. */ - Pair<Expression, Expression> generateCollationKey( - List<RelFieldCollation> collations); - - /** Returns a comparator. Unlike the comparator returned by - * {@link #generateCollationKey(java.util.List)}, this comparator acts on the - * whole element. */ - Expression generateComparator( - RelCollation collation); - - /** Returns a expression that yields a comparer, or null if this type - * is comparable. */ - Expression comparer(); - - /** Generates an expression that creates a record for a row, initializing - * its fields with the given expressions. There must be one expression per - * field. - * - * @param expressions Expression to initialize each field - * @return Expression to create a row - */ - Expression record(List<Expression> expressions); - - /** Returns the format. */ - JavaRowFormat getFormat(); - - List<Expression> accessors(Expression parameter, List<Integer> argList); - - /** Returns a copy of this type that allows nulls if {@code nullable} is - * true. */ - PhysType makeNullable(boolean nullable); - - /** Converts an enumerable of this physical type to an enumerable that uses a - * given physical type for its rows. */ - Expression convertTo(Expression expression, PhysType targetPhysType); -} - -// End PhysType.java
