blob: d2c232dc9823005b54c60b2006c61f6bf47db855 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.asterix.formats.nontagged;
import org.apache.asterix.dataflow.data.nontagged.comparators.ABinaryComparator;
import org.apache.asterix.dataflow.data.nontagged.comparators.ACirclePartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.ADurationPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AIntervalAscPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AIntervalDescPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.ALinePartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AObjectAscRangeBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AObjectDescBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AObjectDescRangeBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.APoint3DPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.APointPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.APolygonPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.ARectanglePartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.AUUIDPartialBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.BooleanBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.RawBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.rangeinterval.IntervalAscRangeBinaryComparatorFactory;
import org.apache.asterix.dataflow.data.nontagged.comparators.rangeinterval.IntervalDescRangeBinaryComparatorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.data.IBinaryComparatorFactoryProvider;
import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
import org.apache.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import org.apache.hyracks.api.dataflow.value.IBinaryRangeComparatorFactory;
import org.apache.hyracks.api.dataflow.value.IRangePartitionType.RangePartitioningType;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
import org.apache.hyracks.data.std.primitive.ByteArrayPointable;
import org.apache.hyracks.data.std.primitive.BytePointable;
import org.apache.hyracks.data.std.primitive.DoublePointable;
import org.apache.hyracks.data.std.primitive.FloatPointable;
import org.apache.hyracks.data.std.primitive.IntegerPointable;
import org.apache.hyracks.data.std.primitive.LongPointable;
import org.apache.hyracks.data.std.primitive.ShortPointable;
import org.apache.hyracks.data.std.primitive.UTF8StringLowercasePointable;
import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
import java.io.Serializable;
public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFactoryProvider, Serializable {
private static final long serialVersionUID = 1L;
public static final AqlBinaryComparatorFactoryProvider INSTANCE = new AqlBinaryComparatorFactoryProvider();
public static final PointableBinaryComparatorFactory BYTE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
BytePointable.FACTORY);
public static final PointableBinaryComparatorFactory SHORT_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
ShortPointable.FACTORY);
public static final PointableBinaryComparatorFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
IntegerPointable.FACTORY);
public static final PointableBinaryComparatorFactory LONG_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
LongPointable.FACTORY);
public static final PointableBinaryComparatorFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
FloatPointable.FACTORY);
public static final PointableBinaryComparatorFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
DoublePointable.FACTORY);
public static final PointableBinaryComparatorFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
UTF8StringPointable.FACTORY);
// Equivalent to UTF8STRING_POINTABLE_INSTANCE but all characters are considered lower case to implement case-insensitive comparisons.
public static final PointableBinaryComparatorFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
UTF8StringLowercasePointable.FACTORY);
public static final PointableBinaryComparatorFactory BINARY_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
ByteArrayPointable.FACTORY);
private AqlBinaryComparatorFactoryProvider() {
}
// This method adds the option of range range
@Override
public IBinaryRangeComparatorFactory getRangeBinaryComparatorFactory(Object type, boolean ascending,
RangePartitioningType rangeType) {
if (type == null) {
return anyBinaryRangeComparatorFactory(ascending);
}
IAType aqlType = (IAType) type;
if (aqlType.getTypeTag() == ATypeTag.INTERVAL) {
return addOffsetForRange(getIntervalRangeBinaryComparatorFactory(ascending), ascending);
} else {
return anyBinaryRangeComparatorFactory(ascending);
}
}
// This method add the option of ignoring the case in string comparisons.
// TODO: We should incorporate this option more nicely, but I'd have to change algebricks.
public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending, boolean ignoreCase) {
if (type == null) {
return anyBinaryComparatorFactory(ascending);
}
IAType aqlType = (IAType) type;
if (aqlType.getTypeTag() == ATypeTag.STRING && ignoreCase) {
return addOffset(UTF8STRING_LOWERCASE_POINTABLE_INSTANCE, ascending);
}
return getBinaryComparatorFactory(type, ascending);
}
@Override
public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending) {
// During a comparison, since proper type promotion among several numeric types are required,
// we will use AObjectAscBinaryComparatorFactory, instead of using a specific comparator
return anyBinaryComparatorFactory(ascending);
}
public IBinaryComparatorFactory getBinaryComparatorFactory(ATypeTag type, boolean ascending) {
switch (type) {
case ANY:
case UNION: { // we could do smth better for nullable fields
return anyBinaryComparatorFactory(ascending);
}
case NULL:
case MISSING:
return new IBinaryComparatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public IBinaryComparator createBinaryComparator() {
return new IBinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return 0;
}
};
}
};
case BOOLEAN: {
return addOffset(BooleanBinaryComparatorFactory.INSTANCE, ascending);
}
case INT8: {
return addOffset(BYTE_POINTABLE_INSTANCE, ascending);
}
case INT16: {
return addOffset(SHORT_POINTABLE_INSTANCE, ascending);
}
case DATE:
case TIME:
case YEARMONTHDURATION:
case INT32: {
return addOffset(INTEGER_POINTABLE_INSTANCE, ascending);
}
case DATETIME:
case DAYTIMEDURATION:
case INT64: {
return addOffset(LONG_POINTABLE_INSTANCE, ascending);
}
case FLOAT: {
return addOffset(FLOAT_POINTABLE_INSTANCE, ascending);
}
case DOUBLE: {
return addOffset(DOUBLE_POINTABLE_INSTANCE, ascending);
}
case STRING: {
return addOffset(UTF8STRING_POINTABLE_INSTANCE, ascending);
}
case RECTANGLE: {
return addOffset(ARectanglePartialBinaryComparatorFactory.INSTANCE, ascending);
}
case CIRCLE: {
return addOffset(ACirclePartialBinaryComparatorFactory.INSTANCE, ascending);
}
case POINT: {
return addOffset(APointPartialBinaryComparatorFactory.INSTANCE, ascending);
}
case POINT3D: {
return addOffset(APoint3DPartialBinaryComparatorFactory.INSTANCE, ascending);
}
case LINE: {
return addOffset(ALinePartialBinaryComparatorFactory.INSTANCE, ascending);
}
case POLYGON: {
return addOffset(APolygonPartialBinaryComparatorFactory.INSTANCE, ascending);
}
case DURATION: {
return addOffset(ADurationPartialBinaryComparatorFactory.INSTANCE, ascending);
}
case INTERVAL: {
return addOffset(getIntervalBinaryComparatorFactory(ascending), ascending);
}
case UUID: {
return addOffset(AUUIDPartialBinaryComparatorFactory.INSTANCE, ascending);
}
case BINARY: {
return addOffset(BINARY_POINTABLE_INSTANCE, ascending);
}
default: {
return addOffset(RawBinaryComparatorFactory.INSTANCE, ascending);
}
}
}
private IBinaryComparatorFactory addOffset(final IBinaryComparatorFactory inst, final boolean ascending) {
return new IBinaryComparatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public IBinaryComparator createBinaryComparator() {
final IBinaryComparator bc = inst.createBinaryComparator();
if (ascending) {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
} else {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return -bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
}
}
};
}
private IBinaryRangeComparatorFactory addOffsetForRange(final IBinaryRangeComparatorFactory inst,
final boolean ascending) {
return new IBinaryRangeComparatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public IBinaryComparator createMinBinaryComparator() {
final IBinaryComparator bc = inst.createMinBinaryComparator();
if (ascending) {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
} else {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return -bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
}
}
@Override
public IBinaryComparator createMaxBinaryComparator() {
final IBinaryComparator bc = inst.createMaxBinaryComparator();
if (ascending) {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
} else {
return new ABinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
throws HyracksDataException {
return -bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
}
}
};
}
private IBinaryComparatorFactory anyBinaryComparatorFactory(boolean ascending) {
if (ascending) {
return AObjectAscBinaryComparatorFactory.INSTANCE;
} else {
return AObjectDescBinaryComparatorFactory.INSTANCE;
}
}
private IBinaryRangeComparatorFactory anyBinaryRangeComparatorFactory(boolean ascending) {
if (ascending) {
return AObjectAscRangeBinaryComparatorFactory.INSTANCE;
} else {
return AObjectDescRangeBinaryComparatorFactory.INSTANCE;
}
}
private IBinaryRangeComparatorFactory getIntervalRangeBinaryComparatorFactory(boolean ascending) {
if (ascending) {
return IntervalAscRangeBinaryComparatorFactory.INSTANCE;
} else {
return IntervalDescRangeBinaryComparatorFactory.INSTANCE;
}
}
private IBinaryComparatorFactory getIntervalBinaryComparatorFactory(boolean ascending) {
// Intervals have separate binary comparator factories, since asc is primarily based on start point
// and desc is similarly based on end point.
if (ascending) {
return AIntervalAscPartialBinaryComparatorFactory.INSTANCE;
} else {
return AIntervalDescPartialBinaryComparatorFactory.INSTANCE;
}
}
}