You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2015/02/12 06:22:28 UTC
[08/97] [abbrv] [partial] incubator-kylin git commit: cleanup for
migration from github.com
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPLimitRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPLimitRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPLimitRel.java
deleted file mode 100644
index 205803b..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPLimitRel.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.relnode;
-
-import java.util.List;
-
-import net.hydromatic.optiq.rules.java.EnumerableConvention;
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-import net.hydromatic.optiq.rules.java.JavaRules.EnumerableLimitRel;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.rel.RelWriter;
-import org.eigenbase.rel.SingleRel;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.relopt.RelOptCost;
-import org.eigenbase.relopt.RelOptPlanner;
-import org.eigenbase.relopt.RelTrait;
-import org.eigenbase.relopt.RelTraitSet;
-import org.eigenbase.rex.RexLiteral;
-import org.eigenbase.rex.RexNode;
-
-import com.google.common.base.Preconditions;
-
-/**
- *
- * @author xjiang
- *
- */
-public class OLAPLimitRel extends SingleRel implements OLAPRel, EnumerableRel {
-
- private final RexNode localOffset; // avoid same name in parent class
- private final RexNode localFetch; // avoid same name in parent class
- private ColumnRowType columnRowType;
- private OLAPContext context;
-
- public OLAPLimitRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, RexNode offset, RexNode fetch) {
- super(cluster, traitSet, child);
- Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION);
- Preconditions.checkArgument(getConvention() == child.getConvention());
- this.localOffset = offset;
- this.localFetch = fetch;
- }
-
- @Override
- public OLAPLimitRel copy(RelTraitSet traitSet, List<RelNode> inputs) {
- return new OLAPLimitRel(getCluster(), traitSet, sole(inputs), localOffset, localFetch);
- }
-
- @Override
- public RelOptCost computeSelfCost(RelOptPlanner planner) {
- return super.computeSelfCost(planner).multiplyBy(.05);
- }
-
- @Override
- public RelWriter explainTerms(RelWriter pw) {
- return super.explainTerms(pw).itemIf("offset", localOffset, localOffset != null).itemIf("fetch", localFetch, localFetch != null);
- }
-
- @Override
- public void implementOLAP(OLAPImplementor implementor) {
- implementor.visitChild(getChild(), this);
-
- this.columnRowType = buildColumnRowType();
-
- this.context = implementor.getContext();
- Number limitValue = (Number) (((RexLiteral) localFetch).getValue());
- int limit = limitValue.intValue();
- this.context.storageContext.setLimit(limit);
- }
-
- private ColumnRowType buildColumnRowType() {
- OLAPRel olapChild = (OLAPRel) getChild();
- ColumnRowType inputColumnRowType = olapChild.getColumnRowType();
- return inputColumnRowType;
- }
-
- @Override
- public void implementRewrite(RewriteImplementor implementor) {
- implementor.visitChild(this, getChild());
-
- this.rowType = this.deriveRowType();
- this.columnRowType = buildColumnRowType();
- }
-
- @Override
- public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
- OLAPRel childRel = (OLAPRel) getChild();
- childRel.replaceTraitSet(EnumerableConvention.INSTANCE);
-
- EnumerableLimitRel enumLimit = new EnumerableLimitRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getChild(), localOffset, localFetch);
- Result res = enumLimit.implement(implementor, pref);
-
- childRel.replaceTraitSet(OLAPRel.CONVENTION);
-
- return res;
- }
-
- @Override
- public OLAPContext getContext() {
- return context;
- }
-
- @Override
- public ColumnRowType getColumnRowType() {
- return columnRowType;
- }
-
- @Override
- public boolean hasSubQuery() {
- OLAPRel olapChild = (OLAPRel) getChild();
- return olapChild.hasSubQuery();
- }
-
- @Override
- public RelTraitSet replaceTraitSet(RelTrait trait) {
- RelTraitSet oldTraitSet = this.traitSet;
- this.traitSet = this.traitSet.replace(trait);
- return oldTraitSet;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPProjectRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPProjectRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPProjectRel.java
deleted file mode 100644
index 5f45e3e..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPProjectRel.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.relnode;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import net.hydromatic.optiq.rules.java.EnumerableConvention;
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-import net.hydromatic.optiq.rules.java.JavaRules.EnumerableCalcRel;
-
-import org.eigenbase.rel.ProjectRelBase;
-import org.eigenbase.rel.RelCollation;
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.relopt.RelOptCost;
-import org.eigenbase.relopt.RelOptPlanner;
-import org.eigenbase.relopt.RelTrait;
-import org.eigenbase.relopt.RelTraitSet;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.reltype.RelDataTypeFactory.FieldInfoBuilder;
-import org.eigenbase.reltype.RelDataTypeField;
-import org.eigenbase.reltype.RelDataTypeFieldImpl;
-import org.eigenbase.rex.RexCall;
-import org.eigenbase.rex.RexInputRef;
-import org.eigenbase.rex.RexLiteral;
-import org.eigenbase.rex.RexNode;
-import org.eigenbase.rex.RexProgram;
-import org.eigenbase.sql.SqlOperator;
-import org.eigenbase.sql.fun.SqlCaseOperator;
-import org.eigenbase.sql.fun.SqlStdOperatorTable;
-import org.eigenbase.sql.validate.SqlUserDefinedFunction;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.kylinolap.metadata.model.cube.TblColRef;
-import com.kylinolap.metadata.model.cube.TblColRef.InnerDataTypeEnum;
-
-/**
- *
- * @author xjiang
- *
- */
-public class OLAPProjectRel extends ProjectRelBase implements OLAPRel, EnumerableRel {
-
- private OLAPContext context;
- private List<RexNode> rewriteProjects;
- private boolean rewriting;
- private ColumnRowType columnRowType;
- private boolean hasJoin;
- private boolean afterJoin;
- private boolean afterAggregate;
-
- public OLAPProjectRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, List<RexNode> exps, RelDataType rowType, int flags) {
- super(cluster, traitSet, child, exps, rowType, flags);
- Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION);
- Preconditions.checkArgument(child.getConvention() == OLAPRel.CONVENTION);
- this.rewriteProjects = exps;
- this.hasJoin = false;
- this.afterJoin = false;
- this.rowType = getRowType();
- }
-
- @Override
- public List<RexNode> getChildExps() {
- return rewriteProjects;
- }
-
- @Override
- public List<RexNode> getProjects() {
- return rewriteProjects;
- }
-
- @Override
- public RelOptCost computeSelfCost(RelOptPlanner planner) {
- return super.computeSelfCost(planner).multiplyBy(.05);
- }
-
- @Override
- public ProjectRelBase copy(RelTraitSet traitSet, RelNode child, List<RexNode> exps, RelDataType rowType) {
- return new OLAPProjectRel(getCluster(), traitSet, child, exps, rowType, this.flags);
- }
-
- @Override
- public void implementOLAP(OLAPImplementor implementor) {
- implementor.visitChild(getChild(), this);
-
- this.context = implementor.getContext();
- this.hasJoin = context.hasJoin;
- this.afterJoin = context.afterJoin;
- this.afterAggregate = context.afterAggregate;
-
- this.columnRowType = buildColumnRowType();
- }
-
- private ColumnRowType buildColumnRowType() {
- List<TblColRef> columns = new ArrayList<TblColRef>();
- List<Set<TblColRef>> sourceColumns = new ArrayList<Set<TblColRef>>();
- OLAPRel olapChild = (OLAPRel) getChild();
- ColumnRowType inputColumnRowType = olapChild.getColumnRowType();
- for (int i = 0; i < this.rewriteProjects.size(); i++) {
- RexNode rex = this.rewriteProjects.get(i);
- RelDataTypeField columnField = this.rowType.getFieldList().get(i);
- String fieldName = columnField.getName();
- Set<TblColRef> sourceCollector = new HashSet<TblColRef>();
- TblColRef column = translateRexNode(rex, inputColumnRowType, fieldName, sourceCollector);
- columns.add(column);
- sourceColumns.add(sourceCollector);
- }
- return new ColumnRowType(columns, sourceColumns);
- }
-
- private TblColRef translateRexNode(RexNode rexNode, ColumnRowType inputColumnRowType, String fieldName, Set<TblColRef> sourceCollector) {
- TblColRef column = null;
- if (rexNode instanceof RexInputRef) {
- RexInputRef inputRef = (RexInputRef) rexNode;
- column = translateRexInputRef(inputRef, inputColumnRowType, fieldName, sourceCollector);
- } else if (rexNode instanceof RexLiteral) {
- RexLiteral literal = (RexLiteral) rexNode;
- column = translateRexLiteral(literal);
- } else if (rexNode instanceof RexCall) {
- RexCall call = (RexCall) rexNode;
- column = translateRexCall(call, inputColumnRowType, fieldName, sourceCollector);
- } else {
- throw new IllegalStateException("Unsupport RexNode " + rexNode);
- }
- return column;
- }
-
- private TblColRef translateRexInputRef(RexInputRef inputRef, ColumnRowType inputColumnRowType, String fieldName, Set<TblColRef> sourceCollector) {
- int index = inputRef.getIndex();
- // check it for rewrite count
- if (index < inputColumnRowType.size()) {
- TblColRef column = inputColumnRowType.getColumnByIndex(index);
- if (!column.isInnerColumn() && !this.rewriting && !this.afterAggregate) {
- context.allColumns.add(column);
- sourceCollector.add(column);
- }
- return column;
- } else {
- throw new IllegalStateException("Can't find " + inputRef + " from child columnrowtype " + inputColumnRowType + " with fieldname " + fieldName);
- }
- }
-
- private TblColRef translateRexLiteral(RexLiteral literal) {
- if (RexLiteral.isNullLiteral(literal)) {
- return TblColRef.newInnerColumn("null", InnerDataTypeEnum.LITERAL);
- } else {
- return TblColRef.newInnerColumn(literal.getValue().toString(), InnerDataTypeEnum.LITERAL);
- }
-
- }
-
- private TblColRef translateRexCall(RexCall call, ColumnRowType inputColumnRowType, String fieldName, Set<TblColRef> sourceCollector) {
- SqlOperator operator = call.getOperator();
- if (operator == SqlStdOperatorTable.EXTRACT_DATE) {
- List<RexNode> extractDateOps = call.getOperands();
- RexCall reinterpret = (RexCall) extractDateOps.get(1);
- List<RexNode> reinterpretOps = reinterpret.getOperands();
- RexInputRef inputRef = (RexInputRef) reinterpretOps.get(0);
- return translateRexInputRef(inputRef, inputColumnRowType, fieldName, sourceCollector);
- } else if (operator instanceof SqlUserDefinedFunction) {
- if (operator.getName().equals("QUARTER")) {
- List<RexNode> quaterOps = call.getOperands();
- RexInputRef inputRef = (RexInputRef) quaterOps.get(0);
- return translateRexInputRef(inputRef, inputColumnRowType, fieldName, sourceCollector);
- }
- } else if (operator instanceof SqlCaseOperator) {
- for (RexNode operand : call.getOperands()) {
- if (operand instanceof RexInputRef) {
- RexInputRef inputRef = (RexInputRef) operand;
- return translateRexInputRef(inputRef, inputColumnRowType, fieldName, sourceCollector);
- }
- }
- }
-
- for (RexNode operand : call.getOperands()) {
- translateRexNode(operand, inputColumnRowType, fieldName, sourceCollector);
- }
- return TblColRef.newInnerColumn(fieldName, InnerDataTypeEnum.LITERAL);
- }
-
- @Override
- public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
- EnumerableCalcRel enumCalcRel;
-
- RelNode child = getChild();
- if (child instanceof OLAPFilterRel) {
- // merge project & filter
- OLAPFilterRel filter = (OLAPFilterRel) getChild();
- RexProgram program = RexProgram.create(filter.getChild().getRowType(), this.rewriteProjects, filter.getCondition(), this.rowType, getCluster().getRexBuilder());
-
- enumCalcRel = new EnumerableCalcRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), filter.getChild(), this.rowType, program, ImmutableList.<RelCollation> of());
- } else {
- // keep project for tablescan
- RexProgram program = RexProgram.create(child.getRowType(), this.rewriteProjects, null, this.rowType, getCluster().getRexBuilder());
-
- enumCalcRel = new EnumerableCalcRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), child, this.rowType, program, ImmutableList.<RelCollation> of());
- }
-
- return enumCalcRel.implement(implementor, pref);
- }
-
- @Override
- public ColumnRowType getColumnRowType() {
- return columnRowType;
- }
-
- @Override
- public void implementRewrite(RewriteImplementor implementor) {
- implementor.visitChild(this, getChild());
-
- this.rewriting = true;
-
- // project before join or is just after OLAPToEnumerableConverter
- if (!RewriteImplementor.needRewrite(this.context) || (this.hasJoin && !this.afterJoin) || this.afterAggregate) {
- this.columnRowType = this.buildColumnRowType();
- return;
- }
-
- // find missed rewrite fields
- int paramIndex = this.rowType.getFieldList().size();
- List<RelDataTypeField> newFieldList = new LinkedList<RelDataTypeField>();
- List<RexNode> newExpList = new LinkedList<RexNode>();
- ColumnRowType inputColumnRowType = ((OLAPRel) getChild()).getColumnRowType();
-
- for (Map.Entry<String, RelDataType> rewriteField : this.context.rewriteFields.entrySet()) {
- String rewriteFieldName = rewriteField.getKey();
- int rowIndex = this.columnRowType.getIndexByName(rewriteFieldName);
- if (rowIndex < 0) {
- int inputIndex = inputColumnRowType.getIndexByName(rewriteFieldName);
- if (inputIndex >= 0) {
- // new field
- RelDataType fieldType = rewriteField.getValue();
- RelDataTypeField newField = new RelDataTypeFieldImpl(rewriteFieldName, paramIndex++, fieldType);
- newFieldList.add(newField);
- // new project
- RelDataTypeField inputField = getChild().getRowType().getFieldList().get(inputIndex);
- RexInputRef newFieldRef = new RexInputRef(inputField.getIndex(), inputField.getType());
- newExpList.add(newFieldRef);
- }
- }
- }
-
- if (!newFieldList.isEmpty()) {
- // rebuild projects
- List<RexNode> newProjects = new ArrayList<RexNode>(this.rewriteProjects);
- newProjects.addAll(newExpList);
- this.rewriteProjects = newProjects;
-
- // rebuild row type
- FieldInfoBuilder fieldInfo = getCluster().getTypeFactory().builder();
- fieldInfo.addAll(this.rowType.getFieldList());
- fieldInfo.addAll(newFieldList);
- this.rowType = getCluster().getTypeFactory().createStructType(fieldInfo);
- }
-
- // rebuild columns
- this.columnRowType = this.buildColumnRowType();
-
- this.rewriting = false;
- }
-
- @Override
- public OLAPContext getContext() {
- return context;
- }
-
- @Override
- public boolean hasSubQuery() {
- OLAPRel olapChild = (OLAPRel) getChild();
- return olapChild.hasSubQuery();
- }
-
- @Override
- public RelTraitSet replaceTraitSet(RelTrait trait) {
- RelTraitSet oldTraitSet = this.traitSet;
- this.traitSet = this.traitSet.replace(trait);
- return oldTraitSet;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPRel.java
deleted file mode 100644
index c773db4..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPRel.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.relnode;
-
-import java.util.Stack;
-
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.relopt.Convention;
-import org.eigenbase.relopt.RelTrait;
-import org.eigenbase.relopt.RelTraitSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author xjiang
- *
- */
-public interface OLAPRel extends RelNode {
-
- public static final Logger logger = LoggerFactory.getLogger(OLAPRel.class);
-
- // Calling convention for relational operations that occur in OLAP.
- public static final Convention CONVENTION = new Convention.Impl("OLAP", OLAPRel.class);
-
- /**
- * get olap context
- */
- public OLAPContext getContext();
-
- /**
- * get the row type of ColumnDesc
- *
- * @return
- */
- public ColumnRowType getColumnRowType();
-
- /**
- * whether has sub query
- */
- public boolean hasSubQuery();
-
- /**
- * replace RelTraitSet
- */
- public RelTraitSet replaceTraitSet(RelTrait trait);
-
- /**
- * visitor pattern for olap query analysis
- */
- public static class OLAPImplementor {
-
- private RelNode parentNode = null;
- private int ctxSeq = 0;
- private Stack<OLAPContext> ctxStack = new Stack<OLAPContext>();
-
- public void visitChild(RelNode input, RelNode parentNode) {
- this.parentNode = parentNode;
- ((OLAPRel) input).implementOLAP(this);
- }
-
- public RelNode getParentNode() {
- return parentNode;
- }
-
- public OLAPContext getContext() {
- if (ctxStack.isEmpty()) {
- return null;
- }
- return ctxStack.peek();
- }
-
- public void freeContext() {
- ctxStack.pop();
- }
-
- public void allocateContext() {
- OLAPContext context = new OLAPContext(ctxSeq++);
- ctxStack.push(context);
- OLAPContext.registerContext(context);
- }
- }
-
- public void implementOLAP(OLAPImplementor implementor);
-
- /**
- * visitor pattern for query rewrite
- */
-
- public static class RewriteImplementor {
- private OLAPContext parentContext;
-
- public void visitChild(RelNode parent, RelNode child) {
- if (parent instanceof OLAPRel) {
- OLAPRel olapRel = (OLAPRel) parent;
- this.parentContext = olapRel.getContext();
- }
- OLAPRel olapChild = (OLAPRel) child;
- olapChild.implementRewrite(this);
- }
-
- public OLAPContext getParentContext() {
- return parentContext;
- }
-
- public static boolean needRewrite(OLAPContext ctx) {
- boolean hasFactTable = ctx.hasJoin || ctx.firstTableScan.getCubeTable().equals(ctx.cubeDesc.getFactTable());
- boolean hasRewriteFields = !ctx.rewriteFields.isEmpty();
- return hasRewriteFields && hasFactTable;
- }
- }
-
- public void implementRewrite(RewriteImplementor rewriter);
-
- /**
- * implementor for java generation
- */
- public static class JavaImplementor extends EnumerableRelImplementor {
-
- private OLAPContext parentContext;
-
- public JavaImplementor(EnumerableRelImplementor enumImplementor) {
- super(enumImplementor.getRexBuilder());
- }
-
- public OLAPContext getParentContext() {
- return parentContext;
- }
-
- @Override
- public EnumerableRel.Result visitChild(EnumerableRel parent, int ordinal, EnumerableRel child, EnumerableRel.Prefer prefer) {
- if (parent instanceof OLAPRel) {
- OLAPRel olapRel = (OLAPRel) parent;
- this.parentContext = olapRel.getContext();
- }
- return super.visitChild(parent, ordinal, child, prefer);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPSortRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPSortRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPSortRel.java
deleted file mode 100644
index 9d71eaf..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPSortRel.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.kylinolap.query.relnode;
-
-import net.hydromatic.optiq.rules.java.EnumerableConvention;
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-import net.hydromatic.optiq.rules.java.JavaRules.EnumerableSortRel;
-
-import org.eigenbase.rel.RelCollation;
-import org.eigenbase.rel.RelFieldCollation;
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.rel.SortRel;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.relopt.RelOptCost;
-import org.eigenbase.relopt.RelOptPlanner;
-import org.eigenbase.relopt.RelTrait;
-import org.eigenbase.relopt.RelTraitSet;
-import org.eigenbase.rex.RexNode;
-
-import com.google.common.base.Preconditions;
-import com.kylinolap.metadata.model.cube.MeasureDesc;
-import com.kylinolap.metadata.model.cube.TblColRef;
-import com.kylinolap.storage.StorageContext;
-
-/**
- * @author xjiang
- *
- */
-public class OLAPSortRel extends SortRel implements EnumerableRel, OLAPRel {
-
- private ColumnRowType columnRowType;
- private OLAPContext context;
-
- public OLAPSortRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
- super(cluster, traitSet, child, collation, offset, fetch);
- Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION);
- Preconditions.checkArgument(getConvention() == child.getConvention());
- }
-
- @Override
- public OLAPSortRel copy(RelTraitSet traitSet, RelNode newInput, RelCollation newCollation, RexNode offset, RexNode fetch) {
- return new OLAPSortRel(getCluster(), traitSet, newInput, newCollation, offset, fetch);
- }
-
- @Override
- public RelOptCost computeSelfCost(RelOptPlanner planner) {
- return super.computeSelfCost(planner).multiplyBy(.05);
- }
-
- @Override
- public void implementOLAP(OLAPImplementor implementor) {
- implementor.visitChild(getChild(), this);
-
- this.context = implementor.getContext();
- this.columnRowType = buildColumnRowType();
- }
-
- private ColumnRowType buildColumnRowType() {
- OLAPRel olapChild = (OLAPRel) getChild();
- ColumnRowType inputColumnRowType = olapChild.getColumnRowType();
- return inputColumnRowType;
- }
-
- @Override
- public void implementRewrite(RewriteImplementor implementor) {
- implementor.visitChild(this, getChild());
-
- for (RelFieldCollation fieldCollation : this.collation.getFieldCollations()) {
- int index = fieldCollation.getFieldIndex();
- StorageContext.OrderEnum order = getOrderEnum(fieldCollation.getDirection());
- OLAPRel olapChild = (OLAPRel) this.getChild();
- TblColRef orderCol = olapChild.getColumnRowType().getAllColumns().get(index);
- MeasureDesc measure = findMeasure(orderCol);
- if (measure != null) {
- this.context.storageContext.addSort(measure, order);
- }
- this.context.storageContext.markSort();
- }
-
- this.rowType = this.deriveRowType();
- this.columnRowType = buildColumnRowType();
- }
-
- private StorageContext.OrderEnum getOrderEnum(RelFieldCollation.Direction direction) {
- if (direction == RelFieldCollation.Direction.DESCENDING) {
- return StorageContext.OrderEnum.DESCENDING;
- } else {
- return StorageContext.OrderEnum.ASCENDING;
- }
- }
-
- private MeasureDesc findMeasure(TblColRef col) {
- for (MeasureDesc measure : this.context.cubeDesc.getMeasures()) {
- if (col.getName().equals(measure.getFunction().getRewriteFieldName())) {
- return measure;
- }
- }
- return null;
- }
-
- @Override
- public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
- OLAPRel childRel = (OLAPRel) getChild();
- childRel.replaceTraitSet(EnumerableConvention.INSTANCE);
-
- EnumerableSortRel enumSort = new EnumerableSortRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE, collation), getChild(), collation, offset, fetch);
-
- Result res = enumSort.implement(implementor, pref);
-
- childRel.replaceTraitSet(OLAPRel.CONVENTION);
-
- return res;
- }
-
- @Override
- public OLAPContext getContext() {
- return context;
- }
-
- @Override
- public ColumnRowType getColumnRowType() {
- return columnRowType;
- }
-
- @Override
- public boolean hasSubQuery() {
- OLAPRel olapChild = (OLAPRel) getChild();
- return olapChild.hasSubQuery();
- }
-
- @Override
- public RelTraitSet replaceTraitSet(RelTrait trait) {
- RelTraitSet oldTraitSet = this.traitSet;
- this.traitSet = this.traitSet.replace(trait);
- return oldTraitSet;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPTableScan.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPTableScan.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPTableScan.java
deleted file mode 100644
index 9c50c36..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPTableScan.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.relnode;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import net.hydromatic.linq4j.expressions.Blocks;
-import net.hydromatic.linq4j.expressions.Expressions;
-import net.hydromatic.linq4j.expressions.Primitive;
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-import net.hydromatic.optiq.rules.java.PhysType;
-import net.hydromatic.optiq.rules.java.PhysTypeImpl;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.rel.RelWriter;
-import org.eigenbase.rel.TableAccessRelBase;
-import org.eigenbase.rel.rules.*;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.relopt.RelOptCost;
-import org.eigenbase.relopt.RelOptPlanner;
-import org.eigenbase.relopt.RelOptTable;
-import org.eigenbase.relopt.RelTrait;
-import org.eigenbase.relopt.RelTraitSet;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.reltype.RelDataTypeFactory;
-import org.eigenbase.reltype.RelDataTypeField;
-
-import com.google.common.base.Preconditions;
-import com.kylinolap.metadata.model.cube.TblColRef;
-import com.kylinolap.metadata.model.schema.ColumnDesc;
-import com.kylinolap.query.optrule.OLAPAggregateRule;
-import com.kylinolap.query.optrule.OLAPFilterRule;
-import com.kylinolap.query.optrule.OLAPJoinRule;
-import com.kylinolap.query.optrule.OLAPLimitRule;
-import com.kylinolap.query.optrule.OLAPProjectRule;
-import com.kylinolap.query.optrule.OLAPSortRule;
-import com.kylinolap.query.optrule.OLAPToEnumerableConverterRule;
-import com.kylinolap.query.schema.OLAPSchema;
-import com.kylinolap.query.schema.OLAPTable;
-
-/**
- * @author xjiang
- */
-public class OLAPTableScan extends TableAccessRelBase implements OLAPRel, EnumerableRel {
-
- private final OLAPTable olapTable;
- private final String cubeTable;
- private final int[] fields;
- private ColumnRowType columnRowType;
- private OLAPContext context;
-
- public OLAPTableScan(RelOptCluster cluster, RelOptTable table, OLAPTable olapTable, int[] fields) {
- super(cluster, cluster.traitSetOf(OLAPRel.CONVENTION), table);
- this.olapTable = olapTable;
- this.fields = fields;
- this.cubeTable = olapTable.getTableName();
- this.rowType = getRowType();
- }
-
- public OLAPTable getOlapTable() {
- return olapTable;
- }
-
- public String getCubeTable() {
- return cubeTable;
- }
-
- public int[] getFields() {
- return fields;
- }
-
- @Override
- public OLAPContext getContext() {
- return context;
- }
-
- @Override
- public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
- Preconditions.checkArgument(inputs.isEmpty());
- return new OLAPTableScan(getCluster(), table, olapTable, fields);
- }
-
- @Override
- public void register(RelOptPlanner planner) {
- // force clear the query context before traversal relational operators
- OLAPContext.clearThreadLocalContexts();
-
- // register OLAP rules
- planner.addRule(OLAPToEnumerableConverterRule.INSTANCE);
- planner.addRule(OLAPFilterRule.INSTANCE);
- planner.addRule(OLAPProjectRule.INSTANCE);
- planner.addRule(OLAPAggregateRule.INSTANCE);
- planner.addRule(OLAPJoinRule.INSTANCE);
- planner.addRule(OLAPLimitRule.INSTANCE);
- planner.addRule(OLAPSortRule.INSTANCE);
-
- // since join is the entry point, we can't push filter past join
- planner.removeRule(PushFilterPastJoinRule.FILTER_ON_JOIN);
- planner.removeRule(PushFilterPastJoinRule.JOIN);
-
- // TODO : since we don't have statistic of table, the optimization of join is too cost
- planner.removeRule(SwapJoinRule.INSTANCE);
- planner.removeRule(PushJoinThroughJoinRule.LEFT);
- planner.removeRule(PushJoinThroughJoinRule.RIGHT);
-
- // for columns in having clause will enable table scan filter rule
- // cause kylin does not depend on MPP
- planner.removeRule(PushFilterPastProjectRule.INSTANCE);
- // distinct count will be split into a separated query that is joined with the left query
- planner.removeRule(RemoveDistinctAggregateRule.INSTANCE);
- }
-
- @Override
- public RelDataType deriveRowType() {
- final List<RelDataTypeField> fieldList = table.getRowType().getFieldList();
- final RelDataTypeFactory.FieldInfoBuilder builder = getCluster().getTypeFactory().builder();
- for (int field : fields) {
- builder.add(fieldList.get(field));
- }
- return getCluster().getTypeFactory().createStructType(builder);
- }
-
- @Override
- public RelOptCost computeSelfCost(RelOptPlanner planner) {
- return super.computeSelfCost(planner).multiplyBy(.05);
- }
-
- @Override
- public RelWriter explainTerms(RelWriter pw) {
- return super.explainTerms(pw).item("fields", Primitive.asList(fields));
- }
-
- @Override
- public void implementOLAP(OLAPImplementor implementor) {
- // create context in case of non-join
- if (implementor.getContext() == null || !(implementor.getParentNode() instanceof OLAPJoinRel)) {
- implementor.allocateContext();
- }
- columnRowType = buildColumnRowType();
- context = implementor.getContext();
-
- if (context.olapSchema == null) {
- OLAPSchema schema = olapTable.getSchema();
- context.olapSchema = schema;
- context.storageContext.setConnUrl(schema.getStorageUrl());
- }
-
- if (context.firstTableScan == null) {
- context.firstTableScan = this;
- }
-
- context.olapRowType = rowType;
- }
-
- private ColumnRowType buildColumnRowType() {
- List<TblColRef> columns = new ArrayList<TblColRef>();
- for (ColumnDesc sourceColumn : olapTable.getExposedColumns()) {
- TblColRef colRef = new TblColRef(sourceColumn);
- columns.add(colRef);
- }
- return new ColumnRowType(columns);
- }
-
- @Override
- public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
- if (!(implementor instanceof JavaImplementor))
- throw new IllegalStateException("implementor is not JavaImplementor");
- JavaImplementor javaImplementor = (JavaImplementor) implementor;
-
- int ctxId = this.context.id;
- if (javaImplementor.getParentContext() != null) {
- ctxId = javaImplementor.getParentContext().id;
- }
-
- PhysType physType = PhysTypeImpl.of(javaImplementor.getTypeFactory(), this.rowType, pref.preferArray());
-
- String execFunction = genExecFunc();
-
- return javaImplementor.result(physType, Blocks.toBlock(Expressions.call(table.getExpression(OLAPTable.class), execFunction, javaImplementor.getRootExpression(), Expressions.constant(ctxId))));
- }
-
- private String genExecFunc() {
- // if the table to scan is not the fact table of cube, then it's a
- // lookup table
- if (context.hasJoin == false && cubeTable.equals(context.cubeDesc.getFactTable()) == false) {
- return "executeLookupTableQuery";
- } else {
- return "executeCubeQuery";
- }
-
- }
-
- @Override
- public ColumnRowType getColumnRowType() {
- return columnRowType;
- }
-
- /**
- * Because OLAPTableScan is reused for the same table, we can't use
- * this.context and have to use parent context
- */
- @Override
- public void implementRewrite(RewriteImplementor implementor) {
- Map<String, RelDataType> rewriteFields = this.context.rewriteFields;
- if (implementor.getParentContext() != null) {
- rewriteFields = implementor.getParentContext().rewriteFields;
- }
-
- for (Map.Entry<String, RelDataType> rewriteField : rewriteFields.entrySet()) {
- String fieldName = rewriteField.getKey();
- RelDataTypeField field = rowType.getField(fieldName, true);
- if (field != null) {
- RelDataType fieldType = field.getType();
- rewriteField.setValue(fieldType);
- }
- }
- }
-
- @Override
- public boolean hasSubQuery() {
- return false;
- }
-
- @Override
- public RelTraitSet replaceTraitSet(RelTrait trait) {
- RelTraitSet oldTraitSet = this.traitSet;
- this.traitSet = this.traitSet.replace(trait);
- return oldTraitSet;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPToEnumerableConverter.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPToEnumerableConverter.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPToEnumerableConverter.java
deleted file mode 100644
index b38282e..0000000
--- a/query/src/main/java/com/kylinolap/query/relnode/OLAPToEnumerableConverter.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.relnode;
-
-import java.util.List;
-
-import net.hydromatic.linq4j.expressions.Blocks;
-import net.hydromatic.linq4j.expressions.Expressions;
-import net.hydromatic.optiq.rules.java.EnumerableRel;
-import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
-import net.hydromatic.optiq.rules.java.PhysType;
-import net.hydromatic.optiq.rules.java.PhysTypeImpl;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.rel.convert.ConverterRelImpl;
-import org.eigenbase.relopt.ConventionTraitDef;
-import org.eigenbase.relopt.RelOptCluster;
-import org.eigenbase.relopt.RelOptCost;
-import org.eigenbase.relopt.RelOptPlanner;
-import org.eigenbase.relopt.RelOptTable;
-import org.eigenbase.relopt.RelTraitSet;
-import org.eigenbase.reltype.RelDataType;
-
-import com.kylinolap.cube.CubeInstance;
-import com.kylinolap.query.relnode.OLAPRel.JavaImplementor;
-import com.kylinolap.query.relnode.OLAPRel.OLAPImplementor;
-import com.kylinolap.query.relnode.OLAPRel.RewriteImplementor;
-import com.kylinolap.query.routing.CubeNotFoundException;
-import com.kylinolap.query.routing.QueryRouter;
-import com.kylinolap.query.schema.OLAPTable;
-
-/**
- * @author xjiang
- */
-public class OLAPToEnumerableConverter extends ConverterRelImpl implements EnumerableRel {
-
- public OLAPToEnumerableConverter(RelOptCluster cluster, RelTraitSet traits, RelNode input) {
- super(cluster, ConventionTraitDef.INSTANCE, traits, input);
- }
-
- @Override
- public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
- return new OLAPToEnumerableConverter(getCluster(), traitSet, sole(inputs));
- }
-
- @Override
- public RelOptCost computeSelfCost(RelOptPlanner planner) {
- return super.computeSelfCost(planner).multiplyBy(.05);
- }
-
- @Override
- public Result implement(EnumerableRelImplementor enumImplementor, Prefer pref) {
- // post-order travel children
- OLAPImplementor olapImplementor = new OLAPRel.OLAPImplementor();
- olapImplementor.visitChild(getChild(), this);
-
- // find cube from olap context
- try {
- for (OLAPContext context : OLAPContext.getThreadLocalContexts()) {
- CubeInstance cube = QueryRouter.findCube(context);
- context.cubeInstance = cube;
- context.cubeDesc = cube.getDescriptor();
- }
- } catch (CubeNotFoundException e) {
- OLAPContext ctx0 = (OLAPContext) OLAPContext.getThreadLocalContexts().toArray()[0];
- if (ctx0 != null && ctx0.olapSchema.hasStarSchemaUrl()) {
- // generate hive result
- return buildHiveResult(enumImplementor, pref, ctx0);
- } else {
- throw e;
- }
- }
-
- // rewrite query if necessary
- RewriteImplementor rewriteImplementor = new RewriteImplementor();
- rewriteImplementor.visitChild(this, getChild());
-
- // build java implementation
- EnumerableRel child = (EnumerableRel) getChild();
- JavaImplementor javaImplementor = new JavaImplementor(enumImplementor);
- return javaImplementor.visitChild(this, 0, child, pref);
-
- }
-
- private Result buildHiveResult(EnumerableRelImplementor enumImplementor, Prefer pref, OLAPContext context) {
- RelDataType hiveRowType = getRowType();
-
- context.olapRowType = hiveRowType;
- PhysType physType = PhysTypeImpl.of(enumImplementor.getTypeFactory(), hiveRowType, pref.preferArray());
-
- RelOptTable factTable = context.firstTableScan.getTable();
- Result result = enumImplementor.result(physType, Blocks.toBlock(Expressions.call(factTable.getExpression(OLAPTable.class), "executeHiveQuery", enumImplementor.getRootExpression())));
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/routing/CubeNotFoundException.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/routing/CubeNotFoundException.java b/query/src/main/java/com/kylinolap/query/routing/CubeNotFoundException.java
deleted file mode 100644
index b8b09ff..0000000
--- a/query/src/main/java/com/kylinolap/query/routing/CubeNotFoundException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.kylinolap.query.routing;
-
-/**
- * @author xjiang
- *
- */
-public class CubeNotFoundException extends RuntimeException {
-
- private static final long serialVersionUID = 4372584597304243555L;
-
- public CubeNotFoundException(String message, Throwable t) {
- super(message, t);
- }
-
- public CubeNotFoundException(String message) {
- super(message);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/routing/QueryRouter.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/routing/QueryRouter.java b/query/src/main/java/com/kylinolap/query/routing/QueryRouter.java
deleted file mode 100644
index 7745c2a..0000000
--- a/query/src/main/java/com/kylinolap/query/routing/QueryRouter.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.routing;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.lang3.StringUtils;
-import org.eigenbase.reltype.RelDataType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.kylinolap.cube.CubeInstance;
-import com.kylinolap.cube.CubeManager;
-import com.kylinolap.cube.project.ProjectManager;
-import com.kylinolap.metadata.model.cube.CubeDesc;
-import com.kylinolap.metadata.model.cube.DimensionDesc;
-import com.kylinolap.metadata.model.cube.FunctionDesc;
-import com.kylinolap.metadata.model.cube.JoinDesc;
-import com.kylinolap.metadata.model.cube.ParameterDesc;
-import com.kylinolap.metadata.model.cube.TblColRef;
-import com.kylinolap.query.relnode.OLAPContext;
-
-/**
- * @author xjiang
- */
-public class QueryRouter {
-
- private static final Logger logger = LoggerFactory.getLogger(QueryRouter.class);
-
- public static CubeInstance findCube(OLAPContext olapContext) throws CubeNotFoundException {
-
- CubeInstance bestCube = null;
- // NOTE: since some query has no groups and projections are the superset of groups, we choose projections.
- ProjectManager projectManager = ProjectManager.getInstance(olapContext.olapSchema.getConfig());
-
- if (olapContext.isSimpleQuery()) {
- // if simple query like "select X from fact table", just return the cube with most dimensions
- // Note that this will only succeed to get best cube if the current simple query is on fact table.
- // Simple query on look up table is handled in OLAPTableScan.genExecFunc
- // In other words, for simple query on lookup tables, bestCube here will be assigned null in this method
- bestCube = findCubeWithMostDimensions(projectManager, olapContext);
- }
-
- if (bestCube == null) {
- bestCube = findBestMatchCube(projectManager, olapContext);
- }
-
- if (bestCube == null) {
- throw new CubeNotFoundException("Can't find cube for fact table " + olapContext.firstTableScan.getCubeTable() //
- + " in project " + olapContext.olapSchema.getProjectName() + " with dimensions " //
- + getDimensionColumns(olapContext) + " and measures " + olapContext.aggregations //
- + ". Also please check whether join types match what defined in Cube.");
- }
-
- return bestCube;
- }
-
- private static CubeInstance findCubeWithMostDimensions(ProjectManager projectManager, OLAPContext olapContext) {
- List<CubeInstance> candidates = projectManager.getOnlineCubesByFactTable(olapContext.olapSchema.getProjectName(), olapContext.firstTableScan.getCubeTable());
- if (candidates.isEmpty()) {
- return null;
- }
-
- CubeInstance cubeWithMostColumns = candidates.get(0);
- for (CubeInstance instance : candidates) {
- int currentDimCount = instance.getDescriptor().listDimensionColumnsIncludingDerived().size();
- int maxDimCount = cubeWithMostColumns.getDescriptor().listDimensionColumnsIncludingDerived().size();
-
- if ((currentDimCount > maxDimCount) || ((currentDimCount == maxDimCount) && (instance.getCost() < cubeWithMostColumns.getCost())))
- cubeWithMostColumns = instance;
- }
- return cubeWithMostColumns;
- }
-
- private static void sortByCost(List<CubeInstance> matchCubes) {
- // sort cube candidates, 0) the cost indicator, 1) the lesser header
- // columns the better, 2) the lesser body columns the better
- Collections.sort(matchCubes, new Comparator<CubeInstance>() {
- @Override
- public int compare(CubeInstance c1, CubeInstance c2) {
- int comp = 0;
- comp = c1.getCost() - c2.getCost();
- if (comp != 0) {
- return comp;
- }
-
- CubeDesc schema1 = c1.getDescriptor();
- CubeDesc schema2 = c2.getDescriptor();
-
- comp = schema1.listDimensionColumnsIncludingDerived().size() - schema2.listDimensionColumnsIncludingDerived().size();
- if (comp != 0)
- return comp;
-
- comp = schema1.getMeasures().size() - schema2.getMeasures().size();
- return comp;
- }
- });
- }
-
- private static Collection<TblColRef> getDimensionColumns(OLAPContext olapContext) {
- Collection<TblColRef> dimensionColumns = new HashSet<TblColRef>();
- dimensionColumns.addAll(olapContext.allColumns);
- for (TblColRef measureColumn : olapContext.metricsColumns) {
- dimensionColumns.remove(measureColumn);
- }
- return dimensionColumns;
- }
-
- static List<CubeInstance> findMatchCubesForTableScanQuery(CubeManager cubeMgr, String factTableName, Collection<TblColRef> dimensionColumns, Collection<FunctionDesc> functions) throws CubeNotFoundException {
- return null;
- }
-
- static CubeInstance findBestMatchCube(ProjectManager projectManager, OLAPContext olapContext) throws CubeNotFoundException {
-
- // retrieve members from olapContext
- String factTableName = olapContext.firstTableScan.getCubeTable();
- String projectName = olapContext.olapSchema.getProjectName();
- Collection<TblColRef> dimensionColumns = getDimensionColumns(olapContext);
- Collection<FunctionDesc> functions = olapContext.aggregations;
- Collection<TblColRef> metricsColumns = olapContext.metricsColumns;
- Collection<JoinDesc> joins = olapContext.joins;
- Map<String, RelDataType> rewriteFields = olapContext.rewriteFields;
-
- // find cubes by table
- List<CubeInstance> candidates = projectManager.getCubesByTable(projectName, factTableName);
- logger.info("Find candidates by table " + factTableName + " and project=" + projectName + " : " + StringUtils.join(candidates, ","));
-
- // match dimensions & aggregations & joins
- Iterator<CubeInstance> it = candidates.iterator();
- List<CubeInstance> backups = new ArrayList<CubeInstance>();
-
- while (it.hasNext()) {
- CubeInstance cube = it.next();
- boolean isOnline = cube.isReady();
-
- boolean matchDimensions = isMatchedWithDimensions(dimensionColumns, cube);
- boolean matchAggregation = isMatchedWithAggregations(functions, cube);
- boolean matchJoin = isMatchedWithJoins(joins, cube);
-
- // Some cubes are not "perfectly" match, but still save them in case of usage
- if (isOnline && matchDimensions && !matchAggregation && matchJoin) {
- // sometimes metrics are indeed dimensions
- // e.g. select min(cal_dt) from ..., where cal_dt is actually a dimension
- if (isWeaklyMatchedWithAggregations(functions, metricsColumns, cube)) {
- logger.info("Weak matched cube " + cube);
- backups.add(cube);
- }
- }
-
- if (!isOnline || !matchDimensions || !matchAggregation || !matchJoin) {
- logger.info("Remove cube " + cube.getName() + " because " + " isOnlne=" + isOnline + ",matchDimensions=" + matchDimensions + ",matchAggregation=" + matchAggregation + ",matchJoin=" + matchJoin);
- it.remove();
- }
- }
-
- // normal case:
- if (!candidates.isEmpty()) {
- return getCheapestCube(candidates);
- }
- // consider backup
- else if (!backups.isEmpty()) {
- CubeInstance cube = getCheapestCube(backups);
- // Using backup cubes indicates that previous judgment on dimensions/metrics is incorrect
- adjustOLAPContext(dimensionColumns, functions, metricsColumns, cube, rewriteFields, olapContext);
- logger.info("Use weak matched cube " + cube.getName());
- return cube;
- }
- return null;
- }
-
- private static CubeInstance getCheapestCube(List<CubeInstance> candidates) {
- sortByCost(candidates);
- CubeInstance bestCube = null;
- if (!candidates.isEmpty()) {
- bestCube = candidates.iterator().next();
- }
- return bestCube;
- }
-
- private static boolean isMatchedWithDimensions(Collection<TblColRef> dimensionColumns, CubeInstance cube) {
- CubeDesc cubeDesc = cube.getDescriptor();
- boolean matchAgg = cubeDesc.listDimensionColumnsIncludingDerived().containsAll(dimensionColumns);
- return matchAgg;
- }
-
- private static boolean isMatchedWithAggregations(Collection<FunctionDesc> aggregations, CubeInstance cube) {
- CubeDesc cubeDesc = cube.getDescriptor();
- boolean matchAgg = cubeDesc.listAllFunctions().containsAll(aggregations);
- return matchAgg;
- }
-
- private static boolean isMatchedWithJoins(Collection<JoinDesc> joins, CubeInstance cube) throws CubeNotFoundException {
- CubeDesc cubeDesc = cube.getDescriptor();
-
- List<JoinDesc> cubeJoins = new ArrayList<JoinDesc>(cubeDesc.getDimensions().size());
- for (DimensionDesc d : cubeDesc.getDimensions()) {
- if (d.getJoin() != null) {
- cubeJoins.add(d.getJoin());
- }
- }
- for (JoinDesc j : joins) {
- // optiq engine can't decide which one is fk or pk
- String pTable = j.getPrimaryKeyColumns()[0].getTable();
- String factTable = cubeDesc.getFactTable();
- if (factTable.equals(pTable)) {
- j.swapPKFK();
- }
-
- // check primary key, all PK column should refer to same tale, the Fact Table of cube.
- // Using first column's table name to check.
- String fTable = j.getForeignKeyColumns()[0].getTable();
- if (!factTable.equals(fTable)) {
- logger.info("Fact Table" + factTable + " not matched in join: " + j + " on cube " + cube.getName());
- return false;
- }
-
- // The hashcode() function of JoinDesc has been overwritten,
- // which takes into consideration: pk,fk,jointype
- if (!cubeJoins.contains(j)) {
- logger.info("Query joins don't macth on cube " + cube.getName());
- return false;
- }
- }
- return true;
- }
-
- private static boolean isWeaklyMatchedWithAggregations(Collection<FunctionDesc> aggregations, Collection<TblColRef> metricColumns, CubeInstance cube) {
- CubeDesc cubeDesc = cube.getDescriptor();
- Collection<FunctionDesc> cubeFuncs = cubeDesc.listAllFunctions();
-
- boolean matched = true;
- for (FunctionDesc functionDesc : aggregations) {
- if (cubeFuncs.contains(functionDesc))
- continue;
-
- // only inverted-index cube does not have count, and let calcite handle in this case
- if (functionDesc.isCount())
- continue;
-
- if (functionDesc.isCountDistinct()) // calcite can not handle distinct count
- matched = false;
-
- TblColRef col = findTblColByMetrics(metricColumns, functionDesc);
- if (col == null || !cubeDesc.listDimensionColumnsIncludingDerived().contains(col)) {
- matched = false;
- }
- }
- return matched;
- }
-
- private static void adjustOLAPContext(Collection<TblColRef> dimensionColumns, Collection<FunctionDesc> aggregations, //
- Collection<TblColRef> metricColumns, CubeInstance cube, Map<String, RelDataType> rewriteFields, OLAPContext olapContext) {
- CubeDesc cubeDesc = cube.getDescriptor();
- Collection<FunctionDesc> cubeFuncs = cubeDesc.listAllFunctions();
-
- Iterator<FunctionDesc> it = aggregations.iterator();
- while (it.hasNext()) {
- FunctionDesc functionDesc = it.next();
- if (!cubeFuncs.contains(functionDesc)) {
- // try to convert the metric to dimension to see if it works
- TblColRef col = findTblColByMetrics(metricColumns, functionDesc);
- functionDesc.setAppliedOnDimension(true);
- rewriteFields.remove(functionDesc.getRewriteFieldName());
- if (col != null) {
- metricColumns.remove(col);
- dimensionColumns.add(col);
- olapContext.storageContext.addOtherMandatoryColumns(col);
- }
- logger.info("Adjust OLAPContext for " + functionDesc);
- }
- }
- }
-
- private static TblColRef findTblColByMetrics(Collection<TblColRef> dimensionColumns, FunctionDesc func) {
- if (func.isCount())
- return null; // count is not about any column but the whole row
-
- ParameterDesc parameter = func.getParameter();
- if (parameter == null)
- return null;
-
- String columnName = parameter.getValue();
- for (TblColRef col : dimensionColumns) {
- String name = col.getName();
- if (name != null && name.equals(columnName))
- return col;
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/schema/OLAPSchema.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/schema/OLAPSchema.java b/query/src/main/java/com/kylinolap/query/schema/OLAPSchema.java
deleted file mode 100644
index 0bb7689..0000000
--- a/query/src/main/java/com/kylinolap/query/schema/OLAPSchema.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.schema;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.hydromatic.optiq.Table;
-import net.hydromatic.optiq.impl.AbstractSchema;
-
-import com.kylinolap.common.KylinConfig;
-import com.kylinolap.cube.CubeManager;
-import com.kylinolap.cube.project.ProjectInstance;
-import com.kylinolap.cube.project.ProjectManager;
-import com.kylinolap.metadata.MetadataManager;
-import com.kylinolap.metadata.model.schema.TableDesc;
-
-/**
- * @author xjiang
- */
-public class OLAPSchema extends AbstractSchema {
-
-// private static final Logger logger = LoggerFactory.getLogger(OLAPSchema.class);
-
- private KylinConfig config;
- private String projectName;
- private String schemaName;
- private String storageUrl;
- private String starSchemaUrl;
- private String starSchemaUser;
- private String starSchemaPassword;
-
- private void init() {
- this.config = KylinConfig.getInstanceFromEnv();
- this.storageUrl = config.getStorageUrl();
- this.starSchemaUrl = config.getHiveUrl();
- this.starSchemaUser = config.getHiveUser();
- this.starSchemaPassword = config.getHivePassword();
- }
-
- public OLAPSchema(String project, String schemaName) {
- this.projectName = ProjectInstance.getNormalizedProjectName(project);
- this.schemaName = schemaName;
- init();
- }
-
- @Override
- protected Map<String, Table> getTableMap() {
- return buildTableMap();
- }
-
- private Map<String, Table> buildTableMap() {
- Map<String, Table> olapTables = new HashMap<String, Table>();
- List<TableDesc> projectTables = getProjectManager().listExposedTables(projectName);
-
- for (TableDesc tableDesc : projectTables) {
- final String tableName = tableDesc.getName();
- final OLAPTable table = new OLAPTable(this, tableDesc);
- olapTables.put(tableName, table);
-// logger.debug("Project " + projectName + " exposes table " + tableName);
- }
-
- return olapTables;
- }
-
- public String getSchemaName() {
- return schemaName;
- }
-
- public String getStorageUrl() {
- return storageUrl;
- }
-
- public boolean hasStarSchemaUrl() {
- return starSchemaUrl != null && !starSchemaUrl.isEmpty();
- }
-
- public String getStarSchemaUrl() {
- return starSchemaUrl;
- }
-
- public String getStarSchemaUser() {
- return starSchemaUser;
- }
-
- public String getStarSchemaPassword() {
- return starSchemaPassword;
- }
-
- public MetadataManager getMetadataManager() {
- return MetadataManager.getInstance(config);
- }
-
- public KylinConfig getConfig() {
- return config;
- }
-
- public String getProjectName() {
- return this.projectName;
- }
-
- public CubeManager getCubeManager() {
- return CubeManager.getInstance(config);
- }
-
- public ProjectManager getProjectManager() {
- return ProjectManager.getInstance(config);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/schema/OLAPSchemaFactory.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/schema/OLAPSchemaFactory.java b/query/src/main/java/com/kylinolap/query/schema/OLAPSchemaFactory.java
deleted file mode 100644
index f3dcb8e..0000000
--- a/query/src/main/java/com/kylinolap/query/schema/OLAPSchemaFactory.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.schema;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.hydromatic.optiq.Schema;
-import net.hydromatic.optiq.SchemaFactory;
-import net.hydromatic.optiq.SchemaPlus;
-
-import org.eigenbase.util14.ConversionUtil;
-
-import com.kylinolap.common.KylinConfig;
-import com.kylinolap.cube.project.ProjectInstance;
-import com.kylinolap.cube.project.ProjectManager;
-import com.kylinolap.metadata.model.schema.DatabaseDesc;
-import com.kylinolap.metadata.model.schema.TableDesc;
-
-/**
- * @author xjiang
- */
-public class OLAPSchemaFactory implements SchemaFactory {
-
- static {
- /*
- * Tricks Optiq to work with Unicode.
- *
- * Sets default char set for string literals in SQL and row types of
- * RelNode. This is more a label used to compare row type equality. For
- * both SQL string and row record, they are passed to Optiq in String
- * object and does not require additional codec.
- *
- * Ref SaffronProperties.defaultCharset
- * SqlUtil.translateCharacterSetName() NlsString constructor()
- */
- System.setProperty("saffron.default.charset", ConversionUtil.NATIVE_UTF16_CHARSET_NAME);
- System.setProperty("saffron.default.nationalcharset", ConversionUtil.NATIVE_UTF16_CHARSET_NAME);
- System.setProperty("saffron.default.collation.name", ConversionUtil.NATIVE_UTF16_CHARSET_NAME + "$en_US");
- }
-
- private final static String SCHEMA_PROJECT = "project";
-
- @Override
- public Schema create(SchemaPlus parentSchema, String schemaName, Map<String, Object> operand) {
- String project = (String) operand.get(SCHEMA_PROJECT);
- Schema newSchema = new OLAPSchema(project, schemaName);
- return newSchema;
- }
-
- public static File createTempOLAPJson(String project, KylinConfig config) {
- project = ProjectInstance.getNormalizedProjectName(project);
-
- List<TableDesc> tables = ProjectManager.getInstance(config).listExposedTables(project);
- // "database" in TableDesc correspond to our schema
- HashMap<String, Integer> schemaCounts = DatabaseDesc.extractDatabaseOccurenceCounts(tables);
-
- String majoritySchemaName = "";
- int majoritySchemaCount = 0;
- for (Map.Entry<String, Integer> e : schemaCounts.entrySet()) {
- if (e.getValue() >= majoritySchemaCount) {
- majoritySchemaCount = e.getValue();
- majoritySchemaName = e.getKey();
- }
- }
-
- try {
- File tmp = File.createTempFile("olap_model_", ".json");
-
- FileWriter out = new FileWriter(tmp);
- out.write("{\n");
- out.write(" \"version\": \"1.0\",\n");
- out.write(" \"defaultSchema\": \"" + majoritySchemaName + "\",\n");
- out.write(" \"schemas\": [\n");
-
- int counter = 0;
- for (String schemaName : schemaCounts.keySet()) {
- out.write(" {\n");
- out.write(" \"type\": \"custom\",\n");
- out.write(" \"name\": \"" + schemaName + "\",\n");
- out.write(" \"factory\": \"com.kylinolap.query.schema.OLAPSchemaFactory\",\n");
- out.write(" \"operand\": {\n");
- out.write(" \"" + SCHEMA_PROJECT + "\": \"" + project + "\"\n");
- out.write(" },\n");
- out.write(" \"functions\": [\n");
- out.write(" {\n");
- out.write(" \"name\": \"QUARTER\",\n");
- out.write(" \"className\": \"com.kylinolap.query.sqlfunc.QuarterFunc\"\n");
- out.write(" }\n");
- out.write(" ]\n");
- out.write(" }\n");
-
- if (++counter != schemaCounts.size()) {
- out.write(",\n");
- }
- }
-
- out.write(" ]\n");
- out.write("}\n");
- out.close();
-
- tmp.deleteOnExit();
- return tmp;
-
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/schema/OLAPTable.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/schema/OLAPTable.java b/query/src/main/java/com/kylinolap/query/schema/OLAPTable.java
deleted file mode 100644
index c56c087..0000000
--- a/query/src/main/java/com/kylinolap/query/schema/OLAPTable.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.kylinolap.query.schema;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-import net.hydromatic.linq4j.Enumerable;
-import net.hydromatic.linq4j.Enumerator;
-import net.hydromatic.linq4j.QueryProvider;
-import net.hydromatic.linq4j.Queryable;
-import net.hydromatic.optiq.DataContext;
-import net.hydromatic.optiq.SchemaPlus;
-import net.hydromatic.optiq.Statistic;
-import net.hydromatic.optiq.Statistics;
-import net.hydromatic.optiq.TranslatableTable;
-import net.hydromatic.optiq.impl.AbstractTableQueryable;
-import net.hydromatic.optiq.impl.java.AbstractQueryableTable;
-
-import org.eigenbase.rel.RelNode;
-import org.eigenbase.relopt.RelOptTable;
-import org.eigenbase.relopt.RelOptTable.ToRelContext;
-import org.eigenbase.reltype.RelDataType;
-import org.eigenbase.reltype.RelDataTypeFactory;
-import org.eigenbase.sql.type.SqlTypeName;
-import org.eigenbase.sql.type.SqlTypeUtil;
-
-import com.kylinolap.cube.project.ProjectManager;
-import com.kylinolap.metadata.model.cube.FunctionDesc;
-import com.kylinolap.metadata.model.cube.MeasureDesc;
-import com.kylinolap.metadata.model.schema.ColumnDesc;
-import com.kylinolap.metadata.model.schema.TableDesc;
-import com.kylinolap.query.enumerator.OLAPQuery;
-import com.kylinolap.query.enumerator.OLAPQuery.EnumeratorTypeEnum;
-import com.kylinolap.query.relnode.OLAPTableScan;
-
-/**
- *
- * @author xjiang
- *
- */
-public class OLAPTable extends AbstractQueryableTable implements TranslatableTable {
-
- private static Map<String, SqlTypeName> SQLTYPE_MAPPING = new HashMap<String, SqlTypeName>();
-
- static {
- SQLTYPE_MAPPING.put("char", SqlTypeName.CHAR);
- SQLTYPE_MAPPING.put("varchar", SqlTypeName.VARCHAR);
- SQLTYPE_MAPPING.put("boolean", SqlTypeName.BOOLEAN);
- SQLTYPE_MAPPING.put("integer", SqlTypeName.INTEGER);
- SQLTYPE_MAPPING.put("tinyint", SqlTypeName.TINYINT);
- SQLTYPE_MAPPING.put("smallint", SqlTypeName.SMALLINT);
- SQLTYPE_MAPPING.put("bigint", SqlTypeName.BIGINT);
- SQLTYPE_MAPPING.put("decimal", SqlTypeName.DECIMAL);
- SQLTYPE_MAPPING.put("numeric", SqlTypeName.DECIMAL);
- SQLTYPE_MAPPING.put("float", SqlTypeName.FLOAT);
- SQLTYPE_MAPPING.put("real", SqlTypeName.REAL);
- SQLTYPE_MAPPING.put("double", SqlTypeName.DOUBLE);
- SQLTYPE_MAPPING.put("date", SqlTypeName.DATE);
- SQLTYPE_MAPPING.put("time", SqlTypeName.TIME);
- SQLTYPE_MAPPING.put("timestamp", SqlTypeName.TIMESTAMP);
- SQLTYPE_MAPPING.put("any", SqlTypeName.ANY);
-
- // try {
- // Class.forName("org.apache.hive.jdbc.HiveDriver");
- // } catch (ClassNotFoundException e) {
- // e.printStackTrace();
- // }
- }
-
- private final OLAPSchema olapSchema;
- private final TableDesc sourceTable;
- private RelDataType rowType;
- private List<ColumnDesc> exposedColumns;
-
- public OLAPTable(OLAPSchema schema, TableDesc tableDesc) {
- super(Object[].class);
- this.olapSchema = schema;
- this.sourceTable = tableDesc;
- this.rowType = null;
- }
-
- public OLAPSchema getSchema() {
- return this.olapSchema;
- }
-
- public TableDesc getSourceTable() {
- return this.sourceTable;
- }
-
- public String getTableName() {
- return this.sourceTable.getName();
- }
-
- public List<ColumnDesc> getExposedColumns() {
- return exposedColumns;
- }
-
- @Override
- public RelDataType getRowType(RelDataTypeFactory typeFactory) {
- if (this.rowType == null) {
- // always build exposedColumns and rowType together
- this.exposedColumns = listSourceColumns();
- this.rowType = deduceRowType(typeFactory);
- }
- return this.rowType;
- }
-
- private RelDataType deduceRowType(RelDataTypeFactory typeFactory) {
- RelDataTypeFactory.FieldInfoBuilder fieldInfo = typeFactory.builder();
- for (ColumnDesc column : exposedColumns) {
- RelDataType sqlType = createSqlType(typeFactory, column);
- sqlType = SqlTypeUtil.addCharsetAndCollation(sqlType, typeFactory);
- fieldInfo.add(column.getName(), sqlType);
- }
- return typeFactory.createStructType(fieldInfo);
- }
-
- private RelDataType createSqlType(RelDataTypeFactory typeFactory, ColumnDesc column) {
- SqlTypeName sqlTypeName = SQLTYPE_MAPPING.get(column.getTypeName());
- if (sqlTypeName == null)
- throw new IllegalArgumentException("Unrecognized column type " + column.getTypeName() + " from " + column);
-
- int precision = column.getTypePrecision();
- int scale = column.getTypeScale();
-
- RelDataType result;
- if (precision >= 0 && scale >= 0)
- result = typeFactory.createSqlType(sqlTypeName, precision, scale);
- else if (precision >= 0)
- result = typeFactory.createSqlType(sqlTypeName, precision);
- else
- result = typeFactory.createSqlType(sqlTypeName);
-
- // due to left join and uncertain data quality, dimension value can be
- // null
- if (column.isNullable()) {
- result = typeFactory.createTypeWithNullability(result, true);
- } else {
- result = typeFactory.createTypeWithNullability(result, false);
- }
-
- return result;
- }
-
- private List<ColumnDesc> listSourceColumns() {
- ProjectManager projectMgr = olapSchema.getProjectManager();
- List<ColumnDesc> exposedColumns = projectMgr.listExposedColumns(olapSchema.getProjectName(), sourceTable.getName());
-
- List<MeasureDesc> countMeasures = projectMgr.listEffectiveRewriteMeasures(olapSchema.getProjectName(), sourceTable.getName());
- HashSet<String> metFields = new HashSet<String>();
- for (MeasureDesc m : countMeasures) {
- FunctionDesc func = m.getFunction();
- String fieldName = func.getRewriteFieldName();
- if (metFields.contains(fieldName) == false) {
- metFields.add(fieldName);
- ColumnDesc fakeCountCol = new ColumnDesc();
- fakeCountCol.setName(fieldName);
- fakeCountCol.setDatatype(func.getSQLType());
- fakeCountCol.setNullable(false);
- fakeCountCol.init(sourceTable);
- exposedColumns.add(fakeCountCol);
- }
- }
-
- return exposedColumns;
- }
-
- @Override
- public RelNode toRel(ToRelContext context, RelOptTable relOptTable) {
- int fieldCount = relOptTable.getRowType().getFieldCount();
- int[] fields = identityList(fieldCount);
- return new OLAPTableScan(context.getCluster(), relOptTable, this, fields);
- }
-
- private int[] identityList(int n) {
- int[] integers = new int[n];
- for (int i = 0; i < n; i++) {
- integers[i] = i;
- }
- return integers;
- }
-
- @Override
- public <T> Queryable<T> asQueryable(QueryProvider queryProvider, SchemaPlus schema, String tableName) {
- return new AbstractTableQueryable<T>(queryProvider, schema, this, tableName) {
- @SuppressWarnings("unchecked")
- public Enumerator<T> enumerator() {
- final OLAPQuery query = new OLAPQuery(EnumeratorTypeEnum.CUBE, 0);
- return (Enumerator<T>) query.enumerator();
- }
- };
- }
-
- @Override
- public Statistic getStatistic() {
- List<BitSet> keys = new ArrayList<BitSet>();
- return Statistics.of(100, keys);
- }
-
- @Override
- public String toString() {
- return "OLAPTable {" + getTableName() + "}";
- }
-
- public Enumerable<Object[]> executeCubeQuery(DataContext optiqContext, int ctxSeq) {
- return new OLAPQuery(optiqContext, EnumeratorTypeEnum.CUBE, ctxSeq);
- }
-
- public Enumerable<Object[]> executeLookupTableQuery(DataContext optiqContext, int ctxSeq) {
- return new OLAPQuery(optiqContext, EnumeratorTypeEnum.LOOKUP_TABLE, ctxSeq);
- }
-
- public Enumerable<Object[]> executeHiveQuery(DataContext optiqContext, int ctxSeq) {
- return new OLAPQuery(optiqContext, EnumeratorTypeEnum.HIVE, ctxSeq);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/sqlfunc/HLLDistinctCountAggFunc.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/sqlfunc/HLLDistinctCountAggFunc.java b/query/src/main/java/com/kylinolap/query/sqlfunc/HLLDistinctCountAggFunc.java
deleted file mode 100644
index e8f952a..0000000
--- a/query/src/main/java/com/kylinolap/query/sqlfunc/HLLDistinctCountAggFunc.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.kylinolap.query.sqlfunc;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.kylinolap.common.hll.HyperLogLogPlusCounter;
-
-/**
- * @author xjiang
- */
-public class HLLDistinctCountAggFunc {
-
- private static final Logger logger = LoggerFactory.getLogger(HLLDistinctCountAggFunc.class);
-
- public static HyperLogLogPlusCounter init() {
- return null;
- }
-
- public static HyperLogLogPlusCounter initAdd(Object v) {
- if (v instanceof Long) { // holistic case
- long l = (Long) v;
- return new FixedValueHLLCMockup(l);
- } else {
- HyperLogLogPlusCounter c = (HyperLogLogPlusCounter) v;
- return new HyperLogLogPlusCounter(c);
- }
- }
-
- public static HyperLogLogPlusCounter add(HyperLogLogPlusCounter counter, Object v) {
- if (v instanceof Long) { // holistic case
- long l = (Long) v;
- if (counter == null) {
- return new FixedValueHLLCMockup(l);
- } else {
- if (!(counter instanceof FixedValueHLLCMockup))
- throw new IllegalStateException("counter is not FixedValueHLLCMockup");
-
- ((FixedValueHLLCMockup) counter).set(l);
- return counter;
- }
- } else {
- HyperLogLogPlusCounter c = (HyperLogLogPlusCounter) v;
- if (counter == null) {
- return new HyperLogLogPlusCounter(c);
- } else {
- counter.merge(c);
- return counter;
- }
- }
- }
-
- public static HyperLogLogPlusCounter merge(HyperLogLogPlusCounter counter0, Object counter1) {
- return add(counter0, counter1);
- }
-
- public static long result(HyperLogLogPlusCounter counter) {
- return counter == null ? 0L : counter.getCountEstimate();
- }
-
- private static class FixedValueHLLCMockup extends HyperLogLogPlusCounter {
-
- private Long value = null;
-
- FixedValueHLLCMockup(long value) {
- this.value = value;
- }
-
- public void set(long value) {
- if (this.value == null) {
- this.value = value;
- } else {
- long oldValue = Math.abs(this.value.longValue());
- long take = Math.max(oldValue, value);
- logger.warn("Error to aggregate holistic count distinct, old value " + oldValue + ", new value " + value + ", taking " + take);
- this.value = -take; // make it obvious that this value is wrong
- }
- }
-
- @Override
- public void clear() {
- this.value = null;
- }
-
- @Override
- protected void add(long hash) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(HyperLogLogPlusCounter another) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long getCountEstimate() {
- return value;
- }
-
- @Override
- public void writeRegisters(ByteBuffer out) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void readRegisters(ByteBuffer in) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + (int) (value ^ (value >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (getClass() != obj.getClass())
- return false;
- FixedValueHLLCMockup other = (FixedValueHLLCMockup) obj;
- if (!value.equals(other.value))
- return false;
- return true;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterBase.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterBase.java b/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterBase.java
deleted file mode 100644
index f0ff187..0000000
--- a/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterBase.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.kylinolap.query.sqlfunc;
-
-import net.hydromatic.optiq.runtime.SqlFunctions;
-import net.hydromatic.optiq.runtime.SqlFunctions.TimeUnitRange;
-
-/**
- * @author xjiang
- *
- */
-public abstract class QuarterBase {
-
- /**
- * According to jvm spec, it return self method before parent.
- * So, we keep Date in parent and int in child
- */
- public static long eval(int date) {
- long month = SqlFunctions.unixDateExtract(TimeUnitRange.MONTH, date);
- return month / 4 + 1;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterFunc.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterFunc.java b/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterFunc.java
deleted file mode 100644
index 1d72a20..0000000
--- a/query/src/main/java/com/kylinolap/query/sqlfunc/QuarterFunc.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2013-2014 eBay Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.kylinolap.query.sqlfunc;
-
-import java.sql.Date;
-
-/**
- * @author xjiang
- *
- */
-public class QuarterFunc extends QuarterBase {
- private QuarterFunc() {
- }
-
- public static long eval(Date date) {
- throw new UnsupportedOperationException();
- }
-}