merge -r1055:1282 (merging from asterix_stabilization to asterix_lsm_stabilization)
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_lsm_stabilization@1322 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-om/pom.xml b/asterix-om/pom.xml
index ff9e143..730f443 100644
--- a/asterix-om/pom.xml
+++ b/asterix-om/pom.xml
@@ -6,9 +6,7 @@
<groupId>edu.uci.ics.asterix</groupId>
<version>0.0.4-SNAPSHOT</version>
</parent>
- <groupId>edu.uci.ics.asterix</groupId>
<artifactId>asterix-om</artifactId>
- <version>0.0.4-SNAPSHOT</version>
<build>
<plugins>
@@ -17,8 +15,9 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.7</source>
+ <target>1.7</target>
+ <fork>true</fork>
</configuration>
</plugin>
</plugins>
@@ -33,20 +32,18 @@
</dependency>
<dependency>
<groupId>edu.uci.ics.hyracks</groupId>
- <artifactId>hyracks-algebricks-compiler</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <artifactId> hyracks-storage-am-lsm-invertedindex </artifactId>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>edu.uci.ics.hyracks</groupId>
- <artifactId>
- hyracks-storage-am-lsm-invertedindex
- </artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <artifactId>algebricks-compiler</artifactId>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>edu.uci.ics.hyracks</groupId>
<artifactId>hyracks-storage-am-lsm-rtree</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/builders/IARecordBuilder.java b/asterix-om/src/main/java/edu/uci/ics/asterix/builders/IARecordBuilder.java
index 544b532..7cdb9a9 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/builders/IARecordBuilder.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/builders/IARecordBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 by The Regents of the University of California
+ * Copyright 2009-2013 by The Regents of the University of California
* 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 from
@@ -18,6 +18,7 @@
import java.io.DataOutput;
import java.io.IOException;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.hyracks.data.std.api.IValueReference;
@@ -49,8 +50,10 @@
* The field name.
* @param out
* The field value.
+ * @throws AsterixException
+ * if the field name conflicts with a closed field name
*/
- public void addField(IValueReference name, IValueReference value);
+ public void addField(IValueReference name, IValueReference value) throws AsterixException;
/**
* @param out
@@ -59,8 +62,10 @@
* Whether to write a typetag as part of the record's serialized
* representation.
* @throws IOException
+ * @throws AsterixException
+ * if any open field names conflict with each other
*/
- public void write(DataOutput out, boolean writeTypeTag) throws IOException;
+ public void write(DataOutput out, boolean writeTypeTag) throws IOException, AsterixException;
public int getFieldId(String fieldName);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/builders/RecordBuilder.java b/asterix-om/src/main/java/edu/uci/ics/asterix/builders/RecordBuilder.java
index 03f0e20..f5d07ae 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/builders/RecordBuilder.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/builders/RecordBuilder.java
@@ -1,40 +1,46 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.builders;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.SerializerDeserializerUtil;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunction;
+import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryHashFunctionFactory;
import edu.uci.ics.hyracks.data.std.api.IValueReference;
import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
public class RecordBuilder implements IARecordBuilder {
- private int openPartOffset;
+ private final static int DEFAULT_NUM_OPEN_FIELDS = 10;
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
- private ARecordType recType;
-
- private ByteArrayOutputStream closedPartOutputStream;
- private int[] closedPartOffsets;
- private int numberOfClosedFields;
- private byte[] nullBitMap;
- private int nullBitMapSize;
-
- private ByteArrayOutputStream openPartOutputStream;
- private long[] openPartOffsets;
- private long[] tempOpenPartOffsets;
-
- private int numberOfOpenFields;
-
- private int fieldNameHashCode;
- private final IBinaryHashFunction utf8HashFunction;
-
- // for write()
private int openPartOffsetArraySize;
private byte[] openPartOffsetArray;
private int offsetPosition;
@@ -42,25 +48,40 @@
private boolean isOpen;
private boolean isNullable;
private int numberOfSchemaFields;
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
- private final static byte RECORD_TYPE_TAG = ATypeTag.RECORD.serialize();
+
+ private int openPartOffset;
+ private ARecordType recType;
+
+ private final IBinaryHashFunction utf8HashFunction;
+ private final IBinaryComparator utf8Comparator;
+
+ private final ByteArrayOutputStream closedPartOutputStream;
+ private int[] closedPartOffsets;
+ private int numberOfClosedFields;
+ private byte[] nullBitMap;
+ private int nullBitMapSize;
+
+ private final ByteArrayAccessibleOutputStream openPartOutputStream;
+ private long[] openPartOffsets;
+ private int[] openFieldNameLengths;
+
+ private int numberOfOpenFields;
public RecordBuilder() {
this.closedPartOutputStream = new ByteArrayOutputStream();
this.numberOfClosedFields = 0;
- this.openPartOutputStream = new ByteArrayOutputStream();
- this.openPartOffsets = new long[20];
- this.tempOpenPartOffsets = new long[20];
-
+ this.openPartOutputStream = new ByteArrayAccessibleOutputStream();
+ this.openPartOffsets = new long[DEFAULT_NUM_OPEN_FIELDS];
+ this.openFieldNameLengths = new int[DEFAULT_NUM_OPEN_FIELDS];
this.numberOfOpenFields = 0;
- this.fieldNameHashCode = 0;
this.utf8HashFunction = new PointableBinaryHashFunctionFactory(UTF8StringPointable.FACTORY)
.createBinaryHashFunction();
+ this.utf8Comparator = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+ .createBinaryComparator();
- // for write()
this.openPartOffsetArray = null;
this.openPartOffsetArraySize = 0;
this.offsetPosition = 0;
@@ -135,23 +156,31 @@
}
@Override
- public void addField(IValueReference name, IValueReference value) {
+ public void addField(IValueReference name, IValueReference value) throws AsterixException {
if (numberOfOpenFields == openPartOffsets.length) {
- tempOpenPartOffsets = openPartOffsets;
- openPartOffsets = new long[numberOfOpenFields + 20];
- for (int i = 0; i < tempOpenPartOffsets.length; i++)
- openPartOffsets[i] = tempOpenPartOffsets[i];
+ openPartOffsets = Arrays.copyOf(openPartOffsets, openPartOffsets.length + DEFAULT_NUM_OPEN_FIELDS);
+ openFieldNameLengths = Arrays.copyOf(openFieldNameLengths, openFieldNameLengths.length
+ + DEFAULT_NUM_OPEN_FIELDS);
}
- fieldNameHashCode = utf8HashFunction.hash(name.getByteArray(), name.getStartOffset() + 1, name.getLength());
+ int fieldNameHashCode = utf8HashFunction.hash(name.getByteArray(), name.getStartOffset() + 1, name.getLength());
+ if (recType != null) {
+ int cFieldPos = recType.findFieldPosition(name.getByteArray(), name.getStartOffset() + 1,
+ name.getLength() - 1);
+ if (cFieldPos >= 0) {
+ throw new AsterixException("Open field \"" + recType.getFieldNames()[cFieldPos]
+ + "\" has the same field name as closed field at index " + cFieldPos);
+ }
+ }
openPartOffsets[this.numberOfOpenFields] = fieldNameHashCode;
openPartOffsets[this.numberOfOpenFields] = (openPartOffsets[numberOfOpenFields] << 32);
- openPartOffsets[numberOfOpenFields++] += openPartOutputStream.size();
+ openPartOffsets[numberOfOpenFields] += openPartOutputStream.size();
+ openFieldNameLengths[numberOfOpenFields++] = name.getLength() - 1;
openPartOutputStream.write(name.getByteArray(), name.getStartOffset() + 1, name.getLength() - 1);
openPartOutputStream.write(value.getByteArray(), value.getStartOffset(), value.getLength());
}
@Override
- public void write(DataOutput out, boolean writeTypeTag) throws IOException {
+ public void write(DataOutput out, boolean writeTypeTag) throws IOException, AsterixException {
int h = headerSize;
int recordLength;
// prepare the open part
@@ -163,13 +192,27 @@
openPartOffsetArray = new byte[openPartOffsetArraySize];
Arrays.sort(this.openPartOffsets, 0, numberOfOpenFields);
+ if (numberOfOpenFields > 1) {
+ byte[] openBytes = openPartOutputStream.getByteArray();
+ for (int i = 1; i < numberOfOpenFields; i++) {
+ if (utf8Comparator.compare(openBytes, (int) openPartOffsets[i - 1], openFieldNameLengths[i - 1],
+ openBytes, (int) openPartOffsets[i], openFieldNameLengths[i]) == 0) {
+ String field = UTF8StringSerializerDeserializer.INSTANCE
+ .deserialize(new DataInputStream(new ByteArrayInputStream(openBytes,
+ (int) openPartOffsets[i], openFieldNameLengths[i])));
+ throw new AsterixException("Open fields " + (i - 1) + " and " + i
+ + " have the same field name \"" + field + "\"");
+ }
+ }
+ }
openPartOffset = h + numberOfSchemaFields * 4 + closedPartOutputStream.size();
+ int fieldNameHashCode;
for (int i = 0; i < numberOfOpenFields; i++) {
fieldNameHashCode = (int) (openPartOffsets[i] >> 32);
SerializerDeserializerUtil.writeIntToByteArray(openPartOffsetArray, (int) fieldNameHashCode,
offsetPosition);
- int fieldOffset = (int) ((openPartOffsets[i] << 64) >> 64);
+ int fieldOffset = (int) openPartOffsets[i];
SerializerDeserializerUtil.writeIntToByteArray(openPartOffsetArray, fieldOffset + openPartOffset + 4
+ openPartOffsetArraySize, offsetPosition + 4);
offsetPosition += 8;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java
new file mode 100644
index 0000000..464a03c
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.comparators;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+
+public class ADateOrTimeAscBinaryComparatorFactory implements IBinaryComparatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final ADateOrTimeAscBinaryComparatorFactory INSTANCE = new ADateOrTimeAscBinaryComparatorFactory();
+
+ private ADateOrTimeAscBinaryComparatorFactory() {
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory#createBinaryComparator()
+ */
+ @Override
+ public IBinaryComparator createBinaryComparator() {
+ return new IBinaryComparator() {
+
+ @Override
+ public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+ int chrononTime1 = getInt(b1, s1);
+ int chrononTime2 = getInt(b2, s2);
+
+ if (chrononTime1 > chrononTime2) {
+ return 1;
+ } else if (chrononTime1 < chrononTime2) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+ private int getInt(byte[] bytes, int start) {
+ return ((bytes[start] & 0xff) << 24) + ((bytes[start + 1] & 0xff) << 16)
+ + ((bytes[start + 2] & 0xff) << 8) + ((bytes[start + 3] & 0xff) << 0);
+ }
+ };
+ }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
index 881590d..0e486e7 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
@@ -24,15 +24,21 @@
public IBinaryComparator createBinaryComparator() {
return new IBinaryComparator() {
final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();
- final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY).createBinaryComparator();
+ final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY)
+ .createBinaryComparator();
final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();
- final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY).createBinaryComparator();
- final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY).createBinaryComparator();
- final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY).createBinaryComparator();
+ final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+ .createBinaryComparator();
+ final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY)
+ .createBinaryComparator();
+ final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY)
+ .createBinaryComparator();
final IBinaryComparator ascRectangleComp = RectangleBinaryComparatorFactory.INSTANCE
.createBinaryComparator();
final IBinaryComparator ascDateTimeComp = ADateTimeAscBinaryComparatorFactory.INSTANCE
.createBinaryComparator();
+ final IBinaryComparator ascDateOrTimeComp = ADateOrTimeAscBinaryComparatorFactory.INSTANCE
+ .createBinaryComparator();
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
@@ -73,6 +79,10 @@
case DATETIME: {
return ascDateTimeComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
+ case TIME:
+ case DATE: {
+ return ascDateOrTimeComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
+ }
default: {
throw new NotImplementedException("Comparison for type " + tag + " is not implemented");
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/MurmurHash3BinaryHashFunctionFamily.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/MurmurHash3BinaryHashFunctionFamily.java
new file mode 100644
index 0000000..83b165b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/MurmurHash3BinaryHashFunctionFamily.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.hash;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunction;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFamily;
+
+/**
+ * An implementation of the Murmur3 hash family. The code is implemented based
+ * on the original <a
+ * href=http://code.google.com/p/guava-libraries/source/browse
+ * /guava/src/com/google/common/hash/Murmur3_32HashFunction.java>guava
+ * implementation</a> from Google Guava library.
+ */
+public class MurmurHash3BinaryHashFunctionFamily implements
+ IBinaryHashFunctionFamily {
+
+ public static final IBinaryHashFunctionFamily INSTANCE = new MurmurHash3BinaryHashFunctionFamily();
+
+ private static final long serialVersionUID = 1L;
+
+ private MurmurHash3BinaryHashFunctionFamily() {
+ }
+
+ private static final int C1 = 0xcc9e2d51;
+ private static final int C2 = 0x1b873593;
+ private static final int C3 = 5;
+ private static final int C4 = 0xe6546b64;
+ private static final int C5 = 0x85ebca6b;
+ private static final int C6 = 0xc2b2ae35;
+
+ @Override
+ public IBinaryHashFunction createBinaryHashFunction(final int seed) {
+ return new IBinaryHashFunction() {
+ @Override
+ public int hash(byte[] bytes, int offset, int length) {
+ int h = seed;
+ int p = offset;
+ int remain = length;
+ while (remain >= 4) {
+ int k = (bytes[p] & 0xff) | ((bytes[p + 1] & 0xff) << 8)
+ | ((bytes[p + 2] & 0xff) << 16)
+ | ((bytes[p + 3] & 0xff) << 24);
+ k *= C1;
+ k = Integer.rotateLeft(k, 15);
+ k *= C2;
+ h ^= k;
+ h = Integer.rotateLeft(h, 13);
+ h = h * C3 + C4;
+ p += 4;
+ remain -= 4;
+ }
+ if (remain > 0) {
+ int k = 0;
+ for (int i = 0; remain > 0; i += 8) {
+ k ^= (bytes[p++] & 0xff) << i;
+ remain--;
+ }
+ k *= C1;
+ k = Integer.rotateLeft(k, 15);
+ k *= C2;
+ h ^= k;
+ }
+ h ^= length;
+ h ^= (h >>> 16);
+ h *= C5;
+ h ^= (h >>> 13);
+ h *= C6;
+ h ^= (h >>> 16);
+ return h;
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32AscNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32AscNormalizedKeyComputerFactory.java
deleted file mode 100644
index 903ac3d..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32AscNormalizedKeyComputerFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
-
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.normalizers.IntegerNormalizedKeyComputerFactory;
-
-public class AInt32AscNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
-
- private static final long serialVersionUID = 1L;
-
- public static final AInt32AscNormalizedKeyComputerFactory INSTANCE = new AInt32AscNormalizedKeyComputerFactory();
-
- private IntegerNormalizedKeyComputerFactory inkcf = new IntegerNormalizedKeyComputerFactory();
-
- private AInt32AscNormalizedKeyComputerFactory() {
- }
-
- @Override
- public INormalizedKeyComputer createNormalizedKeyComputer() {
- final INormalizedKeyComputer intNkc = inkcf.createNormalizedKeyComputer();
- return new INormalizedKeyComputer() {
-
- @Override
- public int normalize(byte[] bytes, int start, int length) {
- return intNkc.normalize(bytes, start + 1, length - 1);
- }
- };
- }
-
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32DescNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32DescNormalizedKeyComputerFactory.java
deleted file mode 100644
index cec6a40..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AInt32DescNormalizedKeyComputerFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
-
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.normalizers.IntegerNormalizedKeyComputerFactory;
-
-public class AInt32DescNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
-
- private static final long serialVersionUID = 1L;
-
- public static final AInt32DescNormalizedKeyComputerFactory INSTANCE = new AInt32DescNormalizedKeyComputerFactory();
-
- private IntegerNormalizedKeyComputerFactory inkcf = new IntegerNormalizedKeyComputerFactory();
-
- private AInt32DescNormalizedKeyComputerFactory() {
- }
-
- @Override
- public INormalizedKeyComputer createNormalizedKeyComputer() {
- final INormalizedKeyComputer intNkc = inkcf.createNormalizedKeyComputer();
- return new INormalizedKeyComputer() {
-
- @Override
- public int normalize(byte[] bytes, int start, int length) {
- int nk = intNkc.normalize(bytes, start + 1, length - 1);
- return (int) ((long) 0xffffffff - (long) nk);
- }
- };
- }
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringAscNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringAscNormalizedKeyComputerFactory.java
deleted file mode 100644
index 0d1780f..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringAscNormalizedKeyComputerFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
-
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.normalizers.UTF8StringNormalizedKeyComputerFactory;
-
-public class AStringAscNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
-
- private static final long serialVersionUID = 1L;
-
- public static final AStringAscNormalizedKeyComputerFactory INSTANCE = new AStringAscNormalizedKeyComputerFactory();
-
- private AStringAscNormalizedKeyComputerFactory() {
- }
-
- private UTF8StringNormalizedKeyComputerFactory strnkcf = new UTF8StringNormalizedKeyComputerFactory();
-
- @Override
- public INormalizedKeyComputer createNormalizedKeyComputer() {
- final INormalizedKeyComputer strNkc = strnkcf.createNormalizedKeyComputer();
- return new INormalizedKeyComputer() {
-
- @Override
- public int normalize(byte[] bytes, int start, int length) {
- return strNkc.normalize(bytes, start + 1, length - 1);
- }
- };
- }
-
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringDescNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringDescNormalizedKeyComputerFactory.java
deleted file mode 100644
index 0ff6acd..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AStringDescNormalizedKeyComputerFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
-
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
-import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
-import edu.uci.ics.hyracks.dataflow.common.data.normalizers.UTF8StringNormalizedKeyComputerFactory;
-
-public class AStringDescNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
-
- private static final long serialVersionUID = 1L;
-
- public static final AStringDescNormalizedKeyComputerFactory INSTANCE = new AStringDescNormalizedKeyComputerFactory();
-
- private AStringDescNormalizedKeyComputerFactory() {
- }
-
- private UTF8StringNormalizedKeyComputerFactory strnkcf = new UTF8StringNormalizedKeyComputerFactory();
-
- @Override
- public INormalizedKeyComputer createNormalizedKeyComputer() {
- final INormalizedKeyComputer strNkc = strnkcf.createNormalizedKeyComputer();
- return new INormalizedKeyComputer() {
-
- @Override
- public int normalize(byte[] bytes, int start, int length) {
- int nk = strNkc.normalize(bytes, start + 1, length - 1);
- return (int) ((long) 0xffffffff - (long) nk);
- }
- };
- }
-
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedAscNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedAscNormalizedKeyComputerFactory.java
new file mode 100644
index 0000000..2efa593
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedAscNormalizedKeyComputerFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
+
+import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
+import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
+
+/**
+ * This class uses a decorator pattern to wrap an ASC ordered INomralizedKeyComputerFactory implementation to
+ * obtain the ASC order.
+ */
+public class AWrappedAscNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
+
+ private static final long serialVersionUID = 1L;
+ private final INormalizedKeyComputerFactory nkcf;
+
+ public AWrappedAscNormalizedKeyComputerFactory(INormalizedKeyComputerFactory nkcf) {
+ this.nkcf = nkcf;
+ }
+
+ @Override
+ public INormalizedKeyComputer createNormalizedKeyComputer() {
+ final INormalizedKeyComputer nkc = nkcf.createNormalizedKeyComputer();
+ return new INormalizedKeyComputer() {
+
+ @Override
+ public int normalize(byte[] bytes, int start, int length) {
+ // start +1, length -1 is because in ASTERIX data format, there is always a type tag before the value
+ return nkc.normalize(bytes, start + 1, length - 1);
+ }
+ };
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedDescNormalizedKeyComputerFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedDescNormalizedKeyComputerFactory.java
new file mode 100644
index 0000000..a5653b9
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/keynormalizers/AWrappedDescNormalizedKeyComputerFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers;
+
+import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputer;
+import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
+
+/**
+ * This class uses a decorator pattern to wrap an ASC ordered INomralizedKeyComputerFactory implementation
+ * to obtain the DESC order.
+ */
+public class AWrappedDescNormalizedKeyComputerFactory implements INormalizedKeyComputerFactory {
+
+ private static final long serialVersionUID = 1L;
+ private final INormalizedKeyComputerFactory nkcf;
+
+ public AWrappedDescNormalizedKeyComputerFactory(INormalizedKeyComputerFactory nkcf) {
+ this.nkcf = nkcf;
+ }
+
+ @Override
+ public INormalizedKeyComputer createNormalizedKeyComputer() {
+ final INormalizedKeyComputer nkc = nkcf.createNormalizedKeyComputer();
+ return new INormalizedKeyComputer() {
+
+ @Override
+ public int normalize(byte[] bytes, int start, int length) {
+ int key = nkc.normalize(bytes, start + 1, length - 1);
+ return (int) ((long) 0xffffffff - (long) key);
+ }
+ };
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinter.java
new file mode 100644
index 0000000..99c40b2
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.printers;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AIntervalPrinter implements IPrinter {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final AIntervalPrinter INSTANCE = new AIntervalPrinter();
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#init()
+ */
+ @Override
+ public void init() throws AlgebricksException {
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#print(byte[], int, int, java.io.PrintStream)
+ */
+ @Override
+ public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+ ps.print("interval(\"");
+
+ short typetag = AInt8SerializerDeserializer.getByte(b, s + 1 + 8 * 2);
+
+ IPrinter timeInstancePrinter;
+
+ if (typetag == ATypeTag.DATE.serialize()) {
+ timeInstancePrinter = ADatePrinter.INSTANCE;
+ } else if (typetag == ATypeTag.TIME.serialize()) {
+ timeInstancePrinter = ATimePrinter.INSTANCE;
+ } else if (typetag == ATypeTag.DATETIME.serialize()) {
+ timeInstancePrinter = ADateTimePrinter.INSTANCE;
+ } else {
+ throw new AlgebricksException("Unsupport internal time types in interval: " + typetag);
+ }
+
+ if (typetag == ATypeTag.TIME.serialize() || typetag == ATypeTag.DATE.serialize()) {
+ timeInstancePrinter.print(b, s + 1 + 4 - 1, 8, ps);
+ ps.print(", ");
+ timeInstancePrinter.print(b, s + 1 + 8 + 4 - 1, 8, ps);
+ } else {
+ timeInstancePrinter.print(b, s, 8, ps);
+ ps.print(", ");
+ timeInstancePrinter.print(b, s + 1 + 8 - 1, 8, ps);
+ }
+
+ ps.print("\")");
+ }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinterFactory.java
new file mode 100644
index 0000000..5500091
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AIntervalPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.printers;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AIntervalPrinterFactory implements IPrinterFactory {
+
+ private static final long serialVersionUID = 1L;
+ public static final AIntervalPrinterFactory INSTANCE = new AIntervalPrinterFactory();
+
+ @Override
+ public IPrinter createPrinter() {
+ return AIntervalPrinter.INSTANCE;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AObjectPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AObjectPrinter.java
index edcfc8a..478ad2c 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AObjectPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AObjectPrinter.java
@@ -73,6 +73,10 @@
ADurationPrinter.INSTANCE.print(b, s, l, ps);
break;
}
+ case INTERVAL: {
+ AIntervalPrinter.INSTANCE.print(b, s, l, ps);
+ break;
+ }
case POINT: {
APointPrinter.INSTANCE.print(b, s, l, ps);
break;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
index 9bd25f4..86a9a8d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateSerializerDeserializer.java
@@ -21,7 +21,7 @@
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.ADate;
import edu.uci.ics.asterix.om.base.AMutableDate;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
import edu.uci.ics.asterix.om.types.BuiltinType;
@@ -64,8 +64,8 @@
long chrononTimeInMs = 0;
try {
StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
- charAccessor.reset(date, 0);
- chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, true);
+ charAccessor.reset(date, 0, date.length());
+ chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, true);
} catch (Exception e) {
throw new HyracksDataException(e);
}
@@ -78,4 +78,8 @@
dateSerde.serialize(aDate, out);
}
+
+ public static int getChronon(byte[] byteArray, int offset) {
+ return AInt32SerializerDeserializer.getInt(byteArray, offset);
+ }
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
index cb9e8e0..cedfc8d 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADateTimeSerializerDeserializer.java
@@ -21,7 +21,8 @@
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.ADateTime;
import edu.uci.ics.asterix.om.base.AMutableDateTime;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -66,7 +67,7 @@
long chrononTimeInMs = 0;
try {
StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
- charAccessor.reset(datetime, 0);
+ charAccessor.reset(datetime, 0, datetime.length());
// +1 if it is negative (-)
short timeOffset = (short) ((charAccessor.getCharAt(0) == '-') ? 1 : 0);
@@ -78,11 +79,11 @@
// if extended form 11, else 9
timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
- chrononTimeInMs = ADateAndTimeParser.parseDatePart(charAccessor, false);
+ chrononTimeInMs = ADateParserFactory.parseDatePart(charAccessor, false);
- charAccessor.reset(datetime, timeOffset);
+ charAccessor.reset(datetime, timeOffset, datetime.length() - timeOffset);
- chrononTimeInMs += ADateAndTimeParser.parseTimePart(charAccessor);
+ chrononTimeInMs += ATimeParserFactory.parseTimePart(charAccessor);
} catch (Exception e) {
throw new HyracksDataException(e);
}
@@ -90,4 +91,8 @@
datetimeSerde.serialize(aDateTime, out);
}
+
+ public static long getChronon(byte[] data, int offset) {
+ return AInt64SerializerDeserializer.getLong(data, offset);
+ }
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
index c3333f0..88e2ea5 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADurationSerializerDeserializer.java
@@ -7,7 +7,7 @@
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.ADuration;
import edu.uci.ics.asterix.om.base.AMutableDuration;
-import edu.uci.ics.asterix.om.base.temporal.ADurationParser;
+import edu.uci.ics.asterix.om.base.temporal.ADurationParserFactory;
import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -48,12 +48,34 @@
try {
AMutableDuration aDuration = new AMutableDuration(0, 0);
StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
- charAccessor.reset(duration, 0);
- ADurationParser.parse(charAccessor, aDuration);
+ charAccessor.reset(duration, 0, duration.length());
+ ADurationParserFactory.parseDuration(charAccessor, aDuration);
durationSerde.serialize(aDuration, out);
} catch (Exception e) {
throw new HyracksDataException(e);
}
}
+
+ /**
+ * Get the year-month field of the duration as an integer number of days.
+ *
+ * @param data
+ * @param offset
+ * @return
+ */
+ public static int getYearMonth(byte[] data, int offset) {
+ return AInt32SerializerDeserializer.getInt(data, offset);
+ }
+
+ /**
+ * Get the day-time field of the duration as an long integer number of milliseconds.
+ *
+ * @param data
+ * @param offset
+ * @return
+ */
+ public static long getDayTime(byte[] data, int offset) {
+ return AInt64SerializerDeserializer.getLong(data, offset + 4);
+ }
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java
new file mode 100644
index 0000000..7c87dfa
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AIntervalSerializerDeserializer.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.dataflow.data.nontagged.serde;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInterval;
+import edu.uci.ics.asterix.om.base.AMutableInterval;
+import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public class AIntervalSerializerDeserializer implements ISerializerDeserializer<AInterval> {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final AIntervalSerializerDeserializer INSTANCE = new AIntervalSerializerDeserializer();
+ @SuppressWarnings("unchecked")
+ private static final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINTERVAL);
+
+ private static final String errorMessage = "This can not be an instance of interval";
+
+ private AIntervalSerializerDeserializer() {
+ }
+
+ @Override
+ public AInterval deserialize(DataInput in) throws HyracksDataException {
+ try {
+ return new AInterval(in.readLong(), in.readLong(), in.readByte());
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+
+ }
+
+ @Override
+ public void serialize(AInterval instance, DataOutput out) throws HyracksDataException {
+ try {
+ out.writeLong(instance.getIntervalStart());
+ out.writeLong(instance.getIntervalEnd());
+ out.writeByte(instance.getIntervalType());
+ } catch (IOException e) {
+ throw new HyracksDataException(e);
+ }
+
+ }
+
+ public static long getIntervalStart(byte[] data, int offset) {
+ return AInt64SerializerDeserializer.getLong(data, offset);
+ }
+
+ public static long getIntervalEnd(byte[] data, int offset) {
+ return AInt64SerializerDeserializer.getLong(data, offset + 8);
+ }
+
+ public static byte getIntervalTimeType(byte[] data, int offset) {
+ return data[offset + 8 * 2];
+ }
+
+ /**
+ * create an interval value from two given datetime instance.
+ *
+ * @param interval
+ * @param out
+ * @throws HyracksDataException
+ */
+ public static void parseDatetime(String interval, DataOutput out) throws HyracksDataException {
+ AMutableInterval aInterval = new AMutableInterval(0l, 0l, (byte) 0);
+
+ long chrononTimeInMsStart = 0;
+ long chrononTimeInMsEnd = 0;
+ try {
+
+ StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+
+ // Get the index for the comma
+ int commaIndex = interval.indexOf(',');
+ if (commaIndex < 0) {
+ throw new AlgebricksException("comma is missing for a string of interval");
+ }
+
+ int nonSpaceIndex = commaIndex - 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex--;
+ }
+
+ // Interval Start
+ charAccessor.reset(interval, 0, nonSpaceIndex + 1);
+
+ // +1 if it is negative (-)
+ short timeOffset = (short) ((charAccessor.getCharAt(0) == '-') ? 1 : 0);
+
+ if (charAccessor.getCharAt(timeOffset + 10) != 'T' && charAccessor.getCharAt(timeOffset + 8) != 'T') {
+ throw new AlgebricksException(errorMessage + ": missing T");
+ }
+
+ // if extended form 11, else 9
+ timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
+
+ chrononTimeInMsStart = ADateParserFactory.parseDatePart(charAccessor, false);
+
+ charAccessor.reset(interval, timeOffset, nonSpaceIndex - timeOffset + 1);
+
+ chrononTimeInMsStart += ATimeParserFactory.parseTimePart(charAccessor);
+
+ // Interval End
+ nonSpaceIndex = commaIndex + 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex++;
+ }
+
+ charAccessor.reset(interval, nonSpaceIndex, interval.length() - nonSpaceIndex);
+
+ // +1 if it is negative (-)
+ timeOffset = (short) ((charAccessor.getCharAt(0) == '-') ? 1 : 0);
+
+ if (charAccessor.getCharAt(timeOffset + 10) != 'T' && charAccessor.getCharAt(timeOffset + 8) != 'T') {
+ throw new AlgebricksException(errorMessage + ": missing T");
+ }
+
+ // if extended form 11, else 9
+ timeOffset += (charAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
+
+ chrononTimeInMsEnd = ADateParserFactory.parseDatePart(charAccessor, false);
+
+ charAccessor.reset(interval, nonSpaceIndex + timeOffset, interval.length() - nonSpaceIndex - timeOffset);
+
+ chrononTimeInMsEnd += ATimeParserFactory.parseTimePart(charAccessor);
+
+ } catch (Exception e) {
+ throw new HyracksDataException(e);
+ }
+
+ aInterval.setValue(chrononTimeInMsStart, chrononTimeInMsEnd, ATypeTag.DATETIME.serialize());
+
+ intervalSerde.serialize(aInterval, out);
+ }
+
+ public static void parseTime(String interval, DataOutput out) throws HyracksDataException {
+ AMutableInterval aInterval = new AMutableInterval(0l, 0l, (byte) 0);
+
+ long chrononTimeInMsStart = 0;
+ long chrononTimeInMsEnd = 0;
+ try {
+
+ StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+
+ // Get the index for the comma
+ int commaIndex = interval.indexOf(',');
+ if (commaIndex < 0) {
+ throw new AlgebricksException("comma is missing for a string of interval");
+ }
+
+ int nonSpaceIndex = commaIndex - 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex--;
+ }
+
+ // Interval Start
+ charAccessor.reset(interval, 0, nonSpaceIndex + 1);
+ chrononTimeInMsStart = ATimeParserFactory.parseTimePart(charAccessor);
+
+ if (chrononTimeInMsStart < 0) {
+ chrononTimeInMsStart += GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
+
+ // Interval End
+ nonSpaceIndex = commaIndex + 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex++;
+ }
+
+ charAccessor.reset(interval, nonSpaceIndex, interval.length() - nonSpaceIndex);
+ chrononTimeInMsEnd = ATimeParserFactory.parseTimePart(charAccessor);
+
+ if (chrononTimeInMsEnd < 0) {
+ chrononTimeInMsEnd += GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
+
+ } catch (Exception e) {
+ throw new HyracksDataException(e);
+ }
+
+ aInterval.setValue(chrononTimeInMsStart, chrononTimeInMsEnd, ATypeTag.TIME.serialize());
+ intervalSerde.serialize(aInterval, out);
+ }
+
+ public static void parseDate(String interval, DataOutput out) throws HyracksDataException {
+ AMutableInterval aInterval = new AMutableInterval(0l, 0l, (byte) 0);
+
+ long chrononTimeInMsStart = 0;
+ long chrononTimeInMsEnd = 0;
+ short tempStart = 0;
+ short tempEnd = 0;
+ try {
+ StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
+
+ // Get the index for the comma
+ int commaIndex = interval.indexOf(',');
+ if (commaIndex < 0) {
+ throw new AlgebricksException("comma is missing for a string of interval");
+ }
+
+ int nonSpaceIndex = commaIndex - 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex--;
+ }
+
+ // Interval Start
+ charAccessor.reset(interval, 0, nonSpaceIndex + 1);
+
+ chrononTimeInMsStart = ADateParserFactory.parseDatePart(charAccessor, true);
+
+ if (chrononTimeInMsStart < 0 && chrononTimeInMsStart % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
+ tempStart = 1;
+ }
+
+ // Interval End
+ nonSpaceIndex = commaIndex + 1;
+ while (interval.charAt(nonSpaceIndex) == ' ') {
+ nonSpaceIndex++;
+ }
+
+ charAccessor.reset(interval, nonSpaceIndex, interval.length() - nonSpaceIndex);
+
+ chrononTimeInMsEnd = ADateParserFactory.parseDatePart(charAccessor, true);
+
+ if (chrononTimeInMsEnd < 0 && chrononTimeInMsEnd % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
+ tempEnd = 1;
+ }
+
+ } catch (Exception e) {
+ throw new HyracksDataException(e);
+ }
+
+ aInterval.setValue((chrononTimeInMsStart / GregorianCalendarSystem.CHRONON_OF_DAY) - tempStart,
+ (chrononTimeInMsEnd / GregorianCalendarSystem.CHRONON_OF_DAY) - tempEnd, ATypeTag.DATE.serialize());
+
+ intervalSerde.serialize(aInterval, out);
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
index 311a6bc..b5b7303 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
@@ -15,6 +15,7 @@
import edu.uci.ics.asterix.om.base.AInt32;
import edu.uci.ics.asterix.om.base.AInt64;
import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AInterval;
import edu.uci.ics.asterix.om.base.ALine;
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.base.AOrderedList;
@@ -84,6 +85,9 @@
case DURATION: {
return ADurationSerializerDeserializer.INSTANCE.deserialize(in);
}
+ case INTERVAL: {
+ return AIntervalSerializerDeserializer.INSTANCE.deserialize(in);
+ }
case POINT: {
return APointSerializerDeserializer.INSTANCE.deserialize(in);
}
@@ -108,9 +112,9 @@
case UNORDEREDLIST: {
return AUnorderedListSerializerDeserializer.SCHEMALESS_INSTANCE.deserialize(in);
}
- // case TYPE: {
- // return AUnorderedListBytesConverter.INSTANCE.deserialize(in);
- // }
+ // case TYPE: {
+ // return AUnorderedListBytesConverter.INSTANCE.deserialize(in);
+ // }
default: {
throw new NotImplementedException("No serializer/deserializer implemented for type " + typeTag + " .");
}
@@ -179,6 +183,10 @@
ADurationSerializerDeserializer.INSTANCE.serialize((ADuration) instance, out);
break;
}
+ case INTERVAL: {
+ AIntervalSerializerDeserializer.INSTANCE.serialize((AInterval) instance, out);
+ break;
+ }
case POINT: {
APointSerializerDeserializer.INSTANCE.serialize((APoint) instance, out);
break;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index 393f634..a450f27 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 by The Regents of the University of California
+ * Copyright 2009-2013 by The Regents of the University of California
* 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 from
@@ -21,6 +21,7 @@
import edu.uci.ics.asterix.builders.IARecordBuilder;
import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
import edu.uci.ics.asterix.formats.nontagged.AqlBinaryHashFunctionFactoryProvider;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
@@ -149,7 +150,7 @@
} else {
return new ARecord(this.recordType, closedFields);
}
- } catch (IOException e) {
+ } catch (IOException | AsterixException e) {
throw new HyracksDataException(e);
}
}
@@ -166,7 +167,7 @@
return fields;
}
- private ARecordType mergeRecordTypes(ARecordType recType1, ARecordType recType2) {
+ private ARecordType mergeRecordTypes(ARecordType recType1, ARecordType recType2) throws AsterixException {
String[] fieldNames = new String[recType1.getFieldNames().length + recType2.getFieldNames().length];
IAType[] fieldTypes = new IAType[recType1.getFieldTypes().length + recType2.getFieldTypes().length];
@@ -199,7 +200,7 @@
}
try {
recordBuilder.write(out, false);
- } catch (IOException e) {
+ } catch (IOException | AsterixException e) {
throw new HyracksDataException(e);
}
} else {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
index 8860f2a..26e8d7a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ATimeSerializerDeserializer.java
@@ -7,7 +7,7 @@
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.AMutableTime;
import edu.uci.ics.asterix.om.base.ATime;
-import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory;
import edu.uci.ics.asterix.om.base.temporal.StringCharSequenceAccessor;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
@@ -52,8 +52,8 @@
try {
StringCharSequenceAccessor charAccessor = new StringCharSequenceAccessor();
- charAccessor.reset(time, 0);
- chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
+ charAccessor.reset(time, 0, time.length());
+ chrononTimeInMs = ATimeParserFactory.parseTimePart(charAccessor);
} catch (Exception e) {
throw new HyracksDataException(e);
}
@@ -63,4 +63,8 @@
timeSerde.serialize(aTime, out);
}
+ public static int getChronon(byte[] byteArray, int offset) {
+ return AInt32SerializerDeserializer.getInt(byteArray, offset);
+ }
+
}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
index c1df096..813c3a0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
@@ -14,6 +14,7 @@
import edu.uci.ics.hyracks.algebricks.data.IBinaryBooleanInspectorFactory;
import edu.uci.ics.hyracks.algebricks.data.IBinaryComparatorFactoryProvider;
import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFactoryProvider;
+import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFamilyProvider;
import edu.uci.ics.hyracks.algebricks.data.IBinaryIntegerInspectorFactory;
import edu.uci.ics.hyracks.algebricks.data.INormalizedKeyComputerFactoryProvider;
import edu.uci.ics.hyracks.algebricks.data.IPrinterFactoryProvider;
@@ -63,4 +64,6 @@
public IExpressionEvalSizeComputer getExpressionEvalSizeComputer();
public INormalizedKeyComputerFactoryProvider getNormalizedKeyComputerFactoryProvider();
+
+ public IBinaryHashFunctionFamilyProvider getBinaryHashFunctionFamilyProvider();
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
index e4db8da..02f0e47 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
@@ -2,6 +2,7 @@
import java.io.Serializable;
+import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateOrTimeAscBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateTimeAscBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectDescBinaryComparatorFactory;
@@ -19,8 +20,8 @@
import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
import edu.uci.ics.hyracks.data.std.primitive.LongPointable;
+import edu.uci.ics.hyracks.data.std.primitive.RawUTF8StringPointable;
import edu.uci.ics.hyracks.data.std.primitive.ShortPointable;
-import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFactoryProvider, Serializable {
@@ -39,7 +40,7 @@
public static final PointableBinaryComparatorFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
DoublePointable.FACTORY);
public static final PointableBinaryComparatorFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
- UTF8StringPointable.FACTORY);
+ RawUTF8StringPointable.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);
@@ -64,11 +65,11 @@
public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending) {
if (type == null) {
return anyBinaryComparatorFactory(ascending);
- }
+ }
IAType aqlType = (IAType) type;
return getBinaryComparatorFactory(aqlType.getTypeTag(), ascending);
}
-
+
public IBinaryComparatorFactory getBinaryComparatorFactory(ATypeTag type, boolean ascending) {
switch (type) {
case ANY:
@@ -120,13 +121,14 @@
return addOffset(RectangleBinaryComparatorFactory.INSTANCE, ascending);
}
case DATE:
- case TIME:
+ case TIME: {
+ return addOffset(ADateOrTimeAscBinaryComparatorFactory.INSTANCE, ascending);
+ }
case DATETIME: {
return addOffset(ADateTimeAscBinaryComparatorFactory.INSTANCE, ascending);
}
default: {
- throw new NotImplementedException("No binary comparator factory implemented for type "
- + type + " .");
+ throw new NotImplementedException("No binary comparator factory implemented for type " + type + " .");
}
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
index cab8ded..1afdbf8 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFactoryProvider.java
@@ -16,20 +16,25 @@
import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
+import edu.uci.ics.hyracks.data.std.primitive.RawUTF8StringPointable;
import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
-
public class AqlBinaryHashFunctionFactoryProvider implements IBinaryHashFunctionFactoryProvider, Serializable {
private static final long serialVersionUID = 1L;
public static final AqlBinaryHashFunctionFactoryProvider INSTANCE = new AqlBinaryHashFunctionFactoryProvider();
- public static final PointableBinaryHashFunctionFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(IntegerPointable.FACTORY);
- public static final PointableBinaryHashFunctionFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(FloatPointable.FACTORY);
- public static final PointableBinaryHashFunctionFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(DoublePointable.FACTORY);
- public static final PointableBinaryHashFunctionFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(UTF8StringPointable.FACTORY);
+ public static final PointableBinaryHashFunctionFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+ IntegerPointable.FACTORY);
+ public static final PointableBinaryHashFunctionFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+ FloatPointable.FACTORY);
+ public static final PointableBinaryHashFunctionFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+ DoublePointable.FACTORY);
+ public static final PointableBinaryHashFunctionFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+ RawUTF8StringPointable.FACTORY);
// Equivalent to UTF8STRING_POINTABLE_INSTANCE but all characters are considered lower case to implement case-insensitive hashing.
- public static final PointableBinaryHashFunctionFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(UTF8StringLowercasePointable.FACTORY);
-
+ public static final PointableBinaryHashFunctionFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryHashFunctionFactory(
+ UTF8StringLowercasePointable.FACTORY);
+
private AqlBinaryHashFunctionFactoryProvider() {
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java
new file mode 100644
index 0000000..bc7ba26
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryHashFunctionFamilyProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.formats.nontagged;
+
+import java.io.Serializable;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.hash.MurmurHash3BinaryHashFunctionFamily;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IBinaryHashFunctionFamilyProvider;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFamily;
+
+/**
+ * We use a type-independent binary hash function family from the hyracks
+ * codebase
+ */
+public class AqlBinaryHashFunctionFamilyProvider implements
+ IBinaryHashFunctionFamilyProvider, Serializable {
+
+ private static final long serialVersionUID = 1L;
+ public static final AqlBinaryHashFunctionFamilyProvider INSTANCE = new AqlBinaryHashFunctionFamilyProvider();
+
+ private AqlBinaryHashFunctionFamilyProvider() {
+
+ }
+
+ @Override
+ public IBinaryHashFunctionFamily getBinaryHashFunctionFamily(Object type)
+ throws AlgebricksException {
+ return MurmurHash3BinaryHashFunctionFamily.INSTANCE;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlNormalizedKeyComputerFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlNormalizedKeyComputerFactoryProvider.java
index fe953dc..23306ed 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlNormalizedKeyComputerFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlNormalizedKeyComputerFactoryProvider.java
@@ -1,12 +1,15 @@
package edu.uci.ics.asterix.formats.nontagged;
-import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AInt32AscNormalizedKeyComputerFactory;
-import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AInt32DescNormalizedKeyComputerFactory;
-import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AStringAscNormalizedKeyComputerFactory;
-import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AStringDescNormalizedKeyComputerFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AWrappedAscNormalizedKeyComputerFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.keynormalizers.AWrappedDescNormalizedKeyComputerFactory;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.hyracks.algebricks.data.INormalizedKeyComputerFactoryProvider;
import edu.uci.ics.hyracks.api.dataflow.value.INormalizedKeyComputerFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.normalizers.DoubleNormalizedKeyComputerFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.normalizers.FloatNormalizedKeyComputerFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.normalizers.Integer64NormalizedKeyComputerFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.normalizers.IntegerNormalizedKeyComputerFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.normalizers.UTF8StringNormalizedKeyComputerFactory;
public class AqlNormalizedKeyComputerFactoryProvider implements INormalizedKeyComputerFactoryProvider {
@@ -21,10 +24,19 @@
if (ascending) {
switch (aqlType.getTypeTag()) {
case INT32: {
- return AInt32AscNormalizedKeyComputerFactory.INSTANCE;
+ return new AWrappedAscNormalizedKeyComputerFactory(new IntegerNormalizedKeyComputerFactory());
+ }
+ case INT64: {
+ return new AWrappedAscNormalizedKeyComputerFactory(new Integer64NormalizedKeyComputerFactory());
+ }
+ case FLOAT: {
+ return new AWrappedAscNormalizedKeyComputerFactory(new FloatNormalizedKeyComputerFactory());
+ }
+ case DOUBLE: {
+ return new AWrappedAscNormalizedKeyComputerFactory(new DoubleNormalizedKeyComputerFactory());
}
case STRING: {
- return AStringAscNormalizedKeyComputerFactory.INSTANCE;
+ return new AWrappedAscNormalizedKeyComputerFactory(new UTF8StringNormalizedKeyComputerFactory());
}
default: {
return null;
@@ -33,10 +45,19 @@
} else {
switch (aqlType.getTypeTag()) {
case INT32: {
- return AInt32DescNormalizedKeyComputerFactory.INSTANCE;
+ return new AWrappedDescNormalizedKeyComputerFactory(new IntegerNormalizedKeyComputerFactory());
+ }
+ case INT64: {
+ return new AWrappedDescNormalizedKeyComputerFactory(new Integer64NormalizedKeyComputerFactory());
+ }
+ case FLOAT: {
+ return new AWrappedDescNormalizedKeyComputerFactory(new FloatNormalizedKeyComputerFactory());
+ }
+ case DOUBLE: {
+ return new AWrappedDescNormalizedKeyComputerFactory(new DoubleNormalizedKeyComputerFactory());
}
case STRING: {
- return AStringDescNormalizedKeyComputerFactory.INSTANCE;
+ return new AWrappedDescNormalizedKeyComputerFactory(new UTF8StringNormalizedKeyComputerFactory());
}
default: {
return null;
@@ -44,5 +65,4 @@
}
}
}
-
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlPrinterFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlPrinterFactoryProvider.java
index b576ce0..fe8792f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlPrinterFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlPrinterFactoryProvider.java
@@ -1,6 +1,5 @@
package edu.uci.ics.asterix.formats.nontagged;
-
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ABooleanPrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ACirclePrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ADatePrinterFactory;
@@ -12,6 +11,7 @@
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AInt32PrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AInt64PrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AInt8PrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AIntervalPrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ALinePrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ANullPrinterFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ANullableFieldPrinterFactory;
@@ -49,8 +49,8 @@
if (aqlType != null) {
switch (aqlType.getTypeTag()) {
- // case ANYTYPE:
- // return AAnyTypePrinterFactory.INSTANCE;
+ // case ANYTYPE:
+ // return AAnyTypePrinterFactory.INSTANCE;
case INT8:
return AInt8PrinterFactory.INSTANCE;
case INT16:
@@ -75,6 +75,8 @@
return ADateTimePrinterFactory.INSTANCE;
case DURATION:
return ADurationPrinterFactory.INSTANCE;
+ case INTERVAL:
+ return AIntervalPrinterFactory.INSTANCE;
case POINT:
return APointPrinterFactory.INSTANCE;
case POINT3D:
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
index 5492c5c..29e33fd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
@@ -16,6 +16,7 @@
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AIntervalSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ALineSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ANullSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer;
@@ -111,6 +112,9 @@
case DURATION: {
return ADurationSerializerDeserializer.INSTANCE;
}
+ case INTERVAL: {
+ return AIntervalSerializerDeserializer.INSTANCE;
+ }
case ORDEREDLIST: {
return new AOrderedListSerializerDeserializer((AOrderedListType) aqlType);
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlTypeTraitProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlTypeTraitProvider.java
index eac6602..a7e8e83 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlTypeTraitProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlTypeTraitProvider.java
@@ -14,6 +14,7 @@
private static final ITypeTraits FOURBYTETYPETRAIT = new TypeTrait(4 + 1);
private static final ITypeTraits EIGHTBYTETYPETRAIT = new TypeTrait(8 + 1);
private static final ITypeTraits SIXTEENBYTETYPETRAIT = new TypeTrait(16 + 1);
+ private static final ITypeTraits SEVENTEENBYTETYPETRAIT = new TypeTrait(17 + 1);
private static final ITypeTraits THIRTYTWOBYTETYPETRAIT = new TypeTrait(32 + 1);
private static final ITypeTraits TWENTYFOURBYTETYPETRAIT = new TypeTrait(24 + 1);
@@ -42,6 +43,8 @@
return EIGHTBYTETYPETRAIT;
case POINT:
return SIXTEENBYTETYPETRAIT;
+ case INTERVAL:
+ return SEVENTEENBYTETYPETRAIT;
case POINT3D:
return TWENTYFOURBYTETYPETRAIT;
case LINE:
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
index ea4c33b..097b736 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/ADate.java
@@ -30,7 +30,7 @@
*/
protected int chrononTimeInDay;
- private static long CHRONON_OF_DAY = 24 * 60 * 60 * 1000;
+ protected static long CHRONON_OF_DAY = 24 * 60 * 60 * 1000;
public ADate(int chrononTimeInDay) {
this.chrononTimeInDay = chrononTimeInDay;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AInterval.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AInterval.java
new file mode 100644
index 0000000..66a587a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AInterval.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.visitors.IOMVisitor;
+
+public class AInterval implements IAObject {
+
+ protected long intervalStart;
+ protected long intervalEnd;
+ protected byte typetag;
+
+ public AInterval(long intervalStart, long intervalEnd, byte typetag) {
+ this.intervalStart = intervalStart;
+ this.intervalEnd = intervalEnd;
+ this.typetag = typetag;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.base.IAObject#getType()
+ */
+ @Override
+ public IAType getType() {
+ return BuiltinType.AINTERVAL;
+ }
+
+ public int compare(Object o) {
+ if (!(o instanceof AInterval)) {
+ return -1;
+ }
+ AInterval d = (AInterval) o;
+ if (d.intervalStart == this.intervalStart && d.intervalEnd == this.intervalEnd && d.typetag == this.typetag) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof AInterval)) {
+ return false;
+ } else {
+ AInterval t = (AInterval) o;
+ return (t.intervalStart == this.intervalStart || t.intervalEnd == this.intervalEnd
+ && t.typetag == this.typetag);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (((int) (this.intervalStart ^ (this.intervalStart >>> 32))) * 31 + (int) (this.intervalEnd ^ (this.intervalEnd >>> 32)))
+ * 31 + (int) this.typetag;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.base.IAObject#accept(edu.uci.ics.asterix.om.visitors.IOMVisitor)
+ */
+ @Override
+ public void accept(IOMVisitor visitor) throws AsterixException {
+ visitor.visitAInterval(this);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.base.IAObject#deepEqual(edu.uci.ics.asterix.om.base.IAObject)
+ */
+ @Override
+ public boolean deepEqual(IAObject obj) {
+ return equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.base.IAObject#hash()
+ */
+ @Override
+ public int hash() {
+ return hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sbder = new StringBuilder();
+ sbder.append("AInterval: { ");
+ if (typetag == ATypeTag.DATE.serialize()) {
+ sbder.append("ADate: { ");
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(
+ intervalStart * ADate.CHRONON_OF_DAY, 0, sbder, GregorianCalendarSystem.Fields.YEAR,
+ GregorianCalendarSystem.Fields.DAY);
+ sbder.append(" }, ADate: {");
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(
+ intervalEnd * ADate.CHRONON_OF_DAY, 0, sbder, GregorianCalendarSystem.Fields.YEAR,
+ GregorianCalendarSystem.Fields.DAY);
+ sbder.append(" }");
+ } else if (typetag == ATypeTag.TIME.serialize()) {
+ sbder.append("ATime: { ");
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(intervalStart, 0, sbder,
+ GregorianCalendarSystem.Fields.HOUR, GregorianCalendarSystem.Fields.MILLISECOND);
+ sbder.append(" }, ATime: { ");
+
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(intervalEnd, 0, sbder,
+ GregorianCalendarSystem.Fields.HOUR, GregorianCalendarSystem.Fields.MILLISECOND);
+ sbder.append(" }");
+ } else if (typetag == ATypeTag.DATETIME.serialize()) {
+ sbder.append("ADateTime: { ");
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(intervalStart, 0, sbder,
+ GregorianCalendarSystem.Fields.YEAR, GregorianCalendarSystem.Fields.MILLISECOND);
+ sbder.append(" }, ADateTime: { ");
+ GregorianCalendarSystem.getInstance().getExtendStringRepWithTimezoneUntilField(intervalEnd, 0, sbder,
+ GregorianCalendarSystem.Fields.YEAR, GregorianCalendarSystem.Fields.MILLISECOND);
+ sbder.append(" }");
+ }
+ sbder.append(" }");
+ return sbder.toString();
+ }
+
+ public long getIntervalStart() {
+ return intervalStart;
+ }
+
+ public long getIntervalEnd() {
+ return intervalEnd;
+ }
+
+ public short getIntervalType() {
+ return typetag;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableInterval.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableInterval.java
new file mode 100644
index 0000000..055535f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/AMutableInterval.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base;
+
+public class AMutableInterval extends AInterval {
+
+ public AMutableInterval(long intervalStart, long intervalEnd, byte typetag) {
+ super(intervalStart, intervalEnd, typetag);
+ }
+
+ public void setValue(long intervalStart, long intervalEnd, byte typetag) {
+ this.intervalStart = intervalStart;
+ this.intervalEnd = intervalEnd;
+ this.typetag = typetag;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java
deleted file mode 100644
index 30ee525..0000000
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateAndTimeParser.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2009-2011 by The Regents of the University of California
- * 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 from
- *
- * 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 edu.uci.ics.asterix.om.base.temporal;
-
-public class ADateAndTimeParser {
-
- private static final GregorianCalendarSystem gCalInstance = GregorianCalendarSystem.getInstance();
-
- private static final String dateErrorMessage = "Wrong date format!";
- private static final String timeErrorMessage = "Wrong time format!";
-
- /**
- * Parse the given char sequence as a date string, and return the milliseconds represented by the date.
- *
- * @param charAccessor
- * accessor for the char sequence
- * @param isDateOnly
- * indicating whether it is a single date string, or it is the date part of a datetime string
- * @param errorMessage
- * @return
- * @throws Exception
- */
- public static <T> long parseDatePart(ICharSequenceAccessor<T> charAccessor, boolean isDateOnly) throws Exception {
-
- int length = charAccessor.getLength();
- int offset = 0;
-
- int year = 0, month = 0, day = 0;
- boolean positive = true;
-
- boolean isExtendedForm = false;
-
- if (charAccessor.getCharAt(offset) == '-') {
- offset++;
- positive = false;
- }
-
- if ((isDateOnly) && charAccessor.getCharAt(offset + 4) == '-' || (!isDateOnly)
- && charAccessor.getCharAt(offset + 13) == ':') {
- isExtendedForm = true;
- }
-
- if (isExtendedForm) {
- if (charAccessor.getCharAt(offset + 4) != '-' || charAccessor.getCharAt(offset + 7) != '-') {
- throw new Exception(dateErrorMessage);
- }
- }
-
- // year
- for (int i = 0; i < 4; i++) {
- if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
- year = year * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(dateErrorMessage);
- }
- }
-
- if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.YEAR.ordinal()]
- || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.YEAR.ordinal()]) {
- throw new Exception(dateErrorMessage + ": year " + year);
- }
-
- offset += (isExtendedForm) ? 5 : 4;
-
- // month
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
- month = month * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(dateErrorMessage);
- }
- }
-
- if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MONTH.ordinal()]
- || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MONTH.ordinal()]) {
- throw new Exception(dateErrorMessage + ": month " + month);
- }
- offset += (isExtendedForm) ? 3 : 2;
-
- // day
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
- day = day * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(dateErrorMessage);
- }
- }
-
- if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.DAY.ordinal()]
- || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.DAY.ordinal()]) {
- throw new Exception(dateErrorMessage + ": day " + day);
- }
-
- offset += 2;
-
- if (!positive) {
- year *= -1;
- }
-
- if (isDateOnly && length > offset) {
- throw new Exception(dateErrorMessage);
- }
- return gCalInstance.getChronon(year, month, day, 0, 0, 0, 0, 0);
- }
-
- /**
- * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
- *
- * @param charAccessor
- * @return
- * @throws Exception
- */
- public static <T> int parseTimePart(ICharSequenceAccessor<T> charAccessor) throws Exception {
-
- int length = charAccessor.getLength();
- int offset = 0;
-
- int hour = 0, min = 0, sec = 0, millis = 0;
- int timezone = 0;
-
- boolean isExtendedForm = false;
- if (charAccessor.getCharAt(offset + 2) == ':') {
- isExtendedForm = true;
- }
-
- if (isExtendedForm && (charAccessor.getCharAt(offset + 2) != ':' || charAccessor.getCharAt(offset + 5) != ':')) {
- throw new Exception(timeErrorMessage);
- }
- // hour
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
- hour = hour * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(timeErrorMessage);
- }
- }
-
- if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.HOUR.ordinal()]
- || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.HOUR.ordinal()]) {
- throw new Exception(timeErrorMessage + ": hour " + hour);
- }
-
- offset += (isExtendedForm) ? 3 : 2;
-
- // minute
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
- min = min * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(timeErrorMessage);
- }
- }
-
- if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]
- || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]) {
- throw new Exception(timeErrorMessage + ": min " + min);
- }
-
- offset += (isExtendedForm) ? 3 : 2;
-
- // second
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
- sec = sec * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- throw new Exception(timeErrorMessage);
- }
- }
-
- if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.SECOND.ordinal()]
- || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.SECOND.ordinal()]) {
- throw new Exception(timeErrorMessage + ": sec " + sec);
- }
-
- offset += 2;
-
- if ((isExtendedForm && length > offset && charAccessor.getCharAt(offset) == '.')
- || (!isExtendedForm && length > offset)) {
-
- offset += (isExtendedForm) ? 1 : 0;
- int i = 0;
- for (; i < 3 && offset + i < length; i++) {
- if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
- millis = millis * 10 + charAccessor.getCharAt(offset + i) - '0';
- } else {
- break;
- }
- }
-
- offset += i;
-
- for (; i < 3; i++) {
- millis = millis * 10;
- }
-
- // error is thrown if more than three digits are seen for the millisecond part
- if (charAccessor.getCharAt(offset) >= '0' && charAccessor.getCharAt(offset) <= '9') {
- throw new Exception("Wrong format of time instance: too many fields for millisecond.");
- }
- }
-
- if (length > offset) {
- if (charAccessor.getCharAt(offset) != 'Z') {
- if ((charAccessor.getCharAt(offset) != '+' && charAccessor.getCharAt(offset) != '-')
- || (isExtendedForm && charAccessor.getCharAt(offset + 3) != ':')) {
- throw new Exception(timeErrorMessage);
- }
-
- short timezoneHour = 0;
- short timezoneMinute = 0;
-
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + 1 + i) >= '0' && charAccessor.getCharAt(offset + 1 + i) <= '9')) {
- timezoneHour = (short) (timezoneHour * 10 + charAccessor.getCharAt(offset + 1 + i) - '0');
- } else {
- throw new Exception(timeErrorMessage);
- }
- }
-
- if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
- || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
- throw new Exception(timeErrorMessage + ": time zone hour " + timezoneHour);
- }
-
- int temp_offset = (isExtendedForm) ? 1 : 0;
-
- for (int i = 0; i < 2; i++) {
- if ((charAccessor.getCharAt(offset + temp_offset + 3 + i) >= '0' && charAccessor.getCharAt(offset
- + temp_offset + 3 + i) <= '9')) {
- timezoneMinute = (short) (timezoneMinute * 10
- + charAccessor.getCharAt(offset + temp_offset + 3 + i) - '0');
- } else {
- throw new Exception(timeErrorMessage);
- }
- }
-
- if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
- || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
- throw new Exception(timeErrorMessage + ": time zone minute " + timezoneMinute);
- }
-
- if (charAccessor.getCharAt(offset) == '-') {
- timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
- } else {
- timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
- }
- }
- }
-
- return gCalInstance.getChronon(hour, min, sec, millis, timezone);
- }
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java
new file mode 100644
index 0000000..8192919
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateParserFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADateParserFactory implements IValueParserFactory {
+
+ public static final IValueParserFactory INSTANCE = new ADateParserFactory();
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String dateErrorMessage = "Wrong input format for a date value";
+
+ private ADateParserFactory() {
+
+ }
+
+ @Override
+ public IValueParser createValueParser() {
+
+ final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+ return new IValueParser() {
+
+ @Override
+ public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+ charArrayAccessor.reset(buffer, start, length);
+ try {
+ out.writeInt((int) (parseDatePart(charArrayAccessor, true) / GregorianCalendarSystem.CHRONON_OF_DAY));
+ } catch (IOException ex) {
+ throw new HyracksDataException(ex);
+ }
+ }
+ };
+ }
+
+ /**
+ * Parse the given char sequence as a date string, and return the milliseconds represented by the date.
+ *
+ * @param charAccessor
+ * accessor for the char sequence
+ * @param isDateOnly
+ * indicating whether it is a single date string, or it is the date part of a datetime string
+ * @param errorMessage
+ * @return
+ * @throws Exception
+ */
+ public static <T> long parseDatePart(ICharSequenceAccessor<T> charAccessor, boolean isDateOnly)
+ throws HyracksDataException {
+
+ int length = charAccessor.getLength();
+ int offset = 0;
+
+ int year = 0, month = 0, day = 0;
+ boolean positive = true;
+
+ boolean isExtendedForm = false;
+
+ if (charAccessor.getCharAt(offset) == '-') {
+ offset++;
+ positive = false;
+ }
+
+ if ((isDateOnly) && charAccessor.getCharAt(offset + 4) == '-' || (!isDateOnly)
+ && charAccessor.getCharAt(offset + 13) == ':') {
+ isExtendedForm = true;
+ }
+
+ if (isExtendedForm) {
+ if (charAccessor.getCharAt(offset + 4) != '-' || charAccessor.getCharAt(offset + 7) != '-') {
+ throw new HyracksDataException("Missing dash in the date string as an extended form");
+ }
+ }
+
+ // year
+ for (int i = 0; i < 4; i++) {
+ if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
+ year = year * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException("Non-numeric value in year field");
+ }
+ }
+
+ if (year < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.YEAR.ordinal()]
+ || year > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.YEAR.ordinal()]) {
+ throw new HyracksDataException(dateErrorMessage + ": year " + year);
+ }
+
+ offset += (isExtendedForm) ? 5 : 4;
+
+ // month
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+ month = month * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException("Non-numeric value in month field");
+ }
+ }
+
+ if (month < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MONTH.ordinal()]
+ || month > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MONTH.ordinal()]) {
+ throw new HyracksDataException(dateErrorMessage + ": month " + month);
+ }
+ offset += (isExtendedForm) ? 3 : 2;
+
+ // day
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+ day = day * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException("Non-numeric value in day field");
+ }
+ }
+
+ if (day < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.DAY.ordinal()]
+ || day > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.DAY.ordinal()]) {
+ throw new HyracksDataException(dateErrorMessage + ": day " + day);
+ }
+
+ offset += 2;
+
+ if (!positive) {
+ year *= -1;
+ }
+
+ if (isDateOnly && length > offset) {
+ throw new HyracksDataException("Too many chars for a date only value");
+ }
+ return GregorianCalendarSystem.getInstance().getChronon(year, month, day, 0, 0, 0, 0, 0);
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java
new file mode 100644
index 0000000..2df3c3b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADateTimeParserFactory.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADateTimeParserFactory implements IValueParserFactory {
+
+ public static final IValueParserFactory INSTANCE = new ADateTimeParserFactory();
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String dateTimeErrorMessage = "Wrong Input Format for a DateTime Value";
+
+ private ADateTimeParserFactory() {
+
+ }
+
+ @Override
+ public IValueParser createValueParser() {
+
+ final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+ return new IValueParser() {
+
+ @Override
+ public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+ long chrononTimeInMs = 0;
+
+ charArrayAccessor.reset(buffer, start, length);
+
+ short timeOffset = (short) ((charArrayAccessor.getCharAt(0) == '-') ? 1 : 0);
+
+ if (charArrayAccessor.getCharAt(timeOffset + 10) != 'T'
+ && charArrayAccessor.getCharAt(timeOffset + 8) != 'T') {
+ throw new HyracksDataException(dateTimeErrorMessage + ": missing T");
+ }
+
+ // if extended form 11, else 9
+ timeOffset += (charArrayAccessor.getCharAt(timeOffset + 13) == ':') ? (short) (11) : (short) (9);
+
+ chrononTimeInMs = ADateParserFactory.parseDatePart(charArrayAccessor, false);
+
+ charArrayAccessor.reset(buffer, start + timeOffset, length - timeOffset);
+
+ chrononTimeInMs += ATimeParserFactory.parseTimePart(charArrayAccessor);
+
+ try {
+ out.writeLong(chrononTimeInMs);
+ } catch (IOException ex) {
+ throw new HyracksDataException(ex);
+ }
+ }
+ };
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
similarity index 62%
rename from asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java
rename to asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
index 5d43bba..b176061 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParser.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ADurationParserFactory.java
@@ -14,9 +14,45 @@
*/
package edu.uci.ics.asterix.om.base.temporal;
-import edu.uci.ics.asterix.om.base.AMutableDuration;
+import java.io.DataOutput;
+import java.io.IOException;
-public class ADurationParser {
+import edu.uci.ics.asterix.om.base.AMutableDuration;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ADurationParserFactory implements IValueParserFactory {
+
+ public static final IValueParserFactory INSTANCE = new ADurationParserFactory();
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String durationErrorMessage = "Wrong Input Format for a Duration Value";
+
+ private ADurationParserFactory() {
+
+ }
+
+ @Override
+ public IValueParser createValueParser() {
+ final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+ final AMutableDuration aMutableDuration = new AMutableDuration(0, 0);
+ return new IValueParser() {
+
+ @Override
+ public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+ charArrayAccessor.reset(buffer, start, length);
+ parseDuration(charArrayAccessor, aMutableDuration);
+ try {
+ out.writeInt(aMutableDuration.getMonths());
+ out.writeLong(aMutableDuration.getMilliseconds());
+ } catch (IOException ex) {
+ throw new HyracksDataException(ex);
+ }
+ }
+ };
+ }
private enum State {
NOTHING_READ,
@@ -30,9 +66,8 @@
SEC;
};
- private static final String errorMessage = "This can not be an instance of duration";
-
- public static <T> void parse(ICharSequenceAccessor<T> charAccessor, AMutableDuration aDuration) throws Exception {
+ public static <T> void parseDuration(ICharSequenceAccessor<T> charAccessor, AMutableDuration aDuration)
+ throws HyracksDataException {
boolean positive = true;
int offset = 0;
@@ -45,7 +80,7 @@
}
if (charAccessor.getCharAt(offset++) != 'P') {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": Missing leading 'P'.");
}
for (; offset < charAccessor.getLength(); offset++) {
@@ -59,7 +94,7 @@
year = value;
state = State.YEAR;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong YEAR feild.");
}
break;
case 'M':
@@ -68,13 +103,13 @@
month = value;
state = State.MONTH;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong MONTH field.");
}
} else if (state.compareTo(State.MIN) < 0) {
minute = value;
state = State.MIN;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong MIN field.");
}
break;
case 'D':
@@ -82,14 +117,14 @@
day = value;
state = State.DAY;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong DAY field");
}
break;
case 'T':
if (state.compareTo(State.TIME) < 0) {
state = State.TIME;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong TIME field.");
}
break;
@@ -98,7 +133,7 @@
hour = value;
state = State.HOUR;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong HOUR field.");
}
break;
case '.':
@@ -110,7 +145,8 @@
if (i < 4) {
millisecond = millisecond * 10 + (charAccessor.getCharAt(offset + i) - '0');
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage
+ + ": wrong MILLISECOND field.");
}
} else {
break;
@@ -119,18 +155,18 @@
offset += i;
state = State.MILLISEC;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong MILLISECOND field.");
}
case 'S':
if (state.compareTo(State.SEC) < 0) {
second = value;
state = State.SEC;
} else {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong SECOND field.");
}
break;
default:
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": wrong format for duration.");
}
value = 0;
@@ -138,7 +174,7 @@
}
if (state.compareTo(State.TIME) == 0) {
- throw new Exception(errorMessage);
+ throw new HyracksDataException(durationErrorMessage + ": no time fields after time separator.");
}
short temp = 1;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
new file mode 100644
index 0000000..d76f41d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base.temporal;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParser;
+import edu.uci.ics.hyracks.dataflow.common.data.parsers.IValueParserFactory;
+
+public class ATimeParserFactory implements IValueParserFactory {
+
+ public static final IValueParserFactory INSTANCE = new ATimeParserFactory();
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String timeErrorMessage = "Wrong Input Format for a Time Value";
+
+ private ATimeParserFactory() {
+
+ }
+
+ @Override
+ public IValueParser createValueParser() {
+
+ final CharArrayCharSequenceAccessor charArrayAccessor = new CharArrayCharSequenceAccessor();
+
+ return new IValueParser() {
+
+ @Override
+ public void parse(char[] buffer, int start, int length, DataOutput out) throws HyracksDataException {
+ charArrayAccessor.reset(buffer, start, length);
+ try {
+ out.writeInt(parseTimePart(charArrayAccessor));
+ } catch (IOException ex) {
+ throw new HyracksDataException(ex);
+ }
+ }
+ };
+ }
+
+ /**
+ * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
+ *
+ * @param charAccessor
+ * @return
+ * @throws Exception
+ */
+ public static <T> int parseTimePart(ICharSequenceAccessor<T> charAccessor) throws HyracksDataException {
+
+ int length = charAccessor.getLength();
+ int offset = 0;
+
+ int hour = 0, min = 0, sec = 0, millis = 0;
+ int timezone = 0;
+
+ boolean isExtendedForm = false;
+ if (charAccessor.getCharAt(offset + 2) == ':') {
+ isExtendedForm = true;
+ }
+
+ if (isExtendedForm && (charAccessor.getCharAt(offset + 2) != ':' || charAccessor.getCharAt(offset + 5) != ':')) {
+ throw new HyracksDataException(timeErrorMessage + ": Missing colon in an extended time format.");
+ }
+ // hour
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+ hour = hour * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in hour field");
+ }
+ }
+
+ if (hour < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.HOUR.ordinal()]
+ || hour > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.HOUR.ordinal()]) {
+ throw new HyracksDataException(timeErrorMessage + ": hour " + hour);
+ }
+
+ offset += (isExtendedForm) ? 3 : 2;
+
+ // minute
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+ min = min * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in minute field");
+ }
+ }
+
+ if (min < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]
+ || min > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.MINUTE.ordinal()]) {
+ throw new HyracksDataException(timeErrorMessage + ": min " + min);
+ }
+
+ offset += (isExtendedForm) ? 3 : 2;
+
+ // second
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9')) {
+ sec = sec * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in second field");
+ }
+ }
+
+ if (sec < GregorianCalendarSystem.FIELD_MINS[GregorianCalendarSystem.Fields.SECOND.ordinal()]
+ || sec > GregorianCalendarSystem.FIELD_MAXS[GregorianCalendarSystem.Fields.SECOND.ordinal()]) {
+ throw new HyracksDataException(timeErrorMessage + ": sec " + sec);
+ }
+
+ offset += 2;
+
+ if ((isExtendedForm && length > offset && charAccessor.getCharAt(offset) == '.')
+ || (!isExtendedForm && length > offset)) {
+
+ offset += (isExtendedForm) ? 1 : 0;
+ int i = 0;
+ for (; i < 3 && offset + i < length; i++) {
+ if (charAccessor.getCharAt(offset + i) >= '0' && charAccessor.getCharAt(offset + i) <= '9') {
+ millis = millis * 10 + charAccessor.getCharAt(offset + i) - '0';
+ } else {
+ break;
+ }
+ }
+
+ offset += i;
+
+ for (; i < 3; i++) {
+ millis = millis * 10;
+ }
+
+ // error is thrown if more than three digits are seen for the millisecond part
+ if (charAccessor.getLength() > offset && charAccessor.getCharAt(offset) >= '0'
+ && charAccessor.getCharAt(offset) <= '9') {
+ throw new HyracksDataException(timeErrorMessage + ": too many fields for millisecond.");
+ }
+ }
+
+ if (length > offset) {
+ timezone = parseTimezonePart(charAccessor, offset);
+ }
+
+ return GregorianCalendarSystem.getInstance().getChronon(hour, min, sec, millis, timezone);
+ }
+
+ /**
+ * Parse the given char sequence as a time string, and return the milliseconds represented by the time.
+ *
+ * @param charAccessor
+ * @return
+ * @throws Exception
+ */
+ public static <T> int parseTimezonePart(ICharSequenceAccessor<T> charAccessor, int offset)
+ throws HyracksDataException {
+ int timezone = 0;
+
+ if (charAccessor.getCharAt(offset) != 'Z') {
+ if ((charAccessor.getCharAt(offset) != '+' && charAccessor.getCharAt(offset) != '-')) {
+ throw new HyracksDataException("Wrong timezone format: missing sign or missing colon for a time zone");
+ }
+
+ short timezoneHour = 0;
+ short timezoneMinute = 0;
+
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + 1 + i) >= '0' && charAccessor.getCharAt(offset + 1 + i) <= '9')) {
+ timezoneHour = (short) (timezoneHour * 10 + charAccessor.getCharAt(offset + 1 + i) - '0');
+ } else {
+ throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in timezone hour field");
+ }
+ }
+
+ if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
+ || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
+ throw new HyracksDataException(timeErrorMessage + ": time zone hour " + timezoneHour);
+ }
+
+ int temp_offset = (charAccessor.getCharAt(offset + 3) == ':') ? 1 : 0;
+
+ for (int i = 0; i < 2; i++) {
+ if ((charAccessor.getCharAt(offset + temp_offset + 3 + i) >= '0' && charAccessor.getCharAt(offset
+ + temp_offset + 3 + i) <= '9')) {
+ timezoneMinute = (short) (timezoneMinute * 10
+ + charAccessor.getCharAt(offset + temp_offset + 3 + i) - '0');
+ } else {
+ throw new HyracksDataException(timeErrorMessage + ": Non-numeric value in timezone minute field");
+ }
+ }
+
+ if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
+ || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
+ throw new HyracksDataException(timeErrorMessage + ": time zone minute " + timezoneMinute);
+ }
+
+ if (charAccessor.getCharAt(offset) == '-') {
+ timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
+ } else {
+ timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ }
+ }
+ return timezone;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java
index e1a2135..453c86f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ByteArrayCharSequenceAccessor.java
@@ -14,27 +14,41 @@
*/
package edu.uci.ics.asterix.om.base.temporal;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+
public class ByteArrayCharSequenceAccessor implements ICharSequenceAccessor<Byte[]> {
- private byte[] string;
+ private byte[] buf;
private int offset;
- private int beginOffset;
+ private int length;
@Override
- public char getCharAt(int index) {
- return (char) (string[index + offset + beginOffset]);
+ public char getCharAt(int index) throws AsterixRuntimeException {
+ if (index < 0 || index >= length) {
+ throw new AsterixRuntimeException("Byte array char accessor is out of bound: " + index + ":" + length);
+ }
+ return (char) (buf[index + offset]);
}
- /* The offset is the position of the first letter in the byte array */
- public void reset(byte[] obj, int beginOffset, int offset) {
- string = obj;
+ /**
+ * Reset the wrapped byte array.
+ *
+ * @param obj
+ * The byte array to be wrapped
+ * @param beginOffset
+ * The offset of the string stored in the byte array.
+ * @param offset
+ * The offset of the substring of the string stored (offset from the beginOffset).
+ */
+ public void reset(byte[] obj, int offset, int length) {
+ this.buf = obj;
this.offset = offset;
- this.beginOffset = beginOffset;
+ this.length = length;
}
@Override
public int getLength() {
- return ((string[beginOffset - 2] & 0xff) << 8) + ((string[beginOffset - 1] & 0xff) << 0) - offset;
+ return length;
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java
new file mode 100644
index 0000000..404f0ee
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/CharArrayCharSequenceAccessor.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base.temporal;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+
+public class CharArrayCharSequenceAccessor implements ICharSequenceAccessor<char[]> {
+
+ private char[] buf;
+ private int offset;
+ private int length;
+
+ @Override
+ public char getCharAt(int index) throws AsterixRuntimeException {
+ if (index < 0 || index >= length) {
+ throw new AsterixRuntimeException("Byte array char accessor is out of bound: " + index + ":" + length);
+ }
+ return (char) (buf[index + offset]);
+ }
+
+ /**
+ * Reset the wrapped byte array.
+ *
+ * @param obj
+ * The byte array to be wrapped
+ * @param beginOffset
+ * The offset of the string stored in the byte array.
+ * @param offset
+ * The offset of the substring of the string stored (offset from the beginOffset).
+ */
+ public void reset(char[] obj, int offset, int length) {
+ this.buf = obj;
+ this.offset = offset;
+ this.length = length;
+ }
+
+ @Override
+ public int getLength() {
+ return length;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java
new file mode 100644
index 0000000..9d6bc2f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.base.temporal;
+
+/**
+ * Algorithms for duration related arithmetic operations.
+ */
+public class DurationArithmeticOperations {
+
+ private final static GregorianCalendarSystem calSystem = GregorianCalendarSystem.getInstance();
+
+ /**
+ * Add a duration (with yearMonth and dayTime) onto a time point. The algorithm works as described in
+ * <a
+ * href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">"XML: adding durations to dateTimes"</a>.
+ * <p/>
+ * The basic algorithm is like this: duration is applied to the time point as two separated fields: year-month field
+ * and day-time field. Year-month field is applied firstly by reserving the correct day within the month's range
+ * (for example add 1M to 03-31 will return 04-30). Then day-time field is applied.
+ * <p/>
+ *
+ * @param pointChronon
+ * @param yearMonthDuration
+ * @param dayTimeDuration
+ * @return
+ */
+ public static long addDuration(long pointChronon, int yearMonthDuration, long dayTimeDuration) {
+
+ int year = calSystem.getYear(pointChronon);
+ int month = calSystem.getMonthOfYear(pointChronon, year);
+ int day = calSystem.getDayOfMonthYear(pointChronon, year, month);
+ int hour = calSystem.getHourOfDay(pointChronon);
+ int min = calSystem.getMinOfHour(pointChronon);
+ int sec = calSystem.getSecOfMin(pointChronon);
+ int ms = calSystem.getMillisOfSec(pointChronon);
+
+ // Apply the year-month duration
+ int carry = yearMonthDuration / 12;
+ month += (yearMonthDuration % 12);
+
+ if (month < 0) {
+ month += 12;
+ carry -= 1;
+ } else if (month > 12) {
+ month -= 12;
+ carry += 1;
+ }
+
+ year += carry;
+
+ boolean isLeapYear = calSystem.isLeapYear(year);
+
+ if (isLeapYear) {
+ if (day > GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1]) {
+ day = GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1];
+ }
+ } else {
+ if (day > GregorianCalendarSystem.DAYS_OF_MONTH_LEAP[month - 1]) {
+ day = GregorianCalendarSystem.DAYS_OF_MONTH_LEAP[month - 1];
+ }
+ }
+
+ return calSystem.getChronon(year, month, day, hour, min, sec, ms, 0) + dayTimeDuration;
+ }
+
+ public static int addDuration(int pointChronon, long dayTimeDuration) {
+ int rtnChronon = (int) ((pointChronon + dayTimeDuration) % GregorianCalendarSystem.CHRONON_OF_DAY);
+ if (rtnChronon < 0) {
+ rtnChronon += GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
+
+ return rtnChronon;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
index 149a1d2..d43f235 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -57,6 +57,7 @@
public static final int CHRONON_OF_MINUTE = 60 * CHRONON_OF_SECOND;
public static final int CHRONON_OF_HOUR = 60 * CHRONON_OF_MINUTE;
public static final long CHRONON_OF_DAY = 24 * CHRONON_OF_HOUR;
+ public static final int MONTHS_IN_A_YEAR = 12;
/**
* Minimum feasible value of each field
@@ -238,8 +239,25 @@
return chrononTime;
}
+ public long adjustChrononByTimezone(long chronon, int timezone) {
+ return chronon + timezone / 4 * CHRONON_OF_HOUR + (timezone % 4) * 15 * CHRONON_OF_MINUTE;
+ }
+
+ public static int getChrononInDays(long chronon) {
+ if (chronon >= 0) {
+ return (int) (chronon / CHRONON_OF_DAY);
+ } else {
+ if (chronon % CHRONON_OF_DAY != 0) {
+ return (int) (chronon / CHRONON_OF_DAY - 1);
+ } else {
+ return (int) (chronon / CHRONON_OF_DAY);
+ }
+ }
+ }
+
/**
- * Get the extended string representation of the given UTC chronon time under the given time zone. Only fields before
+ * Get the extended string representation of the given UTC chronon time under the given time zone. Only fields
+ * before
* the given field index will be returned.
* <p/>
* The extended string representation is like:<br/>
@@ -258,6 +276,7 @@
switch (startField) {
case YEAR:
+ default:
sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
if (untilField == Fields.YEAR) {
return;
@@ -304,10 +323,13 @@
break;
}
- if (untilField.compareTo(Fields.DAY) > 0) {
+ if (timezone == 0) {
sbder.append("Z");
} else {
short tzMin = (short) ((timezone % 4) * 15);
+ if (tzMin < 0) {
+ tzMin = (short) (-1 * tzMin);
+ }
short tzHr = (short) (timezone / 4);
sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr))).append(":")
.append(String.format("%02d", tzMin));
@@ -328,6 +350,7 @@
switch (startField) {
case YEAR:
+ default:
sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
if (untilField == Fields.YEAR) {
return;
@@ -359,10 +382,13 @@
break;
}
- if (untilField.compareTo(Fields.DAY) > 0) {
+ if (timezone == 0) {
sbder.append("Z");
} else {
short tzMin = (short) ((timezone % 4) * 15);
+ if (tzMin < 0) {
+ tzMin = (short) (-1 * tzMin);
+ }
short tzHr = (short) (timezone / 4);
sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
.append(String.format("%02d", tzMin));
@@ -422,7 +448,7 @@
* @param year
* @return
*/
- protected boolean isLeapYear(int year) {
+ public boolean isLeapYear(int year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
@@ -454,7 +480,8 @@
* Get the year for the given chronon time.
* <p/>
* This code is directly from the Joda library BadicChronology.java.<br/>
- * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+ * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May
+ * 7th, 2012.
*
* @param chrononTime
* @return
@@ -501,7 +528,8 @@
* Get the month of the year for the given chronon time and the year.
* <p/>
* This code is directly from the Joda library BasicGJChronology.java.<br/>
- * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+ * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May
+ * 7th, 2012 and commented by Theodoros Ioannou on July 2012.
* <p/>
*
* @param millis
@@ -565,7 +593,8 @@
* Get the day of the given month and year for the input chronon time.
* <p/>
* This function is directly from Joda Library BasicChronology.java.<br/>
- * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May 7th, 2012.
+ * The original authers are Stephen Colebourne, Brain S O'Neill and Guy Allard, and modified by JArod Wen on May
+ * 7th, 2012.
* <p/>
*
* @param millis
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java
index 6b4e898..d5a99a0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ICharSequenceAccessor.java
@@ -14,10 +14,23 @@
*/
package edu.uci.ics.asterix.om.base.temporal;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+
public interface ICharSequenceAccessor<T> {
- public char getCharAt(int index);
+ /**
+ * Return the character in the wrapped char sequence at the given index.
+ *
+ * @param index
+ * @return
+ */
+ public char getCharAt(int index) throws AsterixRuntimeException;
+ /**
+ * Get the length of the wrapped char sequence.
+ *
+ * @return
+ */
public int getLength();
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java
index 6c02340..17e483a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/StringCharSequenceAccessor.java
@@ -14,24 +14,31 @@
*/
package edu.uci.ics.asterix.om.base.temporal;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
+
public class StringCharSequenceAccessor implements ICharSequenceAccessor<String> {
private String string;
private int offset;
+ private int length;
@Override
- public char getCharAt(int index) {
+ public char getCharAt(int index) throws AsterixRuntimeException {
+ if (index >= length) {
+ throw new AsterixRuntimeException("String accessor is out of bound.");
+ }
return string.charAt(index + offset);
}
- public void reset(String obj, int offset) {
- string = obj;
+ public void reset(String obj, int offset, int len) {
+ this.string = obj;
this.offset = offset;
+ this.length = len;
}
@Override
public int getLength() {
- return string.length() - offset;
+ return length;
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index 42904fc..a547737 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -12,6 +12,8 @@
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.ABooleanTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.ACircleTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.ADateTimeTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.ADateTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.ADoubleTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AFloatTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AInt32TypeComputer;
@@ -21,6 +23,7 @@
import edu.uci.ics.asterix.om.typecomputer.impl.APolygonTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.ARectangleTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AStringTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.ATimeTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.BinaryBooleanOrNullFunctionTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.BinaryStringBoolOrNullTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.BinaryStringStringOrNullTypeComputer;
@@ -38,7 +41,9 @@
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSumTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSwitchCaseComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedUnaryMinusTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.NotNullTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OpenRecordConstructorResultType;
+import edu.uci.ics.asterix.om.typecomputer.impl.OptionalABooleanTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalACircleTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalADateTimeTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalADateTypeComputer;
@@ -49,6 +54,7 @@
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAInt32TypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAInt64TypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAInt8TypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAIntervalTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalALineTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAPoint3DTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.OptionalAPointTypeComputer;
@@ -235,11 +241,14 @@
public final static FunctionIdentifier AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-avg", 1);
public final static FunctionIdentifier COUNT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-count", 1);
public final static FunctionIdentifier SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-sum", 1);
- public final static FunctionIdentifier LOCAL_SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-sum", 1);
+ public final static FunctionIdentifier LOCAL_SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "agg-local-sum", 1);
public final static FunctionIdentifier MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-max", 1);
- public final static FunctionIdentifier LOCAL_MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-max", 1);
+ public final static FunctionIdentifier LOCAL_MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "agg-local-max", 1);
public final static FunctionIdentifier MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-min", 1);
- public final static FunctionIdentifier LOCAL_MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-min", 1);
+ public final static FunctionIdentifier LOCAL_MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "agg-local-min", 1);
public final static FunctionIdentifier GLOBAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"agg-global-avg", 1);
public final static FunctionIdentifier LOCAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -270,8 +279,6 @@
public final static FunctionIdentifier SERIAL_LOCAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"local-avg-serial", 1);
- public final static FunctionIdentifier YEAR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "year", 1);
-
public final static FunctionIdentifier SCAN_COLLECTION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"scan-collection", 1);
public final static FunctionIdentifier SUBSET_COLLECTION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -363,6 +370,49 @@
"datetime", 1);
public final static FunctionIdentifier DURATION_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"duration", 1);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_DATE = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-from-date", 2);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_TIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-from-time", 2);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_DATETIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-from-datetime", 2);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_START_FROM_DATE = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-start-from-date", 2);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_START_FROM_TIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-start-from-time", 2);
+ public final static FunctionIdentifier INTERVAL_CONSTRUCTOR_START_FROM_DATETIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-start-from-datetime", 2);
+ public final static FunctionIdentifier INTERVAL_BEFORE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-before", 2);
+ public final static FunctionIdentifier INTERVAL_AFTER = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-after", 2);
+ public final static FunctionIdentifier INTERVAL_MEETS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-meets", 2);
+ public final static FunctionIdentifier INTERVAL_MET_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-met-by", 2);
+ public final static FunctionIdentifier INTERVAL_OVERLAPS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-overlaps", 2);
+ public final static FunctionIdentifier INTERVAL_OVERLAPPED_BY = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "interval-overlapped-by", 2);
+ public final static FunctionIdentifier OVERLAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "overlap", 2);
+ public final static FunctionIdentifier INTERVAL_STARTS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-starts", 2);
+ public final static FunctionIdentifier INTERVAL_STARTED_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-started-by", 2);
+ public final static FunctionIdentifier INTERVAL_COVERS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-covers", 2);
+ public final static FunctionIdentifier INTERVAL_COVERED_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-covered-by", 2);
+ public final static FunctionIdentifier INTERVAL_ENDS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-ends", 2);
+ public final static FunctionIdentifier INTERVAL_ENDED_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-ended-by", 2);
+ public final static FunctionIdentifier CURRENT_TIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "current-time", 0);
+ public final static FunctionIdentifier CURRENT_DATE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "current-date", 0);
+ public final static FunctionIdentifier CURRENT_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "current-datetime", 0);
// spatial
public final static FunctionIdentifier CREATE_POINT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -394,6 +444,56 @@
public final static FunctionIdentifier CAST_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"cast-record", 1);
+ // Spatial and temporal type accessors
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_YEAR = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "year", 1);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_MONTH = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "month", 2);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_DAY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "day", 1);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_HOUR = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "hour", 1);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "minute", 1);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_SEC = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "second", 1);
+ public static final FunctionIdentifier ACCESSOR_TEMPORAL_MILLISEC = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "millisecond", 1);
+
+ // Temporal functions
+ public static final FunctionIdentifier DATE_FROM_UNIX_TIME_IN_DAYS = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "date-from-unix-time-in-days", 1);
+ public static final FunctionIdentifier DATE_FROM_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "date-from-datetime", 1);
+ public final static FunctionIdentifier ADD_DATE_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "add-date-duration", 2);
+ public final static FunctionIdentifier SUBTRACT_DATE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "subtract-date", 2);
+ public final static FunctionIdentifier TIME_FROM_UNIX_TIME_IN_MS = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "time-from-unix-time-in-ms", 1);
+ public final static FunctionIdentifier TIME_FROM_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "time-from-datetime", 1);
+ public final static FunctionIdentifier SUBTRACT_TIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "subtract-time", 2);
+ public final static FunctionIdentifier ADD_TIME_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "add-time-duration", 2);
+ public final static FunctionIdentifier DATETIME_FROM_UNIX_TIME_IN_MS = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "datetime-from-unix-time-in-ms", 1);
+ public final static FunctionIdentifier DATETIME_FROM_DATE_TIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "datetime-from-date-time", 2);
+ public final static FunctionIdentifier SUBTRACT_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "subtract-datetime", 2);
+ public final static FunctionIdentifier ADD_DATETIME_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "add-datetime-duration", 2);
+ public final static FunctionIdentifier CALENDAR_DURATION_FROM_DATETIME = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "calendar-duration-from-datetime", 2);
+ public final static FunctionIdentifier CALENDAR_DURATION_FROM_DATE = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "calendar-duration-from-date", 2);
+ public final static FunctionIdentifier ADJUST_TIME_FOR_TIMEZONE = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "adjust-time-for-timezone", 2);
+ public final static FunctionIdentifier ADJUST_DATETIME_FOR_TIMEZONE = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "adjust-datetime-for-timezone", 2);
+
public final static FunctionIdentifier GET_POINT_X_COORDINATE_ACCESSOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-x", 1);
public final static FunctionIdentifier GET_POINT_Y_COORDINATE_ACCESSOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-y", 1);
public final static FunctionIdentifier GET_CIRCLE_RADIUS_ACCESSOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-radius", 1);
@@ -412,6 +512,9 @@
public static final FunctionIdentifier NUMERIC_ADD = AlgebricksBuiltinFunctions.NUMERIC_ADD;
public static final FunctionIdentifier IS_NULL = AlgebricksBuiltinFunctions.IS_NULL;
+ public static final FunctionIdentifier NOT_NULL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "not-null",
+ 1);
+
public static IFunctionInfo getAsterixFunctionInfo(FunctionIdentifier fid) {
IFunctionInfo finfo = finfoRepo.get(fid);;
if (finfo == null) {
@@ -440,6 +543,7 @@
add(NUMERIC_ADD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
// and then, Asterix builtin functions
+ add(NOT_NULL, NotNullTypeComputer.INSTANCE);
add(ANY_COLLECTION_MEMBER, NonTaggedCollectionMemberResultType.INSTANCE);
addPrivateFunction(AVG, OptionalADoubleTypeComputer.INSTANCE);
add(BOOLEAN_CONSTRUCTOR, UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
@@ -648,7 +752,6 @@
add(TIME_CONSTRUCTOR, OptionalATimeTypeComputer.INSTANCE);
add(TYPE_OF, null); // TODO
add(UNORDERED_LIST_CONSTRUCTOR, UnorderedListConstructorResultType.INSTANCE);
- add(YEAR, OptionalAInt32TypeComputer.INSTANCE);
add(WORD_TOKENS, new IResultTypeComputer() {
@Override
@@ -658,12 +761,64 @@
}
});
+ // temporal type accessors
+ add(ACCESSOR_TEMPORAL_YEAR, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_MONTH, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_DAY, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_HOUR, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_MIN, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_SEC, OptionalAInt32TypeComputer.INSTANCE);
+ add(ACCESSOR_TEMPORAL_MILLISEC, OptionalAInt32TypeComputer.INSTANCE);
+
+ // temporal functions
+ add(DATE_FROM_UNIX_TIME_IN_DAYS, OptionalADateTypeComputer.INSTANCE);
+ add(DATE_FROM_DATETIME, OptionalADateTypeComputer.INSTANCE);
+ add(ADD_DATE_DURATION, OptionalADateTypeComputer.INSTANCE);
+ add(SUBTRACT_DATE, OptionalADurationTypeComputer.INSTANCE);
+ add(TIME_FROM_UNIX_TIME_IN_MS, OptionalATimeTypeComputer.INSTANCE);
+ add(TIME_FROM_DATETIME, OptionalATimeTypeComputer.INSTANCE);
+ add(SUBTRACT_TIME, OptionalADurationTypeComputer.INSTANCE);
+ add(ADD_TIME_DURATION, OptionalATimeTypeComputer.INSTANCE);
+ add(DATETIME_FROM_DATE_TIME, OptionalADateTimeTypeComputer.INSTANCE);
+ add(DATETIME_FROM_UNIX_TIME_IN_MS, OptionalADateTimeTypeComputer.INSTANCE);
+ add(SUBTRACT_DATETIME, OptionalADurationTypeComputer.INSTANCE);
+ add(ADD_DATETIME_DURATION, OptionalADateTimeTypeComputer.INSTANCE);
+ add(CALENDAR_DURATION_FROM_DATETIME, OptionalADurationTypeComputer.INSTANCE);
+ add(CALENDAR_DURATION_FROM_DATE, OptionalADurationTypeComputer.INSTANCE);
+ add(ADJUST_DATETIME_FOR_TIMEZONE, OptionalAStringTypeComputer.INSTANCE);
+ add(ADJUST_TIME_FOR_TIMEZONE, OptionalAStringTypeComputer.INSTANCE);
+ add(INTERVAL_BEFORE, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_AFTER, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_MEETS, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_MET_BY, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_OVERLAPS, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_OVERLAPPED_BY, OptionalABooleanTypeComputer.INSTANCE);
+ add(OVERLAP, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_STARTS, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_STARTED_BY, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_COVERS, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_COVERED_BY, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_ENDS, OptionalABooleanTypeComputer.INSTANCE);
+ add(INTERVAL_ENDED_BY, OptionalABooleanTypeComputer.INSTANCE);
+ add(CURRENT_DATE, ADateTypeComputer.INSTANCE);
+ add(CURRENT_TIME, ATimeTypeComputer.INSTANCE);
+ add(CURRENT_DATETIME, ADateTimeTypeComputer.INSTANCE);
+
+ // interval constructors
+ add(INTERVAL_CONSTRUCTOR_DATE, OptionalAIntervalTypeComputer.INSTANCE);
+ add(INTERVAL_CONSTRUCTOR_TIME, OptionalAIntervalTypeComputer.INSTANCE);
+ add(INTERVAL_CONSTRUCTOR_DATETIME, OptionalAIntervalTypeComputer.INSTANCE);
+ add(INTERVAL_CONSTRUCTOR_START_FROM_DATE, OptionalAIntervalTypeComputer.INSTANCE);
+ add(INTERVAL_CONSTRUCTOR_START_FROM_DATETIME, OptionalAIntervalTypeComputer.INSTANCE);
+ add(INTERVAL_CONSTRUCTOR_START_FROM_TIME, OptionalAIntervalTypeComputer.INSTANCE);
+
String metadataFunctionLoaderClassName = "edu.uci.ics.asterix.metadata.functions.MetadataBuiltinFunctions";
try {
Class.forName(metadataFunctionLoaderClassName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
+
}
static {
@@ -840,7 +995,7 @@
funTypeComputer.put(functionInfo, typeComputer);
finfoRepo.put(fi);
}
-
+
private static IFunctionInfo addPrivateFunction(FunctionIdentifier fi, IResultTypeComputer typeComputer) {
IFunctionInfo functionInfo = getAsterixFunctionInfo(fi);
builtinFunctionsSet.put(functionInfo, functionInfo);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/base/DefaultOpenFieldType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/base/DefaultOpenFieldType.java
index 9184616..45ae5c5 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/base/DefaultOpenFieldType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/base/DefaultOpenFieldType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 by The Regents of the University of California
+ * Copyright 2009-2013 by The Regents of the University of California
* 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 from
@@ -15,6 +15,8 @@
package edu.uci.ics.asterix.om.pointables.base;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
import edu.uci.ics.asterix.om.types.AOrderedListType;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -27,13 +29,19 @@
* fields in the open part, e.g., a "record" (nested) field in the open part is
* always a fully open one, and a "list" field in the open part is always a list
* of "ANY".
- *
*/
public class DefaultOpenFieldType {
// nested open field rec type
- public static ARecordType NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {},
- new IAType[] {}, true);
+ public static ARecordType NESTED_OPEN_RECORD_TYPE;
+
+ static {
+ try {
+ NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {}, new IAType[] {}, true);
+ } catch (AsterixException e) {
+ throw new AsterixRuntimeException();
+ }
+ }
// nested open list type
public static AOrderedListType NESTED_OPEN_AORDERED_LIST_TYPE = new AOrderedListType(BuiltinType.ANY,
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/cast/ARecordCaster.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/cast/ARecordCaster.java
index fbad7a7..494ea6f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/cast/ARecordCaster.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/cast/ARecordCaster.java
@@ -15,9 +15,11 @@
package edu.uci.ics.asterix.om.pointables.cast;
+import java.io.ByteArrayOutputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@@ -28,6 +30,7 @@
import edu.uci.ics.asterix.om.pointables.PointableAllocator;
import edu.uci.ics.asterix.om.pointables.base.DefaultOpenFieldType;
import edu.uci.ics.asterix.om.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.om.pointables.printer.APrintVisitor;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.AUnionType;
@@ -35,6 +38,7 @@
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.asterix.om.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
@@ -184,7 +188,7 @@
}
private void matchClosedPart(List<IVisitablePointable> fieldNames, List<IVisitablePointable> fieldTypeTags,
- List<IVisitablePointable> fieldValues) {
+ List<IVisitablePointable> fieldValues) throws AsterixException {
// sort-merge based match
quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1);
int fnStart = 0;
@@ -213,8 +217,30 @@
// check unmatched fields in the input type
for (int i = 0; i < openFields.length; i++) {
- if (openFields[i] == true && !cachedReqType.isOpen())
- throw new IllegalStateException("type mismatch: including extra closed fields");
+ if (openFields[i] == true && !cachedReqType.isOpen()) {
+ //print the field name
+ IVisitablePointable fieldName = fieldNames.get(i);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(bos);
+ APrintVisitor printVisitor = new APrintVisitor();
+ Pair<PrintStream, ATypeTag> visitorArg = new Pair<PrintStream, ATypeTag>(ps, ATypeTag.STRING);
+ fieldName.accept(printVisitor, visitorArg);
+
+ //print the colon
+ ps.print(":");
+
+ //print the field type
+ IVisitablePointable fieldType = fieldTypeTags.get(i);
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(fieldType.getByteArray()[fieldType
+ .getStartOffset()]);
+ ps.print(typeTag);
+
+ //collect the output message
+ byte[] output = bos.toByteArray();
+
+ //throw the exception
+ throw new IllegalStateException("type mismatch: including an extra field " + new String(output));
+ }
}
// check unmatched fields in the required type
@@ -223,7 +249,8 @@
IAType t = cachedReqType.getFieldTypes()[i];
if (!(t.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) t))) {
// no matched field in the input for a required closed field
- throw new IllegalStateException("type mismatch: miss a required closed field");
+ throw new IllegalStateException("type mismatch: miss a required closed field "
+ + cachedReqType.getFieldNames()[i] + ":" + t.getTypeName());
}
}
}
@@ -288,8 +315,7 @@
int j = right;
while (true) {
// grow from the left
- while (compare(names.get(index[++i]), names.get(index[right])) < 0)
- ;
+ while (compare(names.get(index[++i]), names.get(index[right])) < 0);
// lower from the right
while (compare(names.get(index[right]), names.get(index[--j])) < 0)
if (j == left)
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ADateTimeTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ADateTimeTypeComputer.java
new file mode 100644
index 0000000..c7a51da
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ADateTimeTypeComputer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class ADateTimeTypeComputer implements IResultTypeComputer {
+
+ public static final ADateTimeTypeComputer INSTANCE = new ADateTimeTypeComputer();
+
+ private ADateTimeTypeComputer() {
+ }
+
+ @Override
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ return BuiltinType.ADATETIME;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ATimeTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ATimeTypeComputer.java
new file mode 100644
index 0000000..55e1bc4
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ATimeTypeComputer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class ATimeTypeComputer implements IResultTypeComputer {
+
+ public static final ATimeTypeComputer INSTANCE = new ATimeTypeComputer();
+
+ private ATimeTypeComputer() {
+ }
+
+ @Override
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ return BuiltinType.ATIME;
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
index daf7164..8ed2084 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 by The Regents of the University of California
+ * Copyright 2009-2013 by The Regents of the University of California
* 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 from
@@ -19,6 +19,7 @@
import org.apache.commons.lang3.mutable.Mutable;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
@@ -49,7 +50,7 @@
ARecordType type = (ARecordType) TypeComputerUtilities.getRequiredType(f);
if (type != null)
return type;
-
+
int n = f.getArguments().size() / 2;
String[] fieldNames = new String[n];
IAType[] fieldTypes = new IAType[n];
@@ -68,6 +69,10 @@
fieldTypes[i] = (IAType) env.getType(e2);
i++;
}
- return new ARecordType(null, fieldNames, fieldTypes, false);
+ try {
+ return new ARecordType(null, fieldNames, fieldTypes, false);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedLocalAvgTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedLocalAvgTypeComputer.java
index 8b54197..ee52425 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedLocalAvgTypeComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedLocalAvgTypeComputer.java
@@ -1,8 +1,24 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
import java.util.ArrayList;
import java.util.List;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.AUnionType;
@@ -23,7 +39,11 @@
List<IAType> unionList = new ArrayList<IAType>();
unionList.add(BuiltinType.ANULL);
unionList.add(BuiltinType.ADOUBLE);
- return new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
- new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+ try {
+ return new ARecordType(null, new String[] { "sum", "count" }, new IAType[] {
+ new AUnionType(unionList, "OptionalDouble"), BuiltinType.AINT32 }, false);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NotNullTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NotNullTypeComputer.java
new file mode 100644
index 0000000..a9881c2
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NotNullTypeComputer.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+/**
+ * This class is the type computer for not-null function.
+ * If the input type is not a union, we just return it.
+ * If the input type is a union,
+ * case 1: we return a new union without null if the new union still has more than one types;
+ * case 2: we return the non-null item type in the original union if there are only null and it in the original union.
+ */
+public class NotNullTypeComputer implements IResultTypeComputer {
+
+ public static final NotNullTypeComputer INSTANCE = new NotNullTypeComputer();
+
+ @Override
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
+ IAType type = (IAType) env.getType(f.getArguments().get(0).getValue());
+ if (type.getTypeTag() != ATypeTag.UNION) {
+ // directly return the input type if it is not a union
+ return type;
+ }
+
+ AUnionType unionType = (AUnionType) type;
+ List<IAType> items = new ArrayList<IAType>();
+ // copy the item types
+ items.addAll(unionType.getUnionList());
+
+ // remove null
+ for (int i = items.size() - 1; i >= 0; i--) {
+ IAType itemType = items.get(i);
+ if (itemType.getTypeTag() == ATypeTag.NULL) {
+ items.remove(i);
+ }
+ }
+ if (items.size() == 1) {
+ //only one type is left
+ return items.get(0);
+ } else {
+ //more than two types are left
+ return new AUnionType(items, unionType.getTypeName());
+ }
+ }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
index c46c59b..0c6fc55 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 by The Regents of the University of California
+ * Copyright 2009-2013 by The Regents of the University of California
* 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 from
@@ -21,6 +21,7 @@
import org.apache.commons.lang3.mutable.Mutable;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
@@ -72,6 +73,10 @@
IAType[] fieldTypes = new IAType[n];
fieldNames = namesList.toArray(fieldNames);
fieldTypes = typesList.toArray(fieldTypes);
- return new ARecordType(null, fieldNames, fieldTypes, true);
+ try {
+ return new ARecordType(null, fieldNames, fieldTypes, true);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalABooleanTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalABooleanTypeComputer.java
new file mode 100644
index 0000000..abeea2a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalABooleanTypeComputer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class OptionalABooleanTypeComputer implements IResultTypeComputer {
+
+ public static final OptionalABooleanTypeComputer INSTANCE = new OptionalABooleanTypeComputer();
+
+ private OptionalABooleanTypeComputer() {
+ }
+
+ @Override
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.ABOOLEAN);
+ return new AUnionType(unionList, "OptionalBoolean");
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalAIntervalTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalAIntervalTypeComputer.java
new file mode 100644
index 0000000..bb9f993
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OptionalAIntervalTypeComputer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class OptionalAIntervalTypeComputer implements IResultTypeComputer {
+
+ public static final OptionalAIntervalTypeComputer INSTANCE = new OptionalAIntervalTypeComputer();
+
+ private OptionalAIntervalTypeComputer() {
+
+ }
+
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ List<IAType> unionList = new ArrayList<IAType>();
+ unionList.add(BuiltinType.ANULL);
+ unionList.add(BuiltinType.AINTERVAL);
+ return new AUnionType(unionList, "OptionalInterval");
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/RecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/RecordConstructorResultType.java
index d20f43b..1f072f0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/RecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/RecordConstructorResultType.java
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.typecomputer.impl;
import java.util.Iterator;
import org.apache.commons.lang3.mutable.Mutable;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
@@ -58,6 +74,10 @@
}
i++;
}
- return new ARecordType(null, fieldNames, fieldTypes, isOpen);
+ try {
+ return new ARecordType(null, fieldNames, fieldTypes, isOpen);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
index 1cf6ba7..82320e4 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ARecordType.java
@@ -1,15 +1,38 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * 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 from
+ *
+ * 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 edu.uci.ics.asterix.om.types;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import edu.uci.ics.asterix.common.annotations.IRecordTypeAnnotation;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.om.base.IAObject;
import edu.uci.ics.asterix.om.visitors.IOMVisitor;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunction;
+import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
+import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryHashFunctionFactory;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+import edu.uci.ics.hyracks.data.std.util.ByteArrayAccessibleOutputStream;
+import edu.uci.ics.hyracks.dataflow.common.data.marshalling.UTF8StringSerializerDeserializer;
public class ARecordType extends AbstractComplexType {
@@ -18,16 +41,110 @@
private IAType[] fieldTypes;
private boolean isOpen;
private final List<IRecordTypeAnnotation> annotations = new ArrayList<IRecordTypeAnnotation>();
- private final Map<String, Integer> typeMap = new HashMap<String, Integer>();
- public ARecordType(String typeName, String[] fieldNames, IAType[] fieldTypes, boolean isOpen) {
+ private transient IBinaryHashFunction fieldNameHashFunction;
+ private transient IBinaryComparator fieldNameComparator;
+ private final byte serializedFieldNames[];
+ private final int serializedFieldNameOffsets[];
+ private final long hashCodeIndexPairs[];
+
+ /**
+ * @param typeName
+ * the name of the type
+ * @param fieldNames
+ * the names of the closed fields
+ * @param fieldTypes
+ * the types of the closed fields
+ * @param isOpen
+ * whether the record is open
+ * @throws AsterixException
+ * if there are duplicate field names or if there is an error serializing the field names
+ */
+ public ARecordType(String typeName, String[] fieldNames, IAType[] fieldTypes, boolean isOpen)
+ throws AsterixException {
super(typeName);
this.fieldNames = fieldNames;
this.fieldTypes = fieldTypes;
this.isOpen = isOpen;
+
+ fieldNameComparator = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+ .createBinaryComparator();
+ fieldNameHashFunction = new PointableBinaryHashFunctionFactory(UTF8StringPointable.FACTORY)
+ .createBinaryHashFunction();
+ ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
+ DataOutputStream dos = new DataOutputStream(baaos);
+ serializedFieldNameOffsets = new int[fieldNames.length];
+ hashCodeIndexPairs = new long[fieldNames.length];
+
+ int length = 0;
for (int i = 0; i < fieldNames.length; i++) {
- typeMap.put(fieldNames[i], i);
+ serializedFieldNameOffsets[i] = baaos.size();
+ try {
+ dos.writeUTF(fieldNames[i]);
+ } catch (IOException e) {
+ throw new AsterixException(e);
+ }
+ length = baaos.size() - serializedFieldNameOffsets[i];
+ hashCodeIndexPairs[i] = fieldNameHashFunction.hash(baaos.getByteArray(), serializedFieldNameOffsets[i],
+ length);
+ hashCodeIndexPairs[i] = hashCodeIndexPairs[i] << 32;
+ hashCodeIndexPairs[i] = hashCodeIndexPairs[i] | i;
}
+ serializedFieldNames = baaos.getByteArray();
+
+ Arrays.sort(hashCodeIndexPairs);
+ int j;
+ for (int i = 0; i < fieldNames.length; i++) {
+ j = findFieldPosition(serializedFieldNames, serializedFieldNameOffsets[i],
+ UTF8StringPointable.getStringLength(serializedFieldNames, serializedFieldNameOffsets[i]));
+ if (j != i) {
+ throw new AsterixException("Closed fields " + j + " and " + i + " have the same field name \""
+ + fieldNames[i] + "\"");
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+ ois.defaultReadObject();
+ fieldNameComparator = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+ .createBinaryComparator();
+ fieldNameHashFunction = new PointableBinaryHashFunctionFactory(UTF8StringPointable.FACTORY)
+ .createBinaryHashFunction();
+ }
+
+ /**
+ * Returns the position of the field in the closed schema or -1 if the field does not exist.
+ *
+ * @param bytes
+ * the serialized bytes of the field name
+ * @param start
+ * the starting offset of the field name in bytes
+ * @param length
+ * the length of the field name in bytes
+ * @return the position of the field in the closed schema or -1 if the field does not exist.
+ */
+ public int findFieldPosition(byte[] bytes, int start, int length) {
+ if (hashCodeIndexPairs.length == 0) {
+ return -1;
+ }
+
+ int fIndex;
+ int probeFieldHash = fieldNameHashFunction.hash(bytes, start, length);
+ int i = Arrays.binarySearch(hashCodeIndexPairs, ((long) probeFieldHash) << 32);
+ i = (i < 0) ? (i = -1 * (i + 1)) : i;
+
+ while (i < hashCodeIndexPairs.length && (int) (hashCodeIndexPairs[i] >>> 32) == probeFieldHash) {
+ fIndex = (int) hashCodeIndexPairs[i];
+ int cFieldLength = UTF8StringPointable.getStringLength(serializedFieldNames,
+ serializedFieldNameOffsets[fIndex]);
+ if (fieldNameComparator.compare(serializedFieldNames, serializedFieldNameOffsets[fIndex], cFieldLength,
+ bytes, start, length) == 0) {
+ return fIndex;
+ }
+ i++;
+ }
+
+ return -1;
}
public final String[] getFieldNames() {
@@ -73,17 +190,48 @@
return isOpen;
}
- public int findFieldPosition(String fldName) {
- for (int i = 0; i < fieldNames.length; i++) {
- if (fieldNames[i].equals(fldName)) {
- return i;
- }
- }
- return -1;
+ /**
+ * Returns the position of the field in the closed schema or -1 if the field does not exist.
+ *
+ * @param fieldName
+ * the name of the field whose position is sought
+ * @return the position of the field in the closed schema or -1 if the field does not exist.
+ */
+ public int findFieldPosition(String fieldName) throws IOException {
+ ByteArrayAccessibleOutputStream baaos = new ByteArrayAccessibleOutputStream();
+ DataOutputStream dos = new DataOutputStream(baaos);
+ UTF8StringSerializerDeserializer.INSTANCE.serialize(fieldName, dos);
+ return findFieldPosition(baaos.getByteArray(), 0, baaos.getByteArray().length);
}
- public IAType getFieldType(String fieldName) {
- return fieldTypes[typeMap.get(fieldName)];
+ /**
+ * Returns the field type of the field name if it exists, otherwise null.
+ *
+ * @param fieldName
+ * the fieldName whose type is sought
+ * @return the field type of the field name if it exists, otherwise null
+ * @throws IOException
+ * if an error occurs while serializing the field name
+ */
+ public IAType getFieldType(String fieldName) throws IOException {
+ int fieldPos = findFieldPosition(fieldName);
+ if (fieldPos < 0 || fieldPos >= fieldTypes.length) {
+ return null;
+ }
+ return fieldTypes[fieldPos];
+ }
+
+ /**
+ * Returns true or false indicating whether or not a field is closed.
+ *
+ * @param fieldName
+ * the name of the field to check
+ * @return true if fieldName is a closed field, otherwise false
+ * @throws IOException
+ * if an error occurs while serializing fieldName
+ */
+ public boolean isClosedField(String fieldName) throws IOException {
+ return findFieldPosition(fieldName) != -1;
}
@Override
@@ -115,12 +263,11 @@
public int hash() {
int h = 0;
for (int i = 0; i < fieldNames.length; i++) {
- h += 31 * h + fieldNames[i].hashCode();
+ h += 31 * h + (int) (hashCodeIndexPairs[i] >> 32);
}
for (int i = 0; i < fieldTypes.length; i++) {
h += 31 * h + fieldTypes[i].hashCode();
}
return h;
}
-
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
index b75c074..e69fbcd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/ATypeTag.java
@@ -42,6 +42,7 @@
LINE(30),
POLYGON(31),
CIRCLE(32),
+ INTERVAL(34),
RECTANGLE(33),
SYSTEM_NULL(34);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/BuiltinType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/BuiltinType.java
index 0ec3b21..4d9cd7f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/BuiltinType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/types/BuiltinType.java
@@ -329,6 +329,27 @@
};
+ public final static BuiltinType AINTERVAL = new LowerCaseConstructorType() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String getDisplayName() {
+ return "AInterval";
+ }
+
+ @Override
+ public ATypeTag getTypeTag() {
+ return ATypeTag.INTERVAL;
+ }
+
+ @Override
+ public String getTypeName() {
+ return "interval";
+ }
+
+ };
+
public final static BuiltinType APOINT = new LowerCaseConstructorType() {
private static final long serialVersionUID = 1L;
@@ -515,25 +536,25 @@
return getTypeTag().toString();
}
- @Override
- public boolean deepEqual(IAObject obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof BuiltinType)) {
- return false;
- }
- return ((BuiltinType) obj).getTypeTag().equals(getTypeTag());
- }
+ @Override
+ public boolean deepEqual(IAObject obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof BuiltinType)) {
+ return false;
+ }
+ return ((BuiltinType) obj).getTypeTag().equals(getTypeTag());
+ }
@Override
public boolean equals(Object object) {
return this.deepEqual((IAObject) object);
}
-
+
@Override
public int hashCode() {
- return getTypeTag().hashCode();
+ return getTypeTag().hashCode();
}
@Override
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/AsterixRuntimeUtil.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/AsterixRuntimeUtil.java
index 624d7eb..76f3301 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/AsterixRuntimeUtil.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/AsterixRuntimeUtil.java
@@ -18,39 +18,51 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import edu.uci.ics.asterix.common.api.AsterixAppContextInfoImpl;
-import edu.uci.ics.asterix.common.exceptions.AsterixException;
+/**
+ * Utility class for obtaining information on the set of Hyracks NodeController
+ * processes that are running on a given host.
+ */
public class AsterixRuntimeUtil {
- public static Set<String> getNodeControllersOnIP(String ipAddress) throws AsterixException {
- Map<String, Set<String>> nodeControllerInfo = AsterixAppContextInfoImpl.getNodeControllerMap();
- Set<String> nodeControllersAtLocation = nodeControllerInfo.get(ipAddress);
- return nodeControllersAtLocation;
- }
+ public static Set<String> getNodeControllersOnIP(String ipAddress)
+ throws Exception {
+ Map<String, Set<String>> nodeControllerInfo = getNodeControllerMap();
+ Set<String> nodeControllersAtLocation = nodeControllerInfo
+ .get(ipAddress);
+ return nodeControllersAtLocation;
+ }
- public static Set<String> getNodeControllersOnHostName(String hostName) throws UnknownHostException {
- Map<String, Set<String>> nodeControllerInfo = AsterixAppContextInfoImpl.getNodeControllerMap();
- String address;
- address = InetAddress.getByName(hostName).getHostAddress();
- if (address.equals("127.0.1.1")) {
- address = "127.0.0.1";
- }
- Set<String> nodeControllersAtLocation = nodeControllerInfo.get(address);
- return nodeControllersAtLocation;
- }
+ public static List<String> getAllNodeControllers() throws Exception {
+ Collection<Set<String>> nodeControllersCollection = getNodeControllerMap()
+ .values();
+ List<String> nodeControllers = new ArrayList<String>();
+ for (Set<String> ncCollection : nodeControllersCollection) {
+ nodeControllers.addAll(ncCollection);
+ }
+ return nodeControllers;
+ }
- public static List<String> getAllNodeControllers() {
+ public static Map<String, Set<String>> getNodeControllerMap()
+ throws Exception {
+ Map<String, Set<String>> map = new HashMap<String, Set<String>>();
+ AsterixAppContextInfoImpl.getInstance().getCCApplicationContext()
+ .getCCContext().getIPAddressNodeMap(map);
+ return map;
+ }
- Collection<Set<String>> nodeControllersCollection = AsterixAppContextInfoImpl.getNodeControllerMap().values();
- List<String> nodeControllers = new ArrayList<String>();
- for (Set<String> ncCollection : nodeControllersCollection) {
- nodeControllers.addAll(ncCollection);
- }
- return nodeControllers;
- }
+ public static String getIPAddress(String hostname)
+ throws UnknownHostException {
+ String address = InetAddress.getByName(hostname).getHostAddress();
+ if (address.equals("127.0.1.1")) {
+ address = "127.0.0.1";
+ }
+ return address;
+ }
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
index 8832164..a8c0485 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/util/NonTaggedFormatUtil.java
@@ -95,6 +95,8 @@
return 12;
case POINT:
return 16;
+ case INTERVAL:
+ return 17;
case POINT3D:
case CIRCLE:
return 24;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/IOMVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/IOMVisitor.java
index 2c82174..703b792 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/IOMVisitor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/IOMVisitor.java
@@ -14,6 +14,7 @@
import edu.uci.ics.asterix.om.base.AInt32;
import edu.uci.ics.asterix.om.base.AInt64;
import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AInterval;
import edu.uci.ics.asterix.om.base.ALine;
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.base.AOrderedList;
@@ -46,6 +47,8 @@
public void visitADuration(ADuration obj) throws AsterixException;
+ public void visitAInterval(AInterval obj) throws AsterixException;
+
public void visitADate(ADate obj) throws AsterixException;
public void visitATime(ATime obj) throws AsterixException;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/OMPrintToStringVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/OMPrintToStringVisitor.java
index 1697c5c..e7856f0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/OMPrintToStringVisitor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/visitors/OMPrintToStringVisitor.java
@@ -15,6 +15,7 @@
import edu.uci.ics.asterix.om.base.AInt32;
import edu.uci.ics.asterix.om.base.AInt64;
import edu.uci.ics.asterix.om.base.AInt8;
+import edu.uci.ics.asterix.om.base.AInterval;
import edu.uci.ics.asterix.om.base.ALine;
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.base.AOrderedList;
@@ -90,6 +91,12 @@
}
@Override
+ public void visitAInterval(AInterval obj) throws AsterixException {
+ // TODO Auto-generated method stub
+ throw new NotImplementedException();
+ }
+
+ @Override
public void visitAFloat(AFloat obj) throws AsterixException {
buffer.append(obj.getFloatValue() + "f");
}