http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/OrFilterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/OrFilterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/OrFilterExecuterImpl.java new file mode 100644 index 0000000..38938e6 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/OrFilterExecuterImpl.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; + +import org.carbondata.scan.expression.exception.FilterUnsupportedException; +import org.carbondata.scan.processor.BlocksChunkHolder; + +public class OrFilterExecuterImpl implements FilterExecuter { + + private FilterExecuter leftExecuter; + private FilterExecuter rightExecuter; + + public OrFilterExecuterImpl(FilterExecuter leftExecuter, FilterExecuter rightExecuter) { + this.leftExecuter = leftExecuter; + this.rightExecuter = rightExecuter; + } + + @Override public BitSet applyFilter(BlocksChunkHolder blockChunkHolder) + throws FilterUnsupportedException { + BitSet leftFilters = leftExecuter.applyFilter(blockChunkHolder); + BitSet rightFilters = rightExecuter.applyFilter(blockChunkHolder); + leftFilters.or(rightFilters); + + return leftFilters; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet leftFilters = leftExecuter.isScanRequired(blockMaxValue, blockMinValue); + BitSet rightFilters = rightExecuter.isScanRequired(blockMaxValue, blockMinValue); + leftFilters.or(rightFilters); + return leftFilters; + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RestructureFilterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RestructureFilterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RestructureFilterExecuterImpl.java new file mode 100644 index 0000000..70a6ff0 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RestructureFilterExecuterImpl.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; + +import org.carbondata.core.keygenerator.KeyGenerator; +import org.carbondata.scan.filter.FilterUtil; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.processor.BlocksChunkHolder; + + +public class RestructureFilterExecuterImpl implements FilterExecuter { + + DimColumnExecuterFilterInfo dimColumnExecuterInfo; + + public RestructureFilterExecuterImpl(DimColumnResolvedFilterInfo dimColumnResolvedFilterInfo, + KeyGenerator blockKeyGenerator) { + dimColumnExecuterInfo = new DimColumnExecuterFilterInfo(); + FilterUtil + .prepareKeysFromSurrogates(dimColumnResolvedFilterInfo.getFilterValues(), blockKeyGenerator, + dimColumnResolvedFilterInfo.getDimension(), dimColumnExecuterInfo); + } + + @Override public BitSet applyFilter(BlocksChunkHolder blocksChunkHolder) { + BitSet bitSet = new BitSet(blocksChunkHolder.getDataBlock().nodeSize()); + byte[][] filterValues = dimColumnExecuterInfo.getFilterKeys(); + if (null != filterValues && filterValues.length > 0) { + bitSet.set(0, blocksChunkHolder.getDataBlock().nodeSize()); + } + return bitSet; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + bitSet.set(0); + return bitSet; + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelFilterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelFilterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelFilterExecuterImpl.java new file mode 100644 index 0000000..0463978 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelFilterExecuterImpl.java @@ -0,0 +1,331 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import org.carbondata.common.logging.LogService; +import org.carbondata.common.logging.LogServiceFactory; +import org.carbondata.core.cache.dictionary.Dictionary; +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.chunk.impl.VariableLengthDimensionDataChunk; +import org.carbondata.core.carbon.metadata.datatype.DataType; +import org.carbondata.core.carbon.metadata.encoder.Encoding; +import org.carbondata.core.constants.CarbonCommonConstants; +import org.carbondata.core.keygenerator.directdictionary.DirectDictionaryGenerator; +import org.carbondata.core.keygenerator.directdictionary.DirectDictionaryKeyGeneratorFactory; +import org.carbondata.core.util.CarbonUtil; +import org.carbondata.scan.executor.exception.QueryExecutionException; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.expression.exception.FilterUnsupportedException; +import org.carbondata.scan.filter.FilterUtil; +import org.carbondata.scan.filter.GenericQueryType; +import org.carbondata.scan.filter.intf.RowImpl; +import org.carbondata.scan.filter.intf.RowIntf; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; +import org.carbondata.scan.processor.BlocksChunkHolder; +import org.carbondata.scan.util.DataTypeUtil; + +public class RowLevelFilterExecuterImpl implements FilterExecuter { + + private static final LogService LOGGER = + LogServiceFactory.getLogService(RowLevelFilterExecuterImpl.class.getName()); + protected List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList; + protected List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList; + protected Expression exp; + protected AbsoluteTableIdentifier tableIdentifier; + + public RowLevelFilterExecuterImpl(List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList, + List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList, Expression exp, + AbsoluteTableIdentifier tableIdentifier) { + this.dimColEvaluatorInfoList = dimColEvaluatorInfoList; + if (null == msrColEvalutorInfoList) { + this.msrColEvalutorInfoList = new ArrayList<MeasureColumnResolvedFilterInfo>(20); + } else { + this.msrColEvalutorInfoList = msrColEvalutorInfoList; + } + this.exp = exp; + this.tableIdentifier = tableIdentifier; + } + + @Override public BitSet applyFilter(BlocksChunkHolder blockChunkHolder) + throws FilterUnsupportedException { + for (DimColumnResolvedFilterInfo dimColumnEvaluatorInfo : dimColEvaluatorInfoList) { + if (dimColumnEvaluatorInfo.getDimension().getDataType() != DataType.ARRAY + && dimColumnEvaluatorInfo.getDimension().getDataType() != DataType.STRUCT) { + if (null == blockChunkHolder.getDimensionDataChunk()[dimColumnEvaluatorInfo + .getColumnIndex()]) { + blockChunkHolder.getDimensionDataChunk()[dimColumnEvaluatorInfo.getColumnIndex()] = + blockChunkHolder.getDataBlock().getDimensionChunk(blockChunkHolder.getFileReader(), + dimColumnEvaluatorInfo.getColumnIndex()); + } + } else { + GenericQueryType complexType = dimColumnEvaluatorInfo.getComplexTypesWithBlockStartIndex() + .get(dimColumnEvaluatorInfo.getColumnIndex()); + complexType.fillRequiredBlockData(blockChunkHolder); + } + } + + // CHECKSTYLE:OFF Approval No:Approval-V1R2C10_001 + if (null != msrColEvalutorInfoList) { + for (MeasureColumnResolvedFilterInfo msrColumnEvalutorInfo : msrColEvalutorInfoList) { + if (msrColumnEvalutorInfo.isMeasureExistsInCurrentSlice() && null == blockChunkHolder + .getMeasureDataChunk()[msrColumnEvalutorInfo.getColumnIndex()]) { + blockChunkHolder.getMeasureDataChunk()[msrColumnEvalutorInfo.getColumnIndex()] = + blockChunkHolder.getDataBlock().getMeasureChunk(blockChunkHolder.getFileReader(), + msrColumnEvalutorInfo.getColumnIndex()); + } + } + } + // CHECKSTYLE:ON + + int numberOfRows = blockChunkHolder.getDataBlock().nodeSize(); + BitSet set = new BitSet(numberOfRows); + RowIntf row = new RowImpl(); + + // CHECKSTYLE:OFF Approval No:Approval-V1R2C10_007 + for (int index = 0; index < numberOfRows; index++) { + try { + createRow(blockChunkHolder, row, index); + } catch (QueryExecutionException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + try { + Boolean rslt = exp.evaluate(row).getBoolean(); + if (null != rslt && rslt) { + set.set(index); + } + } catch (FilterUnsupportedException e) { + throw new FilterUnsupportedException(e.getMessage()); + } + } + // CHECKSTYLE:ON + + return set; + } + + /** + * Method will read the members of particular dimension block and create + * a row instance for further processing of the filters + * + * @param blockChunkHolder + * @param row + * @param index + * @throws QueryExecutionException + */ + private void createRow(BlocksChunkHolder blockChunkHolder, RowIntf row, int index) + throws QueryExecutionException { + Object[] record = new Object[dimColEvaluatorInfoList.size() + msrColEvalutorInfoList.size()]; + String memberString = null; + for (DimColumnResolvedFilterInfo dimColumnEvaluatorInfo : dimColEvaluatorInfoList) { + if (dimColumnEvaluatorInfo.getDimension().getDataType() != DataType.ARRAY + && dimColumnEvaluatorInfo.getDimension().getDataType() != DataType.STRUCT) { + if (!dimColumnEvaluatorInfo.isDimensionExistsInCurrentSilce()) { + record[dimColumnEvaluatorInfo.getRowIndex()] = dimColumnEvaluatorInfo.getDefaultValue(); + } + if (!dimColumnEvaluatorInfo.getDimension().hasEncoding(Encoding.DICTIONARY) + && blockChunkHolder.getDimensionDataChunk()[dimColumnEvaluatorInfo + .getColumnIndex()] instanceof VariableLengthDimensionDataChunk) { + + VariableLengthDimensionDataChunk dimensionColumnDataChunk = + (VariableLengthDimensionDataChunk) blockChunkHolder + .getDimensionDataChunk()[dimColumnEvaluatorInfo.getColumnIndex()]; + if (null != dimensionColumnDataChunk.getCompleteDataChunk()) { + memberString = + readMemberBasedOnNoDictionaryVal(dimColumnEvaluatorInfo, dimensionColumnDataChunk, + index); + if (null != memberString) { + if (memberString.equals(CarbonCommonConstants.MEMBER_DEFAULT_VAL)) { + memberString = null; + } + } + record[dimColumnEvaluatorInfo.getRowIndex()] = DataTypeUtil + .getDataBasedOnDataType(memberString, + dimColumnEvaluatorInfo.getDimension().getDataType()); + } else { + continue; + } + } else { + int dictionaryValue = + readSurrogatesFromColumnBlock(blockChunkHolder, index, dimColumnEvaluatorInfo); + Dictionary forwardDictionary = null; + if (dimColumnEvaluatorInfo.getDimension().hasEncoding(Encoding.DICTIONARY) + && !dimColumnEvaluatorInfo.getDimension().hasEncoding(Encoding.DIRECT_DICTIONARY)) { + memberString = + getFilterActualValueFromDictionaryValue(dimColumnEvaluatorInfo, dictionaryValue, + forwardDictionary); + record[dimColumnEvaluatorInfo.getRowIndex()] = DataTypeUtil + .getDataBasedOnDataType(memberString, + dimColumnEvaluatorInfo.getDimension().getDataType()); + } else if (dimColumnEvaluatorInfo.getDimension() + .hasEncoding(Encoding.DIRECT_DICTIONARY)) { + + Object member = getFilterActualValueFromDirectDictionaryValue(dimColumnEvaluatorInfo, + dictionaryValue); + record[dimColumnEvaluatorInfo.getRowIndex()] = member; + } + } + } + } + + DataType msrType; + + for (MeasureColumnResolvedFilterInfo msrColumnEvalutorInfo : msrColEvalutorInfoList) { + switch (msrColumnEvalutorInfo.getType()) { + case LONG: + msrType = DataType.LONG; + break; + case DECIMAL: + msrType = DataType.DECIMAL; + break; + default: + msrType = DataType.DOUBLE; + } + // if measure doesnt exist then set the default value. + if (!msrColumnEvalutorInfo.isMeasureExistsInCurrentSlice()) { + record[msrColumnEvalutorInfo.getRowIndex()] = msrColumnEvalutorInfo.getDefaultValue(); + } else { + Object msrValue; + switch (msrType) { + case LONG: + msrValue = + blockChunkHolder.getMeasureDataChunk()[msrColumnEvalutorInfo.getColumnIndex()] + .getMeasureDataHolder().getReadableLongValueByIndex(index); + break; + case DECIMAL: + msrValue = + blockChunkHolder.getMeasureDataChunk()[msrColumnEvalutorInfo.getColumnIndex()] + .getMeasureDataHolder().getReadableBigDecimalValueByIndex(index); + break; + default: + msrValue = + blockChunkHolder.getMeasureDataChunk()[msrColumnEvalutorInfo.getColumnIndex()] + .getMeasureDataHolder().getReadableDoubleValueByIndex(index); + } + record[msrColumnEvalutorInfo.getRowIndex()] = msrValue; + + } + } + row.setValues(record); + } + + /** + * method will read the actual data from the direct dictionary generator + * by passing direct dictionary value. + * + * @param dimColumnEvaluatorInfo + * @param dictionaryValue + * @return + */ + private Object getFilterActualValueFromDirectDictionaryValue( + DimColumnResolvedFilterInfo dimColumnEvaluatorInfo, int dictionaryValue) { + Object memberString = null; + DirectDictionaryGenerator directDictionaryGenerator = DirectDictionaryKeyGeneratorFactory + .getDirectDictionaryGenerator(dimColumnEvaluatorInfo.getDimension().getDataType()); + if (null != directDictionaryGenerator) { + memberString = directDictionaryGenerator.getValueFromSurrogate(dictionaryValue); + } + return memberString; + } + + /** + * Read the actual filter member by passing the dictionary value from + * the forward dictionary cache which which holds column wise cache + * + * @param dimColumnEvaluatorInfo + * @param dictionaryValue + * @param forwardDictionary + * @return + * @throws QueryExecutionException + */ + private String getFilterActualValueFromDictionaryValue( + DimColumnResolvedFilterInfo dimColumnEvaluatorInfo, int dictionaryValue, + Dictionary forwardDictionary) throws QueryExecutionException { + String memberString; + try { + forwardDictionary = FilterUtil + .getForwardDictionaryCache(tableIdentifier, dimColumnEvaluatorInfo.getDimension()); + } catch (QueryExecutionException e) { + throw new QueryExecutionException(e); + } + + memberString = forwardDictionary.getDictionaryValueForKey(dictionaryValue); + if (null != memberString) { + if (memberString.equals(CarbonCommonConstants.MEMBER_DEFAULT_VAL)) { + memberString = null; + } + } + return memberString; + } + + /** + * read the filter member dictionary data from the block corresponding to + * applied filter column + * + * @param blockChunkHolder + * @param index + * @param dimColumnEvaluatorInfo + * @return + */ + private int readSurrogatesFromColumnBlock(BlocksChunkHolder blockChunkHolder, int index, + DimColumnResolvedFilterInfo dimColumnEvaluatorInfo) { + byte[] rawData = + blockChunkHolder.getDimensionDataChunk()[dimColumnEvaluatorInfo.getColumnIndex()] + .getChunkData(index); + ByteBuffer byteBuffer = ByteBuffer.allocate(CarbonCommonConstants.INT_SIZE_IN_BYTE); + int dictionaryValue = CarbonUtil.getSurrogateKey(rawData, byteBuffer); + return dictionaryValue; + } + + /** + * Reading the blocks for no dictionary data, in no dictionary case + * directly the filter data will read, no need to scan the dictionary + * or read the dictionary value. + * + * @param dimColumnEvaluatorInfo + * @param dimensionColumnDataChunk + * @param index + * @return + */ + private String readMemberBasedOnNoDictionaryVal( + DimColumnResolvedFilterInfo dimColumnEvaluatorInfo, + VariableLengthDimensionDataChunk dimensionColumnDataChunk, int index) { + byte[] noDictionaryVals; + if (null != dimensionColumnDataChunk.getAttributes().getInvertedIndexesReverse()) { + // Getting the data for direct surrogates. + noDictionaryVals = dimensionColumnDataChunk.getCompleteDataChunk() + .get(dimensionColumnDataChunk.getAttributes().getInvertedIndexesReverse()[index]); + } else { + noDictionaryVals = dimensionColumnDataChunk.getCompleteDataChunk().get(index); + } + return new String(noDictionaryVals, Charset.forName(CarbonCommonConstants.DEFAULT_CHARSET)); + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + bitSet.set(0); + return bitSet; + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtThanFiterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtThanFiterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtThanFiterExecuterImpl.java new file mode 100644 index 0000000..2681ccc --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtThanFiterExecuterImpl.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; +import java.util.List; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.util.ByteUtil; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; + +public class RowLevelRangeGrtThanFiterExecuterImpl extends RowLevelFilterExecuterImpl { + private byte[][] filterRangeValues; + + public RowLevelRangeGrtThanFiterExecuterImpl( + List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList, + List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList, Expression exp, + AbsoluteTableIdentifier tableIdentifier, byte[][] filterRangeValues) { + super(dimColEvaluatorInfoList, msrColEvalutorInfoList, exp, tableIdentifier); + this.filterRangeValues = filterRangeValues; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + byte[][] filterValues = this.filterRangeValues; + int columnIndex = this.dimColEvaluatorInfoList.get(0).getColumnIndex(); + boolean isScanRequired = false; + for (int k = 0; k < filterValues.length; k++) { + // filter value should be in range of max and min value i.e + // max>filtervalue>min + // so filter-max should be negative + int maxCompare = + ByteUtil.UnsafeComparer.INSTANCE.compareTo(filterValues[k], blockMaxValue[columnIndex]); + + // if any filter value is in range than this block needs to be + // scanned means always less than block max range. + if (maxCompare < 0) { + isScanRequired = true; + break; + } + } + if (isScanRequired) { + bitSet.set(0); + } + return bitSet; + + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtrThanEquaToFilterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtrThanEquaToFilterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtrThanEquaToFilterExecuterImpl.java new file mode 100644 index 0000000..ef11b4a --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeGrtrThanEquaToFilterExecuterImpl.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; +import java.util.List; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.util.ByteUtil; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; + +public class RowLevelRangeGrtrThanEquaToFilterExecuterImpl extends RowLevelFilterExecuterImpl { + + private byte[][] filterRangeValues; + + public RowLevelRangeGrtrThanEquaToFilterExecuterImpl( + List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList, + List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList, Expression exp, + AbsoluteTableIdentifier tableIdentifier, byte[][] filterRangeValues) { + super(dimColEvaluatorInfoList, msrColEvalutorInfoList, exp, tableIdentifier); + this.filterRangeValues = filterRangeValues; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + byte[][] filterValues = this.filterRangeValues; + int columnIndex = this.dimColEvaluatorInfoList.get(0).getColumnIndex(); + boolean isScanRequired = false; + for (int k = 0; k < filterValues.length; k++) { + // filter value should be in range of max and min value i.e + // max>filtervalue>min + // so filter-max should be negative + int maxCompare = + ByteUtil.UnsafeComparer.INSTANCE.compareTo(filterValues[k], blockMaxValue[columnIndex]); + // if any filter value is in range than this block needs to be + // scanned less than equal to max range. + if (maxCompare <= 0) { + isScanRequired = true; + break; + } + } + if (isScanRequired) { + bitSet.set(0); + } + return bitSet; + + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanEqualFilterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanEqualFilterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanEqualFilterExecuterImpl.java new file mode 100644 index 0000000..afc1ccb --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanEqualFilterExecuterImpl.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; +import java.util.List; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.util.ByteUtil; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; + +public class RowLevelRangeLessThanEqualFilterExecuterImpl extends RowLevelFilterExecuterImpl { + private byte[][] filterRangeValues; + + public RowLevelRangeLessThanEqualFilterExecuterImpl( + List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList, + List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList, Expression exp, + AbsoluteTableIdentifier tableIdentifier, byte[][] filterRangeValues) { + super(dimColEvaluatorInfoList, msrColEvalutorInfoList, exp, tableIdentifier); + this.filterRangeValues = filterRangeValues; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + byte[][] filterValues = this.filterRangeValues; + int columnIndex = this.dimColEvaluatorInfoList.get(0).getColumnIndex(); + boolean isScanRequired = false; + for (int k = 0; k < filterValues.length; k++) { + // and filter-min should be positive + int minCompare = + ByteUtil.UnsafeComparer.INSTANCE.compareTo(filterValues[k], blockMinValue[columnIndex]); + + // if any filter applied is not in range of min and max of block + // then since its a less than equal to fiter validate whether the block + // min range is less than equal to applied filter member + if (minCompare >= 0) { + isScanRequired = true; + break; + } + } + if (isScanRequired) { + bitSet.set(0); + } + return bitSet; + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanFiterExecuterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanFiterExecuterImpl.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanFiterExecuterImpl.java new file mode 100644 index 0000000..d608cc6 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeLessThanFiterExecuterImpl.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import java.util.BitSet; +import java.util.List; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.util.ByteUtil; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; + +public class RowLevelRangeLessThanFiterExecuterImpl extends RowLevelFilterExecuterImpl { + private byte[][] filterRangeValues; + + public RowLevelRangeLessThanFiterExecuterImpl( + List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList, + List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList, Expression exp, + AbsoluteTableIdentifier tableIdentifier, byte[][] filterRangeValues) { + super(dimColEvaluatorInfoList, msrColEvalutorInfoList, exp, tableIdentifier); + this.filterRangeValues = filterRangeValues; + } + + @Override public BitSet isScanRequired(byte[][] blockMaxValue, byte[][] blockMinValue) { + BitSet bitSet = new BitSet(1); + byte[][] filterValues = this.filterRangeValues; + int columnIndex = this.dimColEvaluatorInfoList.get(0).getColumnIndex(); + boolean isScanRequired = false; + for (int k = 0; k < filterValues.length; k++) { + // and filter-min should be positive + int minCompare = + ByteUtil.UnsafeComparer.INSTANCE.compareTo(filterValues[k], blockMinValue[columnIndex]); + + // if any filter applied is not in range of min and max of block + // then since its a less than fiter validate whether the block + // min range is less than applied filter member + if (minCompare > 0) { + isScanRequired = true; + break; + } + } + if (isScanRequired) { + bitSet.set(0); + } + return bitSet; + + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeTypeExecuterFacory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeTypeExecuterFacory.java b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeTypeExecuterFacory.java new file mode 100644 index 0000000..db2fa2d --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/executer/RowLevelRangeTypeExecuterFacory.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.executer; + +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.FilterResolverIntf; +import org.carbondata.scan.filter.resolver.RowLevelRangeFilterResolverImpl; + +public class RowLevelRangeTypeExecuterFacory { + + private RowLevelRangeTypeExecuterFacory() { + + } + + /** + * The method returns the Row Level Range fiter type instance based on + * filter tree resolver type. + * + * @param filterExpressionResolverTree + * @param dataType DataType + * @return the generator instance + */ + public static RowLevelFilterExecuterImpl getRowLevelRangeTypeExecuter( + FilterExecuterType filterExecuterType, FilterResolverIntf filterExpressionResolverTree) { + switch (filterExecuterType) { + + case ROWLEVEL_LESSTHAN: + return new RowLevelRangeLessThanFiterExecuterImpl( + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getDimColEvaluatorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getMsrColEvalutorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getFilterExpression(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getTableIdentifier(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getFilterRangeValues()); + case ROWLEVEL_LESSTHAN_EQUALTO: + return new RowLevelRangeLessThanEqualFilterExecuterImpl( + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getDimColEvaluatorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getMsrColEvalutorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getFilterExpression(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getTableIdentifier(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getFilterRangeValues()); + case ROWLEVEL_GREATERTHAN_EQUALTO: + return new RowLevelRangeGrtrThanEquaToFilterExecuterImpl( + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getDimColEvaluatorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getMsrColEvalutorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getFilterExpression(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getTableIdentifier(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getFilterRangeValues()); + case ROWLEVEL_GREATERTHAN: + return new RowLevelRangeGrtThanFiterExecuterImpl( + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getDimColEvaluatorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getMsrColEvalutorInfoList(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getFilterExpression(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree).getTableIdentifier(), + ((RowLevelRangeFilterResolverImpl) filterExpressionResolverTree) + .getFilterRangeValues()); + default: + // Scenario wont come logic must break + return null; + + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/intf/ExpressionType.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/intf/ExpressionType.java b/core/src/main/java/org/carbondata/scan/filter/intf/ExpressionType.java new file mode 100644 index 0000000..2459b5a --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/intf/ExpressionType.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.intf; + +public enum ExpressionType { + + AND, + OR, + NOT, + EQUALS, + NOT_EQUALS, + LESSTHAN, + LESSTHAN_EQUALTO, + GREATERTHAN, + GREATERTHAN_EQUALTO, + ADD, + SUBSTRACT, + DIVIDE, + MULTIPLY, + IN, + LIST, + NOT_IN, + UNKNOWN, + LITERAL, + RANGE + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/intf/FilterExecuterType.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/intf/FilterExecuterType.java b/core/src/main/java/org/carbondata/scan/filter/intf/FilterExecuterType.java new file mode 100644 index 0000000..2de575e --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/intf/FilterExecuterType.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.intf; + +import java.io.Serializable; + +public enum FilterExecuterType implements Serializable { + + INCLUDE, EXCLUDE, OR, AND, RESTRUCTURE, ROWLEVEL, RANGE, ROWLEVEL_GREATERTHAN, + ROWLEVEL_GREATERTHAN_EQUALTO, ROWLEVEL_LESSTHAN_EQUALTO, ROWLEVEL_LESSTHAN + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/intf/RowImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/intf/RowImpl.java b/core/src/main/java/org/carbondata/scan/filter/intf/RowImpl.java new file mode 100644 index 0000000..04e1a3d --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/intf/RowImpl.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.intf; + +public class RowImpl implements RowIntf { + private Object[] row; + + public RowImpl() { + row = new Object[0]; + } + + @Override public Object getVal(int index) { + return row[index]; + } + + @Override public Object[] getValues() { + return row; + } + + @Override public void setValues(final Object[] row) { + this.row = row; + } + + @Override public int size() { + return this.row.length; + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/intf/RowIntf.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/intf/RowIntf.java b/core/src/main/java/org/carbondata/scan/filter/intf/RowIntf.java new file mode 100644 index 0000000..ddfa1eb --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/intf/RowIntf.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.intf; + +public interface RowIntf { + Object getVal(int index); + + Object[] getValues(); + + void setValues(Object[] setValues); + + int size(); + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/AndFilterResolverImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/AndFilterResolverImpl.java b/core/src/main/java/org/carbondata/scan/filter/resolver/AndFilterResolverImpl.java new file mode 100644 index 0000000..37685c8 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/AndFilterResolverImpl.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.resolver; + +import java.util.SortedMap; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.block.SegmentProperties; +import org.carbondata.scan.filter.intf.ExpressionType; + +public class AndFilterResolverImpl extends LogicalFilterResolverImpl { + + /** + * + */ + private static final long serialVersionUID = -761688076874662001L; + + public AndFilterResolverImpl(FilterResolverIntf leftEvalutor, FilterResolverIntf rightEvalutor, + ExpressionType filterExpressionType) { + super(leftEvalutor, rightEvalutor, filterExpressionType); + } + + @Override public void getStartKey(SegmentProperties segmentProperties, long[] startKeys, + SortedMap<Integer, byte[]> noDicStartKeys) { + leftEvalutor.getStartKey(segmentProperties, startKeys, noDicStartKeys); + rightEvalutor.getStartKey(segmentProperties, startKeys, noDicStartKeys); + } + + @Override public void getEndKey(SegmentProperties segmentProperties, + AbsoluteTableIdentifier tableIdentifier, long[] endKeys, + SortedMap<Integer, byte[]> noDicEndKeys) { + leftEvalutor.getEndKey(segmentProperties, tableIdentifier, endKeys, noDicEndKeys); + rightEvalutor.getEndKey(segmentProperties, tableIdentifier, endKeys, noDicEndKeys); + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/ConditionalFilterResolverImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/ConditionalFilterResolverImpl.java b/core/src/main/java/org/carbondata/scan/filter/resolver/ConditionalFilterResolverImpl.java new file mode 100644 index 0000000..1fb595a --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/ConditionalFilterResolverImpl.java @@ -0,0 +1,239 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.resolver; + +import java.util.List; +import java.util.SortedMap; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.block.SegmentProperties; +import org.carbondata.core.carbon.metadata.encoder.Encoding; +import org.carbondata.scan.executor.exception.QueryExecutionException; +import org.carbondata.scan.expression.ColumnExpression; +import org.carbondata.scan.expression.DataType; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.expression.conditional.BinaryConditionalExpression; +import org.carbondata.scan.expression.conditional.ConditionalExpression; +import org.carbondata.scan.expression.exception.FilterUnsupportedException; +import org.carbondata.scan.filter.FilterUtil; +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.metadata.FilterResolverMetadata; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.visitor.FilterInfoTypeVisitorFactory; + +public class ConditionalFilterResolverImpl implements FilterResolverIntf { + + private static final long serialVersionUID = 1838955268462201691L; + protected Expression exp; + protected boolean isExpressionResolve; + protected boolean isIncludeFilter; + private DimColumnResolvedFilterInfo dimColResolvedFilterInfo; + + public ConditionalFilterResolverImpl(Expression exp, boolean isExpressionResolve, + boolean isIncludeFilter) { + this.exp = exp; + this.isExpressionResolve = isExpressionResolve; + this.isIncludeFilter = isIncludeFilter; + this.dimColResolvedFilterInfo = new DimColumnResolvedFilterInfo(); + } + + /** + * This API will resolve the filter expression and generates the + * dictionaries for executing/evaluating the filter expressions in the + * executer layer. + * + * @throws QueryExecutionException + * @throws FilterUnsupportedException + */ + @Override public void resolve(AbsoluteTableIdentifier absoluteTableIdentifier) + throws FilterUnsupportedException { + FilterResolverMetadata metadata = new FilterResolverMetadata(); + metadata.setTableIdentifier(absoluteTableIdentifier); + if ((!isExpressionResolve) && exp instanceof BinaryConditionalExpression) { + BinaryConditionalExpression binaryConditionalExpression = (BinaryConditionalExpression) exp; + Expression leftExp = binaryConditionalExpression.getLeft(); + Expression rightExp = binaryConditionalExpression.getRight(); + if (leftExp instanceof ColumnExpression) { + ColumnExpression columnExpression = (ColumnExpression) leftExp; + metadata.setColumnExpression(columnExpression); + metadata.setExpression(rightExp); + metadata.setIncludeFilter(isIncludeFilter); + // If imei=imei comes in filter condition then we need to + // skip processing of right expression. + // This flow has reached here assuming that this is a single + // column expression. + // we need to check if the other expression contains column + // expression or not in depth. + if (FilterUtil.checkIfExpressionContainsColumn(rightExp)|| + FilterUtil.isExpressionNeedsToResolved(rightExp,isIncludeFilter) && + columnExpression.getDimension().hasEncoding(Encoding.DICTIONARY)){ + isExpressionResolve = true; + } else { + //Visitor pattern is been used in this scenario inorder to populate the + // dimColResolvedFilterInfo + //visitable object with filter member values based on the visitor type, currently there + //3 types of visitors custom,direct and no dictionary, all types of visitor populate + //the visitable instance as per its buisness logic which is different for all the + // visitors. + dimColResolvedFilterInfo.populateFilterInfoBasedOnColumnType( + FilterInfoTypeVisitorFactory.getResolvedFilterInfoVisitor(columnExpression), + metadata); + } + } else if (rightExp instanceof ColumnExpression) { + ColumnExpression columnExpression = (ColumnExpression) rightExp; + metadata.setColumnExpression(columnExpression); + metadata.setExpression(leftExp); + metadata.setIncludeFilter(isIncludeFilter); + if (columnExpression.getDataType().equals(DataType.TimestampType)) { + isExpressionResolve = true; + } else { + // if imei=imei comes in filter condition then we need to + // skip processing of right expression. + // This flow has reached here assuming that this is a single + // column expression. + // we need to check if the other expression contains column + // expression or not in depth. + if (FilterUtil.checkIfExpressionContainsColumn(leftExp)) { + isExpressionResolve = true; + } else { + + dimColResolvedFilterInfo.populateFilterInfoBasedOnColumnType( + FilterInfoTypeVisitorFactory.getResolvedFilterInfoVisitor(columnExpression), + metadata); + + } + } + } else { + isExpressionResolve = true; + } + } + if (isExpressionResolve && exp instanceof ConditionalExpression) { + ConditionalExpression conditionalExpression = (ConditionalExpression) exp; + List<ColumnExpression> columnList = conditionalExpression.getColumnList(); + metadata.setColumnExpression(columnList.get(0)); + metadata.setExpression(exp); + metadata.setIncludeFilter(isIncludeFilter); + if (!columnList.get(0).getDimension().hasEncoding(Encoding.DICTIONARY) || columnList.get(0) + .getDimension().hasEncoding(Encoding.DIRECT_DICTIONARY)) { + dimColResolvedFilterInfo.populateFilterInfoBasedOnColumnType( + FilterInfoTypeVisitorFactory.getResolvedFilterInfoVisitor(columnList.get(0)), metadata); + + } else if (columnList.get(0).getDimension().hasEncoding(Encoding.DICTIONARY) && !( + columnList.get(0).getDimension().getDataType() + == org.carbondata.core.carbon.metadata.datatype.DataType.STRUCT + || columnList.get(0).getDimension().getDataType() + == org.carbondata.core.carbon.metadata.datatype.DataType.ARRAY)) { + dimColResolvedFilterInfo.setFilterValues(FilterUtil + .getFilterListForAllValues(absoluteTableIdentifier, exp, columnList.get(0), + isIncludeFilter)); + + dimColResolvedFilterInfo.setColumnIndex(columnList.get(0).getDimension().getOrdinal()); + dimColResolvedFilterInfo.setDimension(columnList.get(0).getDimension()); + } + } + + } + + /** + * Left node will not be presentin this scenario + * + * @return left node of type FilterResolverIntf instance + */ + public FilterResolverIntf getLeft() { + // TODO Auto-generated method stub + return null; + } + + /** + * Right node will not be presentin this scenario + * + * @return left node of type FilterResolverIntf instance + */ + @Override public FilterResolverIntf getRight() { + // TODO Auto-generated method stub + return null; + } + + /** + * Method will return the DimColumnResolvedFilterInfo instance which consists + * the mapping of the respective dimension and its surrogates involved in + * filter expression. + * + * @return DimColumnResolvedFilterInfo + */ + public DimColumnResolvedFilterInfo getDimColResolvedFilterInfo() { + return dimColResolvedFilterInfo; + } + + /** + * method will calculates the start key based on the filter surrogates + */ + public void getStartKey(SegmentProperties segmentProperties, long[] startKey, + SortedMap<Integer, byte[]> setOfStartKeyByteArray) { + if (null == dimColResolvedFilterInfo.getStarIndexKey()) { + FilterUtil.getStartKeyForNoDictionaryDimension(dimColResolvedFilterInfo, segmentProperties, + setOfStartKeyByteArray); + } + } + + /** + * method will get the start key based on the filter surrogates + * + * @return end IndexKey + */ + @Override public void getEndKey(SegmentProperties segmentProperties, + AbsoluteTableIdentifier absoluteTableIdentifier, long[] endKeys, + SortedMap<Integer, byte[]> setOfEndKeyByteArray) { + if (null == dimColResolvedFilterInfo.getEndIndexKey()) { + try { + FilterUtil.getEndKey(dimColResolvedFilterInfo.getDimensionResolvedFilterInstance(), + absoluteTableIdentifier, endKeys, segmentProperties); + FilterUtil.getEndKeyForNoDictionaryDimension(dimColResolvedFilterInfo, segmentProperties, + setOfEndKeyByteArray); + } catch (QueryExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /** + * Method will return the executer type for particular conditional resolver + * basically two types of executers will be formed for the conditional query. + * + * @return the filter executer type + */ + @Override public FilterExecuterType getFilterExecuterType() { + switch (exp.getFilterExpressionType()) { + case NOT_EQUALS: + case NOT_IN: + return FilterExecuterType.EXCLUDE; + + default: + return FilterExecuterType.INCLUDE; + } + + } + + @Override public Expression getFilterExpression() { + // TODO Auto-generated method stub + return exp; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/FilterResolverIntf.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/FilterResolverIntf.java b/core/src/main/java/org/carbondata/scan/filter/resolver/FilterResolverIntf.java new file mode 100644 index 0000000..620b1ba --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/FilterResolverIntf.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.carbondata.scan.filter.resolver; + +import java.io.Serializable; +import java.util.SortedMap; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.block.SegmentProperties; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.expression.exception.FilterUnsupportedException; +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; + +public interface FilterResolverIntf extends Serializable { + + /** + * This API will resolve the filter expression and generates the + * dictionaries for executing/evaluating the filter expressions in the + * executer layer. + * + * @throws QueryExecutionException + * @throws FilterUnsupportedException + */ + void resolve(AbsoluteTableIdentifier absoluteTableIdentifier) throws FilterUnsupportedException; + + /** + * This API will provide the left column filter expression + * inorder to resolve the left expression filter. + * + * @return FilterResolverIntf + */ + FilterResolverIntf getLeft(); + + /** + * API will provide the right column filter expression inorder to resolve + * the right expression filter. + * + * @return FilterResolverIntf + */ + FilterResolverIntf getRight(); + + /** + * API will return the resolved filter instance, this instance will provide + * the resolved surrogates based on the applied filter + * + * @return DimColumnResolvedFilterInfo object + */ + DimColumnResolvedFilterInfo getDimColResolvedFilterInfo(); + + /** + * API will get the start key based on the filter applied based on the key generator + * + * @param segmentProperties + * @param startKey + * @param setOfStartKeyByteArray + */ + void getStartKey(SegmentProperties segmentProperties, long[] startKey, + SortedMap<Integer, byte[]> setOfStartKeyByteArray); + + /** + * API will read the end key based on the max surrogate of + * particular dimension column + * + * @param setOfEndKeyByteArray + * @param endKeys + * @return + */ + void getEndKey(SegmentProperties segmentProperties, AbsoluteTableIdentifier tableIdentifier, + long[] endKeys, SortedMap<Integer, byte[]> setOfEndKeyByteArray); + + /** + * API will return the filter executer type which will be used to evaluate + * the resolved filter while query execution + * + * @return FilterExecuterType. + */ + FilterExecuterType getFilterExecuterType(); + + Expression getFilterExpression(); + +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/LogicalFilterResolverImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/LogicalFilterResolverImpl.java b/core/src/main/java/org/carbondata/scan/filter/resolver/LogicalFilterResolverImpl.java new file mode 100644 index 0000000..48c43be --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/LogicalFilterResolverImpl.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.resolver; + +import java.util.SortedMap; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.block.SegmentProperties; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.filter.intf.ExpressionType; +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; + +public class LogicalFilterResolverImpl implements FilterResolverIntf { + /** + * + */ + private static final long serialVersionUID = 5734382980564402914L; + + protected FilterResolverIntf leftEvalutor; + + protected FilterResolverIntf rightEvalutor; + + protected ExpressionType filterExpressionType; + + public LogicalFilterResolverImpl(FilterResolverIntf leftEvalutor, + FilterResolverIntf rightEvalutor, ExpressionType filterExpressionType) { + this.leftEvalutor = leftEvalutor; + this.rightEvalutor = rightEvalutor; + this.filterExpressionType = filterExpressionType; + } + + /** + * Logical filter resolver will return the left and right filter expresison + * node for filter evaluation, so in this instance no implementation is required. + * + * @param absoluteTableIdentifier + */ + @Override public void resolve(AbsoluteTableIdentifier absoluteTableIdentifier) { + + } + + /** + * Since its a binary condition expresion the getLeft method will get the left + * node of filter expression + * + * @return FilterResolverIntf. + */ + public FilterResolverIntf getLeft() { + return leftEvalutor; + } + + /** + * Since its a binary condition expresion the getRight method will get the left + * node of filter expression + * + * @return FilterResolverIntf. + */ + public FilterResolverIntf getRight() { + return rightEvalutor; + } + + @Override public DimColumnResolvedFilterInfo getDimColResolvedFilterInfo() { + return null; + } + + @Override public void getStartKey(SegmentProperties segmentProperties, long[] startKey, + SortedMap<Integer, byte[]> setOfStartKeyByteArray) { + + } + + @Override public void getEndKey(SegmentProperties segmentProperties, + AbsoluteTableIdentifier tableIdentifier, long[] endKeys, + SortedMap<Integer, byte[]> setOfEndKeyByteArray) { + } + + @Override public FilterExecuterType getFilterExecuterType() { + switch (filterExpressionType) { + case OR: + return FilterExecuterType.OR; + case AND: + return FilterExecuterType.AND; + + default: + return null; + } + } + + @Override public Expression getFilterExpression() { + // TODO Auto-generated method stub + return null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/RestructureFilterResolverImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/RestructureFilterResolverImpl.java b/core/src/main/java/org/carbondata/scan/filter/resolver/RestructureFilterResolverImpl.java new file mode 100644 index 0000000..e91e6de --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/RestructureFilterResolverImpl.java @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.resolver; + +import java.util.List; +import java.util.SortedMap; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.datastore.block.SegmentProperties; +import org.carbondata.scan.expression.ColumnExpression; +import org.carbondata.scan.expression.DataType; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.expression.conditional.BinaryConditionalExpression; +import org.carbondata.scan.expression.conditional.ConditionalExpression; +import org.carbondata.scan.filter.FilterUtil; +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; + +public class RestructureFilterResolverImpl implements FilterResolverIntf { + /** + * + */ + private static final long serialVersionUID = -5399656036192814524L; + + protected DimColumnResolvedFilterInfo dimColumnResolvedFilterInfo; + + private Expression exp; + + private String defaultValue; + + private int surrogate; + + private boolean isExpressionResolve; + + private boolean isIncludeFilter; + + public RestructureFilterResolverImpl(Expression exp, String defaultValue, int surrogate, + boolean isExpressionResolve, boolean isIncludeFilter) { + dimColumnResolvedFilterInfo = new DimColumnResolvedFilterInfo(); + this.exp = exp; + this.defaultValue = defaultValue; + this.surrogate = surrogate; + this.isExpressionResolve = isExpressionResolve; + this.isIncludeFilter = isIncludeFilter; + } + + /** + * Method will resolve the filters and it will replace the newly added dimension with default + * value + * + * @param absoluteTableIdentifier + */ + @Override public void resolve(AbsoluteTableIdentifier absoluteTableIdentifier) { + + DimColumnResolvedFilterInfo dimColumnResolvedFilterInfo = new DimColumnResolvedFilterInfo(); + if (!this.isExpressionResolve && exp instanceof BinaryConditionalExpression) { + BinaryConditionalExpression binaryConditionalExpression = (BinaryConditionalExpression) exp; + Expression left = binaryConditionalExpression.getLeft(); + Expression right = binaryConditionalExpression.getRight(); + if (left instanceof ColumnExpression) { + ColumnExpression columnExpression = (ColumnExpression) left; + if (columnExpression.getDataType().equals(DataType.TimestampType)) { + isExpressionResolve = true; + } else { + // If imei=imei comes in filter condition then we need to + // skip processing of right expression. + // This flow has reached here assuming that this is a single + // column expression. + // we need to check if the other expression contains column + // expression or not in depth. + if (FilterUtil.checkIfExpressionContainsColumn(right)) { + isExpressionResolve = true; + } else { + dimColumnResolvedFilterInfo + .setColumnIndex(columnExpression.getCarbonColumn().getOrdinal()); + // dimColumnResolvedFilterInfo + // .setNeedCompressedData(info.getSlices().get(info.getCurrentSliceIndex()) + // .getDataCache(info.getFactTableName()).getAggKeyBlock()[columnExpression.getDim() + // .getOrdinal()]); + dimColumnResolvedFilterInfo.setFilterValues( + FilterUtil.getFilterListForRS(right, columnExpression, defaultValue, surrogate)); + } + } + } else if (right instanceof ColumnExpression) { + ColumnExpression columnExpression = (ColumnExpression) right; + if (columnExpression.getDataType().equals(DataType.TimestampType)) { + isExpressionResolve = true; + } else { + + // If imei=imei comes in filter condition then we need to + // skip processing of right expression. + // This flow has reached here assuming that this is a single + // column expression. + // we need to check if the other expression contains column + // expression or not in depth. + if (checkIfExpressionContainsColumn(left)) { + isExpressionResolve = true; + } else { + dimColumnResolvedFilterInfo + .setColumnIndex(columnExpression.getCarbonColumn().getOrdinal()); + // dimColumnResolvedFilterInfo + // .setNeedCompressedData(info.getSlices().get(info.getCurrentSliceIndex()) + // .getDataCache(info.getFactTableName()).getAggKeyBlock()[columnExpression.getDim() + // .getOrdinal()]); + dimColumnResolvedFilterInfo.setFilterValues( + FilterUtil.getFilterListForRS(left, columnExpression, defaultValue, surrogate)); + } + } + } + } + if (this.isExpressionResolve && exp instanceof ConditionalExpression) { + ConditionalExpression conditionalExpression = (ConditionalExpression) exp; + List<ColumnExpression> columnList = conditionalExpression.getColumnList(); + dimColumnResolvedFilterInfo.setColumnIndex(columnList.get(0).getDimension().getOrdinal()); + dimColumnResolvedFilterInfo.setFilterValues(FilterUtil + .getFilterListForAllMembersRS(exp, columnList.get(0), defaultValue, surrogate, + isIncludeFilter)); + } + + } + + /** + * This method will check if a given expression contains a column expression recursively. + * + * @return boolean + */ + private boolean checkIfExpressionContainsColumn(Expression expression) { + if (expression instanceof ColumnExpression) { + return true; + } + for (Expression child : expression.getChildren()) { + if (checkIfExpressionContainsColumn(child)) { + return true; + } + } + + return false; + } + + @Override public FilterResolverIntf getLeft() { + // TODO Auto-generated method stub + return null; + } + + @Override public FilterResolverIntf getRight() { + // TODO Auto-generated method stub + return null; + } + + /** + * Method will return the DimColumnResolvedFilterInfo instance which consists + * the mapping of the respective dimension and its surrogates involved in + * filter expression. + * + * @return DimColumnResolvedFilterInfo + */ + public DimColumnResolvedFilterInfo getDimColResolvedFilterInfo() { + return dimColumnResolvedFilterInfo; + } + + /** + * For restructure resolver no implementation is required for getting + * the start key since it already has default values + */ + @Override public void getStartKey(SegmentProperties segmentProperties, long[] startKeys, + SortedMap<Integer, byte[]> noDicStartKeys) { + + } + + /** + * For restructure resolver no implementation is required for getting + * the end key since it already has default values + * + * @return IndexKey. + */ + @Override public void getEndKey(SegmentProperties segmentProperties, + AbsoluteTableIdentifier tableIdentifier, long[] endKeys, + SortedMap<Integer, byte[]> noDicEndKeys) { + } + + /** + * Method will get the executer type inorder to create filter executer tree + * + * @return FilterExecuterType + */ + @Override public FilterExecuterType getFilterExecuterType() { + return FilterExecuterType.RESTRUCTURE; + } + + @Override public Expression getFilterExpression() { + // TODO Auto-generated method stub + return exp; + } +} http://git-wip-us.apache.org/repos/asf/incubator-carbondata/blob/1c725f5b/core/src/main/java/org/carbondata/scan/filter/resolver/RowLevelFilterResolverImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/carbondata/scan/filter/resolver/RowLevelFilterResolverImpl.java b/core/src/main/java/org/carbondata/scan/filter/resolver/RowLevelFilterResolverImpl.java new file mode 100644 index 0000000..7a26c12 --- /dev/null +++ b/core/src/main/java/org/carbondata/scan/filter/resolver/RowLevelFilterResolverImpl.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.carbondata.scan.filter.resolver; + +import java.util.ArrayList; +import java.util.List; + +import org.carbondata.core.carbon.AbsoluteTableIdentifier; +import org.carbondata.core.carbon.metadata.schema.table.column.CarbonMeasure; +import org.carbondata.core.constants.CarbonCommonConstants; +import org.carbondata.scan.expression.ColumnExpression; +import org.carbondata.scan.expression.Expression; +import org.carbondata.scan.expression.conditional.ConditionalExpression; +import org.carbondata.scan.filter.intf.FilterExecuterType; +import org.carbondata.scan.filter.resolver.resolverinfo.DimColumnResolvedFilterInfo; +import org.carbondata.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; + +public class RowLevelFilterResolverImpl extends ConditionalFilterResolverImpl { + + private static final long serialVersionUID = 176122729713729929L; + protected boolean isExpressionResolve; + protected boolean isIncludeFilter; + + private List<DimColumnResolvedFilterInfo> dimColEvaluatorInfoList; + private List<MeasureColumnResolvedFilterInfo> msrColEvalutorInfoList; + private AbsoluteTableIdentifier tableIdentifier; + + public RowLevelFilterResolverImpl(Expression exp, boolean isExpressionResolve, + boolean isIncludeFilter, AbsoluteTableIdentifier tableIdentifier) { + super(exp, isExpressionResolve, isIncludeFilter); + dimColEvaluatorInfoList = + new ArrayList<DimColumnResolvedFilterInfo>(CarbonCommonConstants.DEFAULT_COLLECTION_SIZE); + msrColEvalutorInfoList = new ArrayList<MeasureColumnResolvedFilterInfo>( + CarbonCommonConstants.DEFAULT_COLLECTION_SIZE); + this.tableIdentifier = tableIdentifier; + } + + /** + * Method which will resolve the filter expression by converting the filter member + * to its assigned dictionary values. + */ + public void resolve(AbsoluteTableIdentifier absoluteTableIdentifier) { + DimColumnResolvedFilterInfo dimColumnEvaluatorInfo = null; + MeasureColumnResolvedFilterInfo msrColumnEvalutorInfo = null; + int index = 0; + if (exp instanceof ConditionalExpression) { + ConditionalExpression conditionalExpression = (ConditionalExpression) exp; + List<ColumnExpression> columnList = conditionalExpression.getColumnList(); + for (ColumnExpression columnExpression : columnList) { + if (columnExpression.isDimension()) { + dimColumnEvaluatorInfo = new DimColumnResolvedFilterInfo(); + dimColumnEvaluatorInfo.setColumnIndex(columnExpression.getCarbonColumn().getOrdinal()); + dimColumnEvaluatorInfo.setRowIndex(index++); + dimColumnEvaluatorInfo.setDimension(columnExpression.getDimension()); + dimColumnEvaluatorInfo.setDimensionExistsInCurrentSilce(false); + dimColEvaluatorInfoList.add(dimColumnEvaluatorInfo); + } else { + msrColumnEvalutorInfo = new MeasureColumnResolvedFilterInfo(); + msrColumnEvalutorInfo.setRowIndex(index++); + msrColumnEvalutorInfo.setAggregator( + ((CarbonMeasure) columnExpression.getCarbonColumn()).getAggregateFunction()); + msrColumnEvalutorInfo + .setColumnIndex(((CarbonMeasure) columnExpression.getCarbonColumn()).getOrdinal()); + msrColumnEvalutorInfo.setType(columnExpression.getCarbonColumn().getDataType()); + msrColEvalutorInfoList.add(msrColumnEvalutorInfo); + } + } + } + } + + /** + * This method will provide the executer type to the callee inorder to identify + * the executer type for the filter resolution, Row level filter executer is a + * special executer since it get all the rows of the specified filter dimension + * and will be send to the spark for processing + */ + @Override public FilterExecuterType getFilterExecuterType() { + return FilterExecuterType.ROWLEVEL; + } + + /** + * Method will the read filter expression corresponding to the resolver. + * This method is required in row level executer inorder to evaluate the filter + * expression against spark, as mentioned above row level is a special type + * filter resolver. + * + * @return Expression + */ + public Expression getFilterExpresion() { + return exp; + } + + /** + * Method will return the DimColumnResolvedFilterInfo instance which consists + * the mapping of the respective dimension and its surrogates involved in + * filter expression. + * + * @return DimColumnResolvedFilterInfo + */ + public List<DimColumnResolvedFilterInfo> getDimColEvaluatorInfoList() { + return dimColEvaluatorInfoList; + } + + /** + * Method will return the DimColumnResolvedFilterInfo instance which containts + * measure level details. + * + * @return MeasureColumnResolvedFilterInfo + */ + public List<MeasureColumnResolvedFilterInfo> getMsrColEvalutorInfoList() { + return msrColEvalutorInfoList; + } + + /** + * Method will return table information which will be required for retrieving + * dictionary cache inorder to read all the members of respective dimension. + * + * @return AbsoluteTableIdentifier + */ + public AbsoluteTableIdentifier getTableIdentifier() { + return tableIdentifier; + } + +}