Return-Path: X-Original-To: apmail-kylin-commits-archive@minotaur.apache.org Delivered-To: apmail-kylin-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4044717AC6 for ; Thu, 12 Feb 2015 05:23:21 +0000 (UTC) Received: (qmail 39358 invoked by uid 500); 12 Feb 2015 05:23:21 -0000 Delivered-To: apmail-kylin-commits-archive@kylin.apache.org Received: (qmail 39274 invoked by uid 500); 12 Feb 2015 05:23:21 -0000 Mailing-List: contact commits-help@kylin.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@kylin.incubator.apache.org Delivered-To: mailing list commits@kylin.incubator.apache.org Received: (qmail 39101 invoked by uid 99); 12 Feb 2015 05:23:21 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 Feb 2015 05:23:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO mail.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 12 Feb 2015 05:22:42 +0000 Received: (qmail 34403 invoked by uid 99); 12 Feb 2015 05:22:22 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 12 Feb 2015 05:22:22 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id F196EE0844; Thu, 12 Feb 2015 05:22:21 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: liyang@apache.org To: commits@kylin.incubator.apache.org Date: Thu, 12 Feb 2015 05:22:29 -0000 Message-Id: In-Reply-To: <3d070d2bf544491da99b49813a6b9a81@git.apache.org> References: <3d070d2bf544491da99b49813a6b9a81@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [09/97] [abbrv] [partial] incubator-kylin git commit: cleanup for migration from github.com X-Virus-Checked: Checked by ClamAV on apache.org http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/enumerator/CubeEnumerator.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/enumerator/CubeEnumerator.java b/query/src/main/java/com/kylinolap/query/enumerator/CubeEnumerator.java deleted file mode 100644 index 5768e60..0000000 --- a/query/src/main/java/com/kylinolap/query/enumerator/CubeEnumerator.java +++ /dev/null @@ -1,223 +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.enumerator; - -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import net.hydromatic.linq4j.Enumerator; -import net.hydromatic.optiq.DataContext; -import net.hydromatic.optiq.jdbc.OptiqConnection; - -import org.eigenbase.reltype.RelDataTypeField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.kylinolap.metadata.model.cube.DimensionDesc; -import com.kylinolap.metadata.model.cube.FunctionDesc; -import com.kylinolap.metadata.model.cube.MeasureDesc; -import com.kylinolap.metadata.model.cube.TblColRef; -import com.kylinolap.query.relnode.OLAPContext; -import com.kylinolap.storage.IStorageEngine; -import com.kylinolap.storage.StorageEngineFactory; -import com.kylinolap.storage.filter.CompareTupleFilter; -import com.kylinolap.storage.filter.TupleFilter; -import com.kylinolap.storage.tuple.ITuple; -import com.kylinolap.storage.tuple.ITupleIterator; - -/** - * @author xjiang - */ -public class CubeEnumerator implements Enumerator { - - private final static Logger logger = LoggerFactory.getLogger(CubeEnumerator.class); - - private final OLAPContext olapContext; - private final DataContext optiqContext; - private final Object[] current; - private ITupleIterator cursor; - private int[] fieldIndexes; - - public CubeEnumerator(OLAPContext olapContext, DataContext optiqContext) { - this.olapContext = olapContext; - this.optiqContext = optiqContext; - this.current = new Object[olapContext.olapRowType.getFieldCount()]; - this.cursor = null; - this.fieldIndexes = null; - } - - @Override - public Object[] current() { - return current; - } - - @Override - public boolean moveNext() { - if (cursor == null) { - cursor = queryStorage(); - } - - if (!cursor.hasNext()) { - return false; - } - - ITuple tuple = cursor.next(); - if (tuple == null) { - return false; - } - convertCurrentRow(tuple); - return true; - } - - @Override - public void reset() { - close(); - cursor = queryStorage(); - } - - @Override - public void close() { - if (cursor != null) { - cursor.close(); - } - } - - private Object[] convertCurrentRow(ITuple tuple) { - - // build field index map - if (this.fieldIndexes == null) { - List fields = tuple.getAllFields(); - int size = fields.size(); - this.fieldIndexes = new int[size]; - for (int i = 0; i < size; i++) { - String field = fields.get(i); - RelDataTypeField relField = olapContext.olapRowType.getField(field, true); - if (relField != null) { - fieldIndexes[i] = relField.getIndex(); - } else { - fieldIndexes[i] = -1; - } - } - } - - // set field value - Object[] values = tuple.getAllValues(); - for (int i = 0, n = values.length; i < n; i++) { - Object value = values[i]; - int index = fieldIndexes[i]; - if (index >= 0) { - current[index] = value; - } - } - - return current; - } - - private ITupleIterator queryStorage() { - logger.debug("query storage..."); - - // set connection properties - setConnectionProperties(); - - // bind dynamic variables - bindVariable(olapContext.filter); - - // build dimension & metrics - Collection dimensions = new HashSet(); - Collection metrics = new HashSet(); - buildDimensionsAndMetrics(dimensions, metrics); - - // query storage engine - IStorageEngine storageEngine = StorageEngineFactory.getStorageEngine(olapContext.cubeInstance); - ITupleIterator iterator = storageEngine.search(dimensions, olapContext.filter, olapContext.groupByColumns, metrics, olapContext.storageContext); - if (logger.isDebugEnabled()) { - logger.debug("return TupleIterator..."); - } - - this.fieldIndexes = null; - return iterator; - } - - private void buildDimensionsAndMetrics(Collection dimensions, Collection metrics) { - - for (FunctionDesc func : olapContext.aggregations) { - if (!func.isAppliedOnDimension()) { - metrics.add(func); - } - } - - if (olapContext.isSimpleQuery()) { - // In order to prevent coprocessor from doing the real aggregating, - // All dimensions are injected - for (DimensionDesc dim : olapContext.cubeDesc.getDimensions()) { - for (TblColRef col : dim.getColumnRefs()) { - dimensions.add(col); - } - } - // select sth from fact table - for (MeasureDesc measure : olapContext.cubeDesc.getMeasures()) { - FunctionDesc func = measure.getFunction(); - if (func.isSum()) { - // the rewritten name for sum(metric) is metric itself - metrics.add(func); - } - } - olapContext.storageContext.markAvoidAggregation(); - } else { - for (TblColRef column : olapContext.allColumns) { - // skip measure columns - if (olapContext.metricsColumns.contains(column)) { - continue; - } - dimensions.add(column); - } - } - } - - private void bindVariable(TupleFilter filter) { - if (filter == null) { - return; - } - - for (TupleFilter childFilter : filter.getChildren()) { - bindVariable(childFilter); - } - - if (filter instanceof CompareTupleFilter && optiqContext != null) { - CompareTupleFilter compFilter = (CompareTupleFilter) filter; - for (Map.Entry entry : compFilter.getVariables().entrySet()) { - String variable = entry.getKey(); - Object value = optiqContext.get(variable); - if (value != null) { - compFilter.bindVariable(variable, value.toString()); - } - - } - } - } - - private void setConnectionProperties() { - OptiqConnection conn = (OptiqConnection) optiqContext.getQueryProvider(); - Properties connProps = conn.getProperties(); - - String propThreshold = connProps.getProperty(OLAPQuery.PROP_SCAN_THRESHOLD); - int threshold = Integer.valueOf(propThreshold); - olapContext.storageContext.setThreshold(threshold); - } -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/enumerator/HiveEnumerator.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/enumerator/HiveEnumerator.java b/query/src/main/java/com/kylinolap/query/enumerator/HiveEnumerator.java deleted file mode 100644 index a5914a8..0000000 --- a/query/src/main/java/com/kylinolap/query/enumerator/HiveEnumerator.java +++ /dev/null @@ -1,130 +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.enumerator; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import net.hydromatic.linq4j.Enumerator; - -import org.eigenbase.reltype.RelDataTypeField; - -import com.kylinolap.query.relnode.OLAPContext; - -/** - * Hive Query Result Enumerator - * - * @author xjiang - * - */ -public class HiveEnumerator implements Enumerator { - - private final OLAPContext olapContext; - private final Object[] current; - private ResultSet rs; - private Connection conn; - - public HiveEnumerator(OLAPContext olapContext) { - this.olapContext = olapContext; - this.current = new Object[olapContext.olapRowType.getFieldCount()]; - } - - @Override - public Object[] current() { - return current; - } - - @Override - public boolean moveNext() { - if (rs == null) { - rs = executeQuery(); - } - return populateResult(); - } - - private ResultSet executeQuery() { - String url = olapContext.olapSchema.getStarSchemaUrl(); - String user = olapContext.olapSchema.getStarSchemaUser(); - String pwd = olapContext.olapSchema.getStarSchemaPassword(); - String sql = olapContext.sql; - Statement stmt = null; - try { - conn = DriverManager.getConnection(url, user, pwd); - stmt = conn.createStatement(); - return stmt.executeQuery(sql); - } catch (SQLException e) { - throw new IllegalStateException(url + " can't execute query " + sql, e); - } finally { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException ex) { - ex.printStackTrace(); - } - } - stmt = null; - if (conn != null) { - try { - conn.close(); - } catch (SQLException ex) { - ex.printStackTrace(); - } - conn = null; - } - } - } - - private boolean populateResult() { - try { - boolean hasNext = rs.next(); - if (hasNext) { - for (RelDataTypeField relField : olapContext.olapRowType.getFieldList()) { - Object value = rs.getObject(relField.getName().toLowerCase()); - current[relField.getIndex()] = value; - } - } - return hasNext; - } catch (SQLException e) { - throw new IllegalStateException("Can't populate result!", e); - } - } - - @Override - public void reset() { - close(); - rs = executeQuery(); - } - - @Override - public void close() { - try { - if (rs != null) { - rs.close(); - rs = null; - } - if (conn != null) { - conn.close(); - conn = null; - } - } catch (SQLException e) { - throw new IllegalStateException("Can't close ResultSet!", e); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/enumerator/LookupTableEnumerator.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/enumerator/LookupTableEnumerator.java b/query/src/main/java/com/kylinolap/query/enumerator/LookupTableEnumerator.java deleted file mode 100644 index e0079ea..0000000 --- a/query/src/main/java/com/kylinolap/query/enumerator/LookupTableEnumerator.java +++ /dev/null @@ -1,96 +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.enumerator; - -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import net.hydromatic.linq4j.Enumerator; - -import com.kylinolap.cube.CubeInstance; -import com.kylinolap.cube.CubeManager; -import com.kylinolap.dict.lookup.LookupStringTable; -import com.kylinolap.metadata.model.cube.DimensionDesc; -import com.kylinolap.metadata.model.schema.ColumnDesc; -import com.kylinolap.query.relnode.OLAPContext; -import com.kylinolap.query.schema.OLAPTable; -import com.kylinolap.storage.tuple.Tuple; - -/** - * @author yangli9 - * - */ -public class LookupTableEnumerator implements Enumerator { - - private final Collection allRows; - private final List colDescs; - private final Object[] current; - private Iterator iterator; - - public LookupTableEnumerator(OLAPContext olapContext) { - - String lookupTableName = olapContext.firstTableScan.getCubeTable(); - DimensionDesc dim = olapContext.cubeDesc.findDimensionByTable(lookupTableName); - if (dim == null) - throw new IllegalStateException("No dimension with derived columns found for lookup table " + lookupTableName + ", cube desc " + olapContext.cubeDesc); - - CubeInstance cube = olapContext.cubeInstance; - CubeManager cubeMgr = CubeManager.getInstance(cube.getConfig()); - LookupStringTable table = cubeMgr.getLookupTable(cube.getLatestReadySegment(), dim); - this.allRows = table.getAllRows(); - - OLAPTable olapTable = (OLAPTable) olapContext.firstTableScan.getOlapTable(); - this.colDescs = olapTable.getExposedColumns(); - this.current = new Object[colDescs.size()]; - - reset(); - } - - @Override - public boolean moveNext() { - boolean hasNext = iterator.hasNext(); - if (hasNext) { - String[] row = iterator.next(); - for (int i = 0, n = colDescs.size(); i < n; i++) { - ColumnDesc colDesc = colDescs.get(i); - int colIdx = colDesc.getZeroBasedIndex(); - if (colIdx >= 0) { - current[i] = Tuple.convertOptiqCellValue(row[colIdx], colDesc.getType().getName()); - } else { - current[i] = null; // fake column - } - } - } - return hasNext; - } - - @Override - public Object[] current() { - return current; - } - - @Override - public void reset() { - this.iterator = allRows.iterator(); - } - - @Override - public void close() { - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/enumerator/OLAPQuery.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/enumerator/OLAPQuery.java b/query/src/main/java/com/kylinolap/query/enumerator/OLAPQuery.java deleted file mode 100644 index 78a5cf1..0000000 --- a/query/src/main/java/com/kylinolap/query/enumerator/OLAPQuery.java +++ /dev/null @@ -1,65 +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.enumerator; - -import net.hydromatic.linq4j.AbstractEnumerable; -import net.hydromatic.linq4j.Enumerable; -import net.hydromatic.linq4j.Enumerator; -import net.hydromatic.optiq.DataContext; - -import com.kylinolap.query.relnode.OLAPContext; - -/** - * - * @author xjiang - * - */ -public class OLAPQuery extends AbstractEnumerable implements Enumerable { - - public static final String PROP_SCAN_THRESHOLD = "scan_threshold"; - - public enum EnumeratorTypeEnum { - CUBE, LOOKUP_TABLE, HIVE - } - - private final DataContext optiqContext; - private final EnumeratorTypeEnum type; - private final int contextId; - - public OLAPQuery(DataContext optiqContext, EnumeratorTypeEnum type, int ctxId) { - this.optiqContext = optiqContext; - this.type = type; - this.contextId = ctxId; - } - - public OLAPQuery(EnumeratorTypeEnum type, int ctxSeq) { - this(null, type, ctxSeq); - } - - public Enumerator enumerator() { - OLAPContext olapContext = OLAPContext.getThreadLocalContextById(contextId); - switch (type) { - case CUBE: - return new CubeEnumerator(olapContext, optiqContext); - case LOOKUP_TABLE: - return new LookupTableEnumerator(olapContext); - case HIVE: - return new HiveEnumerator(olapContext); - default: - throw new IllegalArgumentException("Wrong type " + type + "!"); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPAggregateRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPAggregateRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPAggregateRule.java deleted file mode 100644 index c1c5603..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPAggregateRule.java +++ /dev/null @@ -1,52 +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.optrule; - -import org.eigenbase.rel.AggregateRel; -import org.eigenbase.rel.InvalidRelException; -import org.eigenbase.rel.RelNode; -import org.eigenbase.rel.convert.ConverterRule; -import org.eigenbase.relopt.Convention; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPAggregateRel; -import com.kylinolap.query.relnode.OLAPRel; - -/** - * - * @author xjiang - * - */ -public class OLAPAggregateRule extends ConverterRule { - - public static final ConverterRule INSTANCE = new OLAPAggregateRule(); - - public OLAPAggregateRule() { - super(AggregateRel.class, Convention.NONE, OLAPRel.CONVENTION, "OLAPAggregateRule"); - } - - @Override - public RelNode convert(RelNode rel) { - AggregateRel agg = (AggregateRel) rel; - RelTraitSet traitSet = agg.getTraitSet().replace(OLAPRel.CONVENTION); - try { - return new OLAPAggregateRel(agg.getCluster(), traitSet, convert(agg.getChild(), traitSet), agg.getGroupSet(), agg.getAggCallList()); - } catch (InvalidRelException e) { - throw new IllegalStateException("Can't create OLAPAggregateRel!", e); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPFilterRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPFilterRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPFilterRule.java deleted file mode 100644 index 4c35616..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPFilterRule.java +++ /dev/null @@ -1,49 +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.optrule; - -import org.eigenbase.rel.FilterRel; -import org.eigenbase.relopt.RelOptRule; -import org.eigenbase.relopt.RelOptRuleCall; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPFilterRel; -import com.kylinolap.query.relnode.OLAPRel; - -/** - * - * @author xjiang - * - */ - -public class OLAPFilterRule extends RelOptRule { - - public static final RelOptRule INSTANCE = new OLAPFilterRule(); - - public OLAPFilterRule() { - super(operand(FilterRel.class, any())); - } - - @Override - public void onMatch(RelOptRuleCall call) { - FilterRel filter = call.rel(0); - - RelTraitSet traitSet = filter.getTraitSet().replace(OLAPRel.CONVENTION); - OLAPFilterRel olapFilter = new OLAPFilterRel(filter.getCluster(), traitSet, convert(filter.getChild(), traitSet), filter.getCondition()); - call.transformTo(olapFilter); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPJoinRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPJoinRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPJoinRule.java deleted file mode 100644 index f3ac3df..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPJoinRule.java +++ /dev/null @@ -1,81 +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.optrule; - -import org.eigenbase.rel.InvalidRelException; -import org.eigenbase.rel.JoinInfo; -import org.eigenbase.rel.JoinRel; -import org.eigenbase.rel.JoinRelType; -import org.eigenbase.rel.RelNode; -import org.eigenbase.rel.convert.ConverterRule; -import org.eigenbase.relopt.Convention; -import org.eigenbase.relopt.RelOptCluster; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPFilterRel; -import com.kylinolap.query.relnode.OLAPJoinRel; -import com.kylinolap.query.relnode.OLAPRel; - -/** - * - * @author xjiang - * - */ -public class OLAPJoinRule extends ConverterRule { - - public static final ConverterRule INSTANCE = new OLAPJoinRule(); - - public OLAPJoinRule() { - super(JoinRel.class, Convention.NONE, OLAPRel.CONVENTION, "OLAPJoinRule"); - } - - @Override - public RelNode convert(RelNode rel) { - JoinRel join = (JoinRel) rel; - RelNode left = join.getInput(0); - RelNode right = join.getInput(1); - - RelTraitSet traitSet = join.getTraitSet().replace(OLAPRel.CONVENTION); - left = convert(left, traitSet); - right = convert(right, traitSet); - - final JoinInfo info = JoinInfo.of(left, right, join.getCondition()); - if (!info.isEqui() && join.getJoinType() != JoinRelType.INNER) { - // EnumerableJoinRel only supports equi-join. We can put a filter on top - // if it is an inner join. - return null; - } - - RelOptCluster cluster = join.getCluster(); - RelNode newRel; - try { - newRel = new OLAPJoinRel(cluster, traitSet, left, right, // - info.getEquiCondition(left, right, cluster.getRexBuilder()), // - info.leftKeys, info.rightKeys, join.getJoinType(), join.getVariablesStopped()); - } catch (InvalidRelException e) { - // Semantic error not possible. Must be a bug. Convert to - // internal error. - throw new AssertionError(e); - // LOGGER.fine(e.toString()); - // return null; - } - if (!info.isEqui()) { - newRel = new OLAPFilterRel(cluster, newRel.getTraitSet(), newRel, info.getRemaining(cluster.getRexBuilder())); - } - return newRel; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPLimitRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPLimitRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPLimitRule.java deleted file mode 100644 index af14759..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPLimitRule.java +++ /dev/null @@ -1,56 +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.optrule; - -import org.eigenbase.rel.RelNode; -import org.eigenbase.rel.SortRel; -import org.eigenbase.relopt.RelOptRule; -import org.eigenbase.relopt.RelOptRuleCall; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPLimitRel; -import com.kylinolap.query.relnode.OLAPRel; - -/** - * - * @author xjiang - * - */ -public class OLAPLimitRule extends RelOptRule { - - public static final RelOptRule INSTANCE = new OLAPLimitRule(); - - public OLAPLimitRule() { - super(operand(SortRel.class, any()), "OLAPLimitRule"); - } - - @Override - public void onMatch(RelOptRuleCall call) { - final SortRel sort = call.rel(0); - if (sort.offset == null && sort.fetch == null) { - return; - } - final RelTraitSet traitSet = sort.getTraitSet().replace(OLAPRel.CONVENTION); - RelNode input = sort.getChild(); - if (!sort.getCollation().getFieldCollations().isEmpty()) { - // Create a sort with the same sort key, but no offset or fetch. - input = sort.copy(sort.getTraitSet(), input, sort.getCollation(), null, null); - } - RelNode x = convert(input, input.getTraitSet().replace(OLAPRel.CONVENTION)); - call.transformTo(new OLAPLimitRel(sort.getCluster(), traitSet, x, sort.offset, sort.fetch)); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPProjectRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPProjectRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPProjectRule.java deleted file mode 100644 index e174366..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPProjectRule.java +++ /dev/null @@ -1,48 +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.optrule; - -import org.eigenbase.rel.ProjectRel; -import org.eigenbase.relopt.RelOptRule; -import org.eigenbase.relopt.RelOptRuleCall; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPProjectRel; -import com.kylinolap.query.relnode.OLAPRel; - -/** - * - * @author xjiang - * - */ -public class OLAPProjectRule extends RelOptRule { - - public static final RelOptRule INSTANCE = new OLAPProjectRule(); - - public OLAPProjectRule() { - super(operand(ProjectRel.class, any())); - } - - @Override - public void onMatch(RelOptRuleCall call) { - ProjectRel project = call.rel(0); - - RelTraitSet traitSet = project.getTraitSet().replace(OLAPRel.CONVENTION); - OLAPProjectRel olapProj = new OLAPProjectRel(project.getCluster(), traitSet, convert(project.getChild(), project.getTraitSet().replace(OLAPRel.CONVENTION)), project.getProjects(), project.getRowType(), project.getFlags()); - call.transformTo(olapProj); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPSortRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPSortRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPSortRule.java deleted file mode 100644 index cccfe47..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPSortRule.java +++ /dev/null @@ -1,51 +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.optrule; - -import org.eigenbase.rel.RelNode; -import org.eigenbase.rel.SortRel; -import org.eigenbase.rel.convert.ConverterRule; -import org.eigenbase.relopt.Convention; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPRel; -import com.kylinolap.query.relnode.OLAPSortRel; - -/** - * @author xjiang - * - */ -public class OLAPSortRule extends ConverterRule { - - public static final OLAPSortRule INSTANCE = new OLAPSortRule(); - - public OLAPSortRule() { - super(SortRel.class, Convention.NONE, OLAPRel.CONVENTION, "OLAPSortRule"); - } - - @Override - public RelNode convert(RelNode rel) { - final SortRel sort = (SortRel) rel; - if (sort.offset != null || sort.fetch != null) { - return null; - } - final RelTraitSet traitSet = sort.getTraitSet().replace(OLAPRel.CONVENTION); - final RelNode input = sort.getChild(); - return new OLAPSortRel(rel.getCluster(), traitSet, convert(input, input.getTraitSet().replace(OLAPRel.CONVENTION)), sort.getCollation(), sort.offset, sort.fetch); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/optrule/OLAPToEnumerableConverterRule.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/optrule/OLAPToEnumerableConverterRule.java b/query/src/main/java/com/kylinolap/query/optrule/OLAPToEnumerableConverterRule.java deleted file mode 100644 index ec11756..0000000 --- a/query/src/main/java/com/kylinolap/query/optrule/OLAPToEnumerableConverterRule.java +++ /dev/null @@ -1,46 +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.optrule; - -import net.hydromatic.optiq.rules.java.EnumerableConvention; - -import org.eigenbase.rel.RelNode; -import org.eigenbase.rel.convert.ConverterRule; -import org.eigenbase.relopt.RelTraitSet; - -import com.kylinolap.query.relnode.OLAPRel; -import com.kylinolap.query.relnode.OLAPToEnumerableConverter; - -/** - * - * @author xjiang - * - */ -public class OLAPToEnumerableConverterRule extends ConverterRule { - - public static final ConverterRule INSTANCE = new OLAPToEnumerableConverterRule(); - - public OLAPToEnumerableConverterRule() { - super(RelNode.class, OLAPRel.CONVENTION, EnumerableConvention.INSTANCE, "OLAPToEnumerableConverterRule"); - } - - @Override - public RelNode convert(RelNode rel) { - RelTraitSet newTraitSet = rel.getTraitSet().replace(getOutConvention()); - return new OLAPToEnumerableConverter(rel.getCluster(), newTraitSet, rel); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/ColumnRowType.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/relnode/ColumnRowType.java b/query/src/main/java/com/kylinolap/query/relnode/ColumnRowType.java deleted file mode 100644 index a0dd3cf..0000000 --- a/query/src/main/java/com/kylinolap/query/relnode/ColumnRowType.java +++ /dev/null @@ -1,84 +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.Collections; -import java.util.List; -import java.util.Set; - -import com.kylinolap.metadata.model.cube.TblColRef; - -/** - * - * @author xjiang - * - */ -public class ColumnRowType { - - private List columns; - // for calculated column, like (CASE LSTG_FORMAT_NAME WHEN 'Auction' THEN - // '111' ELSE '222' END) - // source columns are the contributing physical columns, here the - // LSTG_FORMAT_NAME - private List> sourceColumns; - - public ColumnRowType(List columns) { - this(columns, null); - } - - public ColumnRowType(List columns, List> sourceColumns) { - this.columns = columns; - this.sourceColumns = sourceColumns; - } - - public TblColRef getColumnByIndex(int index) { - return columns.get(index); - } - - public int getIndexByName(String columnName) { - for (int i = 0; i < columns.size(); i++) { - if (columns.get(i).getName().equals(columnName)) { - return i; - } - } - return -1; - } - - public Set getSourceColumnsByIndex(int i) { - Set result = null; - if (sourceColumns != null) { - result = sourceColumns.get(i); - } - if (result == null || result.isEmpty()) { - result = Collections.singleton(getColumnByIndex(i)); - } - return result; - } - - public List getAllColumns() { - return columns; - } - - public int size() { - return columns.size(); - } - - @Override - public String toString() { - return "ColumnRowType [" + columns + "]"; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPAggregateRel.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPAggregateRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPAggregateRel.java deleted file mode 100644 index 33a403d..0000000 --- a/query/src/main/java/com/kylinolap/query/relnode/OLAPAggregateRel.java +++ /dev/null @@ -1,370 +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.BitSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.hydromatic.optiq.AggregateFunction; -import net.hydromatic.optiq.FunctionParameter; -import net.hydromatic.optiq.impl.AggregateFunctionImpl; -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.EnumerableAggregateRel; - -import org.eigenbase.rel.AggregateCall; -import org.eigenbase.rel.AggregateRelBase; -import org.eigenbase.rel.Aggregation; -import org.eigenbase.rel.InvalidRelException; -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; -import org.eigenbase.reltype.RelDataTypeField; -import org.eigenbase.sql.SqlAggFunction; -import org.eigenbase.sql.SqlIdentifier; -import org.eigenbase.sql.fun.SqlSumEmptyIsZeroAggFunction; -import org.eigenbase.sql.parser.SqlParserPos; -import org.eigenbase.sql.type.InferTypes; -import org.eigenbase.sql.type.OperandTypes; -import org.eigenbase.sql.type.ReturnTypes; -import org.eigenbase.sql.type.SqlTypeFamily; -import org.eigenbase.sql.validate.SqlUserDefinedAggFunction; -import org.eigenbase.util.Util; - -import com.google.common.base.Preconditions; -import com.kylinolap.metadata.model.cube.FunctionDesc; -import com.kylinolap.metadata.model.cube.ParameterDesc; -import com.kylinolap.metadata.model.cube.TblColRef; -import com.kylinolap.metadata.model.schema.ColumnDesc; -import com.kylinolap.metadata.model.schema.TableDesc; -import com.kylinolap.query.sqlfunc.HLLDistinctCountAggFunc; - -/** - * @author xjiang - */ -public class OLAPAggregateRel extends AggregateRelBase implements OLAPRel, EnumerableRel { - - private final static Map AGGR_FUNC_MAP = new HashMap(); - - static { - AGGR_FUNC_MAP.put("SUM", "SUM"); - AGGR_FUNC_MAP.put("$SUM0", "SUM"); - AGGR_FUNC_MAP.put("COUNT", "COUNT"); - AGGR_FUNC_MAP.put("COUNT_DISTINCT", "COUNT_DISTINCT"); - AGGR_FUNC_MAP.put("HLL_COUNT", "COUNT_DISTINCT"); - AGGR_FUNC_MAP.put("MAX", "MAX"); - AGGR_FUNC_MAP.put("MIN", "MIN"); - } - - private static String getFuncName(AggregateCall aggCall) { - String aggName = aggCall.getAggregation().getName(); - if (aggCall.isDistinct()) { - aggName = aggName + "_DISTINCT"; - } - String funcName = AGGR_FUNC_MAP.get(aggName); - if (funcName == null) { - throw new IllegalStateException("Don't suppoprt aggregation " + aggName); - } - return funcName; - } - - private OLAPContext context; - private ColumnRowType columnRowType; - private boolean afterAggregate; - private List rewriteAggCalls; - private List groups; - private List aggregations; - - public OLAPAggregateRel(RelOptCluster cluster, RelTraitSet traits, RelNode child, BitSet groupSet, List aggCalls) throws InvalidRelException { - super(cluster, traits, child, groupSet, aggCalls); - Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION); - this.afterAggregate = false; - this.rewriteAggCalls = aggCalls; - this.rowType = getRowType(); - } - - @Override - public AggregateRelBase copy(RelTraitSet traitSet, RelNode input, BitSet groupSet, List aggCalls) { - try { - return new OLAPAggregateRel(getCluster(), traitSet, input, groupSet, aggCalls); - } catch (InvalidRelException e) { - throw new IllegalStateException("Can't create OLAPAggregateRel!", e); - } - } - - @Override - public RelOptCost computeSelfCost(RelOptPlanner planner) { - double factor = .5; - for (AggregateCall aggCall : aggCalls) { - if ("$SUM0".equals(aggCall.getAggregation().getName())) { - factor = .2; - } - } - return super.computeSelfCost(planner).multiplyBy(factor); - } - - @Override - public void implementOLAP(OLAPImplementor implementor) { - - implementor.visitChild(getChild(), this); - - this.context = implementor.getContext(); - this.columnRowType = buildColumnRowType(); - this.afterAggregate = this.context.afterAggregate; - - // only translate the first aggregation - if (!this.afterAggregate) { - translateGroupBy(); - fillbackOptimizedColumn(); - translateAggregation(); - this.context.afterAggregate = true; - } else { - for (AggregateCall aggCall : aggCalls) { - // check if supported by kylin - if (aggCall.isDistinct()) { - throw new IllegalStateException("Distinct count is only allowed in innermost sub-query."); - } - } - } - } - - private ColumnRowType buildColumnRowType() { - buildGroups(); - buildAggregations(); - - ColumnRowType inputColumnRowType = ((OLAPRel) getChild()).getColumnRowType(); - List columns = new ArrayList(this.rowType.getFieldCount()); - columns.addAll(this.groups); - - for (int i = 0; i < this.aggregations.size(); i++) { - FunctionDesc aggFunc = this.aggregations.get(i); - TblColRef aggCol = null; - if (aggFunc.needRewrite()) { - aggCol = buildRewriteColumn(aggFunc); - } else { - AggregateCall aggCall = this.rewriteAggCalls.get(i); - if (!aggCall.getArgList().isEmpty()) { - int index = aggCall.getArgList().get(0); - aggCol = inputColumnRowType.getColumnByIndex(index); - } - } - columns.add(aggCol); - } - return new ColumnRowType(columns); - } - - private TblColRef buildRewriteColumn(FunctionDesc aggFunc) { - TblColRef colRef = null; - if (aggFunc.needRewrite()) { - ColumnDesc column = new ColumnDesc(); - column.setName(aggFunc.getRewriteFieldName()); - TableDesc table = this.context.firstTableScan.getOlapTable().getSourceTable(); - column.setTable(table); - colRef = new TblColRef(column); - } - return colRef; - } - - private void buildGroups() { - ColumnRowType inputColumnRowType = ((OLAPRel) getChild()).getColumnRowType(); - this.groups = new ArrayList(); - for (int i = getGroupSet().nextSetBit(0); i >= 0; i = getGroupSet().nextSetBit(i + 1)) { - Set columns = inputColumnRowType.getSourceColumnsByIndex(i); - this.groups.addAll(columns); - } - } - - private void buildAggregations() { - ColumnRowType inputColumnRowType = ((OLAPRel) getChild()).getColumnRowType(); - this.aggregations = new ArrayList(); - for (AggregateCall aggCall : this.rewriteAggCalls) { - ParameterDesc parameter = null; - if (!aggCall.getArgList().isEmpty()) { - int index = aggCall.getArgList().get(0); - TblColRef column = inputColumnRowType.getColumnByIndex(index); - if (!column.isInnerColumn()) { - parameter = new ParameterDesc(); - parameter.setValue(column.getName()); - parameter.setType("column"); - } - } - FunctionDesc aggFunc = new FunctionDesc(); - String funcName = getFuncName(aggCall); - aggFunc.setExpression(funcName); - aggFunc.setParameter(parameter); - this.aggregations.add(aggFunc); - } - } - - private void translateGroupBy() { - context.groupByColumns.addAll(this.groups); - } - - private void translateAggregation() { - ColumnRowType inputColumnRowType = ((OLAPRel) getChild()).getColumnRowType(); - for (int i = 0; i < this.aggregations.size(); i++) { - FunctionDesc aggFunc = this.aggregations.get(i); - context.aggregations.add(aggFunc); - if (aggFunc.needRewrite()) { - String rewriteFieldName = aggFunc.getRewriteFieldName(); - context.rewriteFields.put(rewriteFieldName, null); - - TblColRef column = buildRewriteColumn(aggFunc); - this.context.metricsColumns.add(column); - } - AggregateCall aggCall = this.rewriteAggCalls.get(i); - if (!aggCall.getArgList().isEmpty()) { - int index = aggCall.getArgList().get(0); - TblColRef column = inputColumnRowType.getColumnByIndex(index); - if (!column.isInnerColumn()) { - this.context.metricsColumns.add(column); - } - } - } - } - - private void fillbackOptimizedColumn() { - // some aggcall will be optimized out in sub-query (e.g. tableau - // generated sql) - // we need to fill them back - RelDataType inputAggRow = getChild().getRowType(); - RelDataType outputAggRow = getRowType(); - if (inputAggRow.getFieldCount() != outputAggRow.getFieldCount()) { - for (RelDataTypeField inputField : inputAggRow.getFieldList()) { - String inputFieldName = inputField.getName(); - if (outputAggRow.getField(inputFieldName, true) == null) { - TblColRef column = this.columnRowType.getColumnByIndex(inputField.getIndex()); - this.context.metricsColumns.add(column); - } - } - } - } - - @Override - public void implementRewrite(RewriteImplementor implementor) { - implementor.visitChild(this, getChild()); - - // only rewrite the first aggregation - if (!this.afterAggregate && RewriteImplementor.needRewrite(this.context)) { - // rewrite the aggCalls - this.rewriteAggCalls = new ArrayList(aggCalls.size()); - for (int i = 0; i < this.aggCalls.size(); i++) { - AggregateCall aggCall = this.aggCalls.get(i); - FunctionDesc cubeFunc = this.context.aggregations.get(i); - if (cubeFunc.needRewrite()) { - aggCall = rewriteAggregateCall(aggCall, cubeFunc); - } - this.rewriteAggCalls.add(aggCall); - } - } - - // rebuild rowType & columnRowType - this.rowType = this.deriveRowType(); - this.columnRowType = this.buildColumnRowType(); - - } - - private AggregateCall rewriteAggregateCall(AggregateCall aggCall, FunctionDesc func) { - - // rebuild parameters - List newArgList = new ArrayList(1); - String fieldName = func.getRewriteFieldName(); - RelDataTypeField field = getChild().getRowType().getField(fieldName, true); - newArgList.add(field.getIndex()); - - // rebuild function - RelDataType fieldType = aggCall.getType(); - Aggregation newAgg = aggCall.getAggregation(); - if (func.isCountDistinct()) { - newAgg = createHyperLogLogAggFunction(fieldType); - } else if (func.isCount()) { - newAgg = new SqlSumEmptyIsZeroAggFunction(fieldType); - } - - // rebuild aggregate call - AggregateCall newAggCall = new AggregateCall(newAgg, false, newArgList, fieldType, newAgg.getName()); - - // To make sure specified type matches the inferReturnType, or otherwise - // there will be assertion failure in optiq - // The problem is BIGINT != BIGINT NOT NULL - // Details see https://github.scm.corp.ebay.com/Kylin/Kylin/issues/323 - SqlAggFunction aggFunction = (SqlAggFunction) newAggCall.getAggregation(); - AggCallBinding callBinding = newAggCall.createBinding(this); - RelDataType inferReturnType = aggFunction.inferReturnType(callBinding); - - return new AggregateCall(newAgg, false, newArgList, inferReturnType, newAgg.getName()); - } - - private Aggregation createHyperLogLogAggFunction(RelDataType returnType) { - RelDataTypeFactory typeFactory = getCluster().getTypeFactory(); - SqlIdentifier sqlIdentifier = new SqlIdentifier("HLL_COUNT", new SqlParserPos(1, 1)); - AggregateFunction aggFunction = AggregateFunctionImpl.create(HLLDistinctCountAggFunc.class); - List argTypes = new ArrayList(); - List typeFamilies = new ArrayList(); - for (FunctionParameter o : aggFunction.getParameters()) { - final RelDataType type = o.getType(typeFactory); - argTypes.add(type); - typeFamilies.add(Util.first(type.getSqlTypeName().getFamily(), SqlTypeFamily.ANY)); - } - return new SqlUserDefinedAggFunction(sqlIdentifier, ReturnTypes.explicit(returnType), InferTypes.explicit(argTypes), OperandTypes.family(typeFamilies), aggFunction); - } - - @Override - public Result implement(EnumerableRelImplementor implementor, Prefer pref) { - - EnumerableAggregateRel enumAggRel; - try { - enumAggRel = new EnumerableAggregateRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getChild(), this.groupSet, rewriteAggCalls); - } catch (InvalidRelException e) { - throw new IllegalStateException("Can't create EnumerableAggregateRel!", e); - } - - return enumAggRel.implement(implementor, pref); - } - - @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/OLAPContext.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPContext.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPContext.java deleted file mode 100644 index 7de1817..0000000 --- a/query/src/main/java/com/kylinolap/query/relnode/OLAPContext.java +++ /dev/null @@ -1,122 +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.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.eigenbase.reltype.RelDataType; - -import com.kylinolap.cube.CubeInstance; -import com.kylinolap.metadata.model.cube.CubeDesc; -import com.kylinolap.metadata.model.cube.FunctionDesc; -import com.kylinolap.metadata.model.cube.JoinDesc; -import com.kylinolap.metadata.model.cube.TblColRef; -import com.kylinolap.query.schema.OLAPSchema; -import com.kylinolap.storage.StorageContext; -import com.kylinolap.storage.filter.TupleFilter; - -/** - * @author xjiang - * - */ -public class OLAPContext { - - public static final String PRM_ACCEPT_PARTIAL_RESULT = "AcceptPartialResult"; - - private static final ThreadLocal> _localPrarameters = new ThreadLocal>(); - - private static final ThreadLocal> _localContexts = new ThreadLocal>(); - - public static void setParameters(Map parameters) { - _localPrarameters.set(parameters); - } - - public static void clearParameter() { - _localPrarameters.remove(); - } - - public static void registerContext(OLAPContext ctx) { - if (_localContexts.get() == null) { - Map contextMap = new HashMap(); - _localContexts.set(contextMap); - } - _localContexts.get().put(ctx.id, ctx); - } - - public static Collection getThreadLocalContexts() { - Map map = _localContexts.get(); - return map == null ? null : map.values(); - } - - public static OLAPContext getThreadLocalContextById(int id) { - return _localContexts.get().get(id); - } - - public static void clearThreadLocalContexts() { - _localContexts.remove(); - } - - public OLAPContext(int seq) { - this.id = seq; - this.storageContext = new StorageContext(); - Map parameters = _localPrarameters.get(); - if (parameters != null) { - String acceptPartialResult = parameters.get(PRM_ACCEPT_PARTIAL_RESULT); - if (acceptPartialResult != null) { - this.storageContext.setAcceptPartialResult(Boolean.parseBoolean(acceptPartialResult)); - } - } - } - - public final int id; - public final StorageContext storageContext; - - // query info - public OLAPSchema olapSchema = null; - public OLAPTableScan firstTableScan = null; // to be fact table scan except - // "select * from lookupTable" - public RelDataType olapRowType = null; - public boolean afterAggregate = false; - public boolean afterJoin = false; - public boolean hasJoin = false; - - // cube metadata - public CubeInstance cubeInstance; - public CubeDesc cubeDesc; - public Collection allColumns = new HashSet(); - public Collection metricsColumns = new HashSet(); - public Collection groupByColumns = new ArrayList(); - public List aggregations = new ArrayList(); - public List joins = new LinkedList(); - public TupleFilter filter; - - // rewrite info - public Map rewriteFields = new HashMap(); - - // hive query - public String sql = ""; - - public boolean isSimpleQuery() { - return (joins.size() == 0) && (groupByColumns.size() == 0) && (aggregations.size() == 0); - } -} http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/a4fd4268/query/src/main/java/com/kylinolap/query/relnode/OLAPFilterRel.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPFilterRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPFilterRel.java deleted file mode 100644 index 923a540..0000000 --- a/query/src/main/java/com/kylinolap/query/relnode/OLAPFilterRel.java +++ /dev/null @@ -1,326 +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.Calendar; -import java.util.GregorianCalendar; -import java.util.LinkedList; -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.EnumerableCalcRel; -import net.hydromatic.optiq.runtime.SqlFunctions; - -import org.eigenbase.rel.FilterRelBase; -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.rex.RexBuilder; -import org.eigenbase.rex.RexCall; -import org.eigenbase.rex.RexDynamicParam; -import org.eigenbase.rex.RexInputRef; -import org.eigenbase.rex.RexLiteral; -import org.eigenbase.rex.RexLocalRef; -import org.eigenbase.rex.RexNode; -import org.eigenbase.rex.RexProgram; -import org.eigenbase.rex.RexProgramBuilder; -import org.eigenbase.rex.RexVisitorImpl; -import org.eigenbase.sql.SqlKind; -import org.eigenbase.sql.SqlOperator; -import org.eigenbase.util.NlsString; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.kylinolap.metadata.model.cube.TblColRef; -import com.kylinolap.storage.filter.CaseTupleFilter; -import com.kylinolap.storage.filter.ColumnTupleFilter; -import com.kylinolap.storage.filter.CompareTupleFilter; -import com.kylinolap.storage.filter.ConstantTupleFilter; -import com.kylinolap.storage.filter.DynamicTupleFilter; -import com.kylinolap.storage.filter.ExtractTupleFilter; -import com.kylinolap.storage.filter.LogicalTupleFilter; -import com.kylinolap.storage.filter.TupleFilter; -import com.kylinolap.storage.filter.TupleFilter.FilterOperatorEnum; - -/** - * @author xjiang - */ -public class OLAPFilterRel extends FilterRelBase implements OLAPRel, EnumerableRel { - - private static class TupleFilterVisitor extends RexVisitorImpl { - - private final ColumnRowType inputRowType; - private final OLAPContext context; - - public TupleFilterVisitor(ColumnRowType inputRowType, OLAPContext context) { - super(true); - this.inputRowType = inputRowType; - this.context = context; - } - - @Override - public TupleFilter visitCall(RexCall call) { - TupleFilter filter = null; - SqlOperator op = call.getOperator(); - switch (op.getKind()) { - case AND: - filter = new LogicalTupleFilter(FilterOperatorEnum.AND); - break; - case OR: - filter = new LogicalTupleFilter(FilterOperatorEnum.OR); - break; - case NOT: - filter = new LogicalTupleFilter(FilterOperatorEnum.NOT); - break; - case EQUALS: - filter = new CompareTupleFilter(FilterOperatorEnum.EQ); - break; - case GREATER_THAN: - filter = new CompareTupleFilter(FilterOperatorEnum.GT); - break; - case LESS_THAN: - filter = new CompareTupleFilter(FilterOperatorEnum.LT); - break; - case GREATER_THAN_OR_EQUAL: - filter = new CompareTupleFilter(FilterOperatorEnum.GTE); - break; - case LESS_THAN_OR_EQUAL: - filter = new CompareTupleFilter(FilterOperatorEnum.LTE); - break; - case NOT_EQUALS: - filter = new CompareTupleFilter(FilterOperatorEnum.NEQ); - break; - case IS_NULL: - filter = new CompareTupleFilter(FilterOperatorEnum.ISNULL); - break; - case IS_NOT_NULL: - filter = new CompareTupleFilter(FilterOperatorEnum.ISNOTNULL); - break; - case CAST: - case REINTERPRET: - // NOTE: use child directly - break; - case CASE: - filter = new CaseTupleFilter(); - break; - case OTHER: - if (op.getName().equalsIgnoreCase("extract_date")) { - filter = new ExtractTupleFilter(FilterOperatorEnum.EXTRACT); - } else { - throw new UnsupportedOperationException(op.getName()); - } - break; - default: - throw new UnsupportedOperationException(op.getName()); - } - - for (RexNode operand : call.operands) { - TupleFilter childFilter = operand.accept(this); - if (filter == null) { - filter = childFilter; - } else { - filter.addChild(childFilter); - } - } - - if (op.getKind() == SqlKind.OR) { - CompareTupleFilter inFilter = mergeToInClause(filter); - if (inFilter != null) { - filter = inFilter; - } - } - return filter; - } - - private CompareTupleFilter mergeToInClause(TupleFilter filter) { - List children = filter.getChildren(); - TblColRef inColumn = null; - List inValues = new LinkedList(); - for (TupleFilter child : children) { - if (child.getOperator() == FilterOperatorEnum.EQ) { - CompareTupleFilter compFilter = (CompareTupleFilter) child; - TblColRef column = compFilter.getColumn(); - if (inColumn == null) { - inColumn = column; - } - - if (column == null || !column.equals(inColumn)) { - return null; - } - inValues.addAll(compFilter.getValues()); - } else { - return null; - } - } - - children.clear(); - - CompareTupleFilter inFilter = new CompareTupleFilter(FilterOperatorEnum.IN); - inFilter.addChild(new ColumnTupleFilter(inColumn)); - inFilter.addChild(new ConstantTupleFilter(inValues)); - return inFilter; - } - - @Override - public TupleFilter visitLocalRef(RexLocalRef localRef) { - throw new UnsupportedOperationException("local ref:" + localRef); - } - - @Override - public TupleFilter visitInputRef(RexInputRef inputRef) { - TblColRef column = inputRowType.getColumnByIndex(inputRef.getIndex()); - context.allColumns.add(column); - ColumnTupleFilter filter = new ColumnTupleFilter(column); - return filter; - } - - private String normToTwoDigits(int i) { - if (i < 10) - return "0" + i; - else - return "" + i; - } - - @Override - public TupleFilter visitLiteral(RexLiteral literal) { - String strValue = null; - Object literalValue = literal.getValue(); - if (literalValue instanceof NlsString) { - strValue = ((NlsString) literalValue).getValue(); - } else if (literalValue instanceof GregorianCalendar) { - GregorianCalendar g = (GregorianCalendar) literalValue; - strValue = "" + g.get(Calendar.YEAR) + "-" + normToTwoDigits(g.get(Calendar.MONTH) + 1) + "-" + normToTwoDigits(g.get(Calendar.DAY_OF_MONTH)); - } else if (literalValue instanceof SqlFunctions.TimeUnitRange) { - // Extract(x from y) in where clause - strValue = ((SqlFunctions.TimeUnitRange) literalValue).name(); - } else if (literalValue == null) { - strValue = null; - } else { - strValue = literalValue.toString(); - } - TupleFilter filter = new ConstantTupleFilter(strValue); - return filter; - } - - @Override - public TupleFilter visitDynamicParam(RexDynamicParam dynamicParam) { - String name = dynamicParam.getName(); - TupleFilter filter = new DynamicTupleFilter(name); - return filter; - } - } - - private ColumnRowType columnRowType; - private OLAPContext context; - - public OLAPFilterRel(RelOptCluster cluster, RelTraitSet traits, RelNode child, RexNode condition) { - super(cluster, traits, child, condition); - Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION); - Preconditions.checkArgument(getConvention() == child.getConvention()); - this.rowType = getRowType(); - } - - @Override - public RelOptCost computeSelfCost(RelOptPlanner planner) { - return super.computeSelfCost(planner).multiplyBy(.05); - } - - @Override - public FilterRelBase copy(RelTraitSet traitSet, RelNode input, RexNode condition) { - return new OLAPFilterRel(getCluster(), traitSet, input, condition); - } - - @Override - public void implementOLAP(OLAPImplementor implementor) { - implementor.visitChild(getChild(), this); - - this.columnRowType = buildColumnRowType(); - this.context = implementor.getContext(); - - // only translate where clause and don't translate having clause - if (!context.afterAggregate) { - translateFilter(context); - } - } - - private ColumnRowType buildColumnRowType() { - OLAPRel olapChild = (OLAPRel) getChild(); - ColumnRowType inputColumnRowType = olapChild.getColumnRowType(); - return inputColumnRowType; - } - - private void translateFilter(OLAPContext context) { - if (this.condition == null) { - return; - } - - TupleFilterVisitor visitor = new TupleFilterVisitor(this.columnRowType, context); - context.filter = this.condition.accept(visitor); - } - - @Override - public Result implement(EnumerableRelImplementor implementor, Prefer pref) { - // keep it for having clause - RexBuilder rexBuilder = getCluster().getRexBuilder(); - RelDataType inputRowType = getChild().getRowType(); - RexProgramBuilder programBuilder = new RexProgramBuilder(inputRowType, rexBuilder); - programBuilder.addIdentity(); - programBuilder.addCondition(this.condition); - RexProgram program = programBuilder.getProgram(); - - EnumerableCalcRel enumCalcRel = new EnumerableCalcRel(getCluster(), getCluster().traitSetOf(EnumerableConvention.INSTANCE), getChild(), this.rowType, program, ImmutableList. of()); - - return enumCalcRel.implement(implementor, pref); - } - - @Override - public void implementRewrite(RewriteImplementor implementor) { - implementor.visitChild(this, getChild()); - - this.rowType = this.deriveRowType(); - this.columnRowType = buildColumnRowType(); - } - - @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/OLAPJoinRel.java ---------------------------------------------------------------------- diff --git a/query/src/main/java/com/kylinolap/query/relnode/OLAPJoinRel.java b/query/src/main/java/com/kylinolap/query/relnode/OLAPJoinRel.java deleted file mode 100644 index 83e7993..0000000 --- a/query/src/main/java/com/kylinolap/query/relnode/OLAPJoinRel.java +++ /dev/null @@ -1,294 +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.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.hydromatic.linq4j.expressions.Blocks; -import net.hydromatic.linq4j.expressions.Expressions; -import net.hydromatic.optiq.rules.java.EnumerableRelImplementor; -import net.hydromatic.optiq.rules.java.JavaRules.EnumerableJoinRel; -import net.hydromatic.optiq.rules.java.PhysType; -import net.hydromatic.optiq.rules.java.PhysTypeImpl; - -import org.eigenbase.rel.InvalidRelException; -import org.eigenbase.rel.JoinInfo; -import org.eigenbase.rel.JoinRelType; -import org.eigenbase.rel.RelNode; -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.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.RexNode; -import org.eigenbase.sql.SqlKind; -import org.eigenbase.util.ImmutableIntList; - -import com.google.common.base.Preconditions; -import com.kylinolap.metadata.model.cube.JoinDesc; -import com.kylinolap.metadata.model.cube.TblColRef; -import com.kylinolap.query.schema.OLAPTable; - -/** - * @author xjiang - */ -public class OLAPJoinRel extends EnumerableJoinRel implements OLAPRel { - - private final static String[] COLUMN_ARRAY_MARKER = new String[0]; - - private OLAPContext context; - private ColumnRowType columnRowType; - private boolean isTopJoin; - private boolean hasSubQuery; - - public OLAPJoinRel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, // - RexNode condition, ImmutableIntList leftKeys, ImmutableIntList rightKeys, // - JoinRelType joinType, Set variablesStopped) throws InvalidRelException { - super(cluster, traits, left, right, condition, leftKeys, rightKeys, joinType, variablesStopped); - Preconditions.checkArgument(getConvention() == OLAPRel.CONVENTION); - this.rowType = getRowType(); - this.isTopJoin = false; - } - - @Override - public EnumerableJoinRel copy(RelTraitSet traitSet, RexNode conditionExpr, RelNode left, RelNode right, // - JoinRelType joinType, boolean semiJoinDone) { - - final JoinInfo joinInfo = JoinInfo.of(left, right, condition); - assert joinInfo.isEqui(); - try { - return new OLAPJoinRel(getCluster(), traitSet, left, right, condition, joinInfo.leftKeys, joinInfo.rightKeys, joinType, variablesStopped); - } catch (InvalidRelException e) { - // Semantic error not possible. Must be a bug. Convert to - // internal error. - throw new AssertionError(e); - } - } - - @Override - public RelOptCost computeSelfCost(RelOptPlanner planner) { - return super.computeSelfCost(planner).multiplyBy(.05); - } - - @Override - public double getRows() { - return super.getRows() * 0.1; - } - - @Override - public void implementOLAP(OLAPImplementor implementor) { - - // create context for root join - if (!(implementor.getParentNode() instanceof OLAPJoinRel)) { - implementor.allocateContext(); - } - this.context = implementor.getContext(); - this.isTopJoin = !this.context.hasJoin; - this.context.hasJoin = true; - - // as we keep the first table as fact table, we need to visit from left - // to right - implementor.visitChild(this.left, this); - if (this.context != implementor.getContext() || ((OLAPRel) this.left).hasSubQuery()) { - this.hasSubQuery = true; - implementor.freeContext(); - } - implementor.visitChild(this.right, this); - if (this.context != implementor.getContext() || ((OLAPRel) this.right).hasSubQuery()) { - this.hasSubQuery = true; - implementor.freeContext(); - } - - this.columnRowType = buildColumnRowType(); - if (isTopJoin) { - this.context.afterJoin = true; - } - - if (!this.hasSubQuery) { - this.context.allColumns.clear(); - this.context.olapRowType = getRowType(); - buildAliasMap(); - - // build JoinDesc - RexCall condition = (RexCall) this.getCondition(); - JoinDesc join = buildJoin(condition); - - JoinRelType joinRelType = this.getJoinType(); - String joinType = joinRelType == JoinRelType.INNER ? "INNER" : joinRelType == JoinRelType.LEFT ? "LEFT" : null; - join.setType(joinType); - - this.context.joins.add(join); - } - } - - private ColumnRowType buildColumnRowType() { - List columns = new ArrayList(); - - OLAPRel olapLeft = (OLAPRel) this.left; - ColumnRowType leftColumnRowType = olapLeft.getColumnRowType(); - columns.addAll(leftColumnRowType.getAllColumns()); - - OLAPRel olapRight = (OLAPRel) this.right; - ColumnRowType rightColumnRowType = olapRight.getColumnRowType(); - columns.addAll(rightColumnRowType.getAllColumns()); - - if (columns.size() != this.rowType.getFieldCount()) { - throw new IllegalStateException("RowType=" + this.rowType.getFieldCount() + ", ColumnRowType=" + columns.size()); - } - return new ColumnRowType(columns); - } - - private JoinDesc buildJoin(RexCall condition) { - Map joinColumns = new HashMap(); - translateJoinColumn(condition, joinColumns); - - List pks = new ArrayList(); - List pkCols = new ArrayList(); - List fks = new ArrayList(); - List fkCols = new ArrayList(); - String factTable = context.firstTableScan.getCubeTable(); - for (Map.Entry columnPair : joinColumns.entrySet()) { - TblColRef fromCol = columnPair.getKey(); - TblColRef toCol = columnPair.getValue(); - if (factTable.equalsIgnoreCase(fromCol.getTable())) { - fks.add(fromCol.getName()); - fkCols.add(fromCol); - pks.add(toCol.getName()); - pkCols.add(toCol); - } else { - fks.add(toCol.getName()); - fkCols.add(toCol); - pks.add(fromCol.getName()); - pkCols.add(fromCol); - } - } - - JoinDesc join = new JoinDesc(); - join.setForeignKey(fks.toArray(COLUMN_ARRAY_MARKER)); - join.setForeignKeyColumns(fkCols.toArray(new TblColRef[fkCols.size()])); - join.setPrimaryKey(pks.toArray(COLUMN_ARRAY_MARKER)); - join.setPrimaryKeyColumns(pkCols.toArray(new TblColRef[pkCols.size()])); - return join; - } - - private void translateJoinColumn(RexCall condition, Map joinColumns) { - SqlKind kind = condition.getOperator().getKind(); - if (kind == SqlKind.AND) { - for (RexNode operand : condition.getOperands()) { - RexCall subCond = (RexCall) operand; - translateJoinColumn(subCond, joinColumns); - } - } else if (kind == SqlKind.EQUALS) { - List operands = condition.getOperands(); - RexInputRef op0 = (RexInputRef) operands.get(0); - TblColRef col0 = columnRowType.getColumnByIndex(op0.getIndex()); - RexInputRef op1 = (RexInputRef) operands.get(1); - TblColRef col1 = columnRowType.getColumnByIndex(op1.getIndex()); - joinColumns.put(col0, col1); - } - } - - private void buildAliasMap() { - int size = this.rowType.getFieldList().size(); - - for (int i = 0; i < size; i++) { - RelDataTypeField field = this.rowType.getFieldList().get(i); - TblColRef column = this.columnRowType.getColumnByIndex(i); - context.storageContext.addAlias(column, field.getName()); - } - } - - @Override - public Result implement(EnumerableRelImplementor implementor, Prefer pref) { - Result result = null; - if (this.hasSubQuery) { - result = super.implement(implementor, pref); - } else { - PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.preferArray()); - - RelOptTable factTable = context.firstTableScan.getTable(); - result = implementor.result(physType, Blocks.toBlock(Expressions.call(factTable.getExpression(OLAPTable.class), "executeCubeQuery", implementor.getRootExpression(), Expressions.constant(context.id)))); - } - - return result; - } - - @Override - public ColumnRowType getColumnRowType() { - return columnRowType; - } - - @Override - public void implementRewrite(RewriteImplementor implementor) { - implementor.visitChild(this, this.left); - implementor.visitChild(this, this.right); - - this.rowType = this.deriveRowType(); - - if (this.isTopJoin && RewriteImplementor.needRewrite(this.context)) { - // find missed rewrite fields - int paramIndex = this.rowType.getFieldList().size(); - List newFieldList = new LinkedList(); - for (Map.Entry rewriteField : this.context.rewriteFields.entrySet()) { - String fieldName = rewriteField.getKey(); - if (this.rowType.getField(fieldName, true) == null) { - RelDataType fieldType = rewriteField.getValue(); - RelDataTypeField newField = new RelDataTypeFieldImpl(fieldName, paramIndex++, fieldType); - newFieldList.add(newField); - } - } - - // rebuild row type - FieldInfoBuilder fieldInfo = getCluster().getTypeFactory().builder(); - fieldInfo.addAll(this.rowType.getFieldList()); - fieldInfo.addAll(newFieldList); - this.rowType = getCluster().getTypeFactory().createStructType(fieldInfo); - this.context.olapRowType = this.rowType; - - // rebuild columns - this.columnRowType = this.buildColumnRowType(); - } - } - - @Override - public OLAPContext getContext() { - return context; - } - - @Override - public boolean hasSubQuery() { - return this.hasSubQuery; - } - - @Override - public RelTraitSet replaceTraitSet(RelTrait trait) { - RelTraitSet oldTraitSet = this.traitSet; - this.traitSet = this.traitSet.replace(trait); - return oldTraitSet; - } -}