This is an automated email from the ASF dual-hosted git repository.

wyk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 90a24ec  [NO ISSUE][TYPE] Introduce IATypeVisitor
90a24ec is described below

commit 90a24ec2c01108322e9d00c6d56f4574f6981ee9
Author: Wail Alkowaileet <[email protected]>
AuthorDate: Mon Aug 16 14:42:02 2021 -0700

    [NO ISSUE][TYPE] Introduce IATypeVisitor
    
    - user mode changes: no
    - storage format changes: no
    - interface changes: yes
    
    Interface changes:
    - Add accept method to IAType
    
    Details:
    Several operation require to traverse IAType to process types. The 
IATypeVisitor provides
    an easy way to traverse nested types (e.g., comparing AsterixDB type and 
Parquet Type)
    
    Change-Id: I16cbb7b3675846b3a4097d5a38ee15fa28634f92
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/12824
    Tested-by: Jenkins <[email protected]>
    Integration-Tests: Jenkins <[email protected]>
    Reviewed-by: Wael Alkowaileet <[email protected]>
    Reviewed-by: Dmitry Lychagin <[email protected]>
---
 .../org/apache/asterix/om/types/ARecordType.java   |   5 +
 .../org/apache/asterix/om/types/AUnionType.java    |  15 +++
 .../asterix/om/types/AbstractCollectionType.java   |   5 +
 .../org/apache/asterix/om/types/BuiltinType.java   |  13 ++-
 .../java/org/apache/asterix/om/types/IAType.java   |   7 ++
 .../om/types/{IAType.java => IATypeVisitor.java}   |  21 ++--
 .../SimpleStringBuilderForIATypeVisitor.java       |  99 +++++++++++++++++
 .../types/visitor/TypeSimpleStringBuilderTest.java | 121 +++++++++++++++++++++
 8 files changed, 275 insertions(+), 11 deletions(-)

diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
index b91b4ae..a79b8de 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
@@ -428,4 +428,9 @@ public class ARecordType extends AbstractComplexType {
         }
         return false;
     }
+
+    @Override
+    public <R, T> R accept(IATypeVisitor<R, T> visitor, T arg) {
+        return visitor.visit(this, arg);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnionType.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnionType.java
index 7ef18d4..caa926d 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnionType.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnionType.java
@@ -70,6 +70,16 @@ public class AUnionType extends AbstractComplexType {
         return false;
     }
 
+    public IAType getType(ATypeTag typeTag) {
+        for (int i = 0; i < unionList.size(); i++) {
+            IAType type = unionList.get(i);
+            if (typeTag == type.getTypeTag()) {
+                return type;
+            }
+        }
+        return null;
+    }
+
     public IAType getActualType() {
         return unionList.get(AUnionType.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
     }
@@ -241,6 +251,11 @@ public class AUnionType extends AbstractComplexType {
         return jsonObject;
     }
 
+    @Override
+    public <R, T> R accept(IATypeVisitor<R, T> visitor, T arg) {
+        return visitor.visit(this, arg);
+    }
+
     public static IJsonSerializable fromJson(IPersistedResourceRegistry 
registry, JsonNode json)
             throws HyracksDataException {
         String typeName = json.get(TYPE_NAME_FIELD).asText();
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
index ef15224..9b75566 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
@@ -70,6 +70,11 @@ public abstract class AbstractCollectionType extends 
AbstractComplexType {
         return isTyped() && itemType.getTypeName().equals(type.getTypeName());
     }
 
+    @Override
+    public <R, T> R accept(IATypeVisitor<R, T> visitor, T arg) {
+        return visitor.visit(this, arg);
+    }
+
     JsonNode convertToJson(IPersistedResourceRegistry registry, Class<? 
extends IJsonSerializable> clazz, long version)
             throws HyracksDataException {
         final ObjectNode jsonObject = registry.getClassIdentifier(clazz, 
version);
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/BuiltinType.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/BuiltinType.java
index bdac9e9..2404ac2 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/BuiltinType.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/BuiltinType.java
@@ -1081,6 +1081,14 @@ public abstract class BuiltinType implements IAType {
         return getType().getTypeTag().serialize();
     }
 
+    /**
+     * Visit built-in type as a flat type
+     */
+    @Override
+    public <R, T> R accept(IATypeVisitor<R, T> visitor, T arg) {
+        return visitor.visitFlat(this, arg);
+    }
+
     private static JsonNode convertToJson(IPersistedResourceRegistry registry, 
short tag, long version) {
         ObjectNode jsonNode = registry.getClassIdentifier(BuiltinType.class, 
version);
         jsonNode.put(TAG_FIELD, tag);
@@ -1090,7 +1098,10 @@ public abstract class BuiltinType implements IAType {
     @SuppressWarnings("squid:S1172") // unused parameter
     public static IJsonSerializable fromJson(IPersistedResourceRegistry 
registry, JsonNode json) {
         byte tag = (byte) json.get(TAG_FIELD).shortValue();
-        ATypeTag typeTag = VALUE_TYPE_MAPPING[tag];
+        return getBuiltinType(VALUE_TYPE_MAPPING[tag]);
+    }
+
+    public static IAType getBuiltinType(ATypeTag typeTag) {
         switch (typeTag) {
             case TYPE:
                 return ALL_TYPE;
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java
index 0e6cc4f..ed4c2bb 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java
@@ -31,4 +31,11 @@ public interface IAType extends IAObject, Serializable, 
IJsonSerializable {
 
     public String getTypeName();
 
+    /**
+     * Allow for additional traversal and processing for {@link IAType}
+     *
+     * @param visitor visitor
+     * @param arg     visitor's argument
+     */
+    <R, T> R accept(IATypeVisitor<R, T> visitor, T arg);
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IATypeVisitor.java
similarity index 70%
copy from 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java
copy to 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IATypeVisitor.java
index 0e6cc4f..0951763 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IAType.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/IATypeVisitor.java
@@ -18,17 +18,18 @@
  */
 package org.apache.asterix.om.types;
 
-import java.io.Serializable;
-
-import org.apache.asterix.om.base.IAObject;
-import org.apache.hyracks.api.io.IJsonSerializable;
-
-public interface IAType extends IAObject, Serializable, IJsonSerializable {
-
-    public ATypeTag getTypeTag();
+/**
+ * Allows for a specialized processing for the {@link IAType}
+ *
+ * @param <R> return type
+ * @param <T> argument type
+ */
+public interface IATypeVisitor<R, T> {
+    R visit(ARecordType recordType, T arg);
 
-    public String getDisplayName();
+    R visit(AbstractCollectionType collectionType, T arg);
 
-    public String getTypeName();
+    R visit(AUnionType unionType, T arg);
 
+    R visitFlat(IAType flatType, T arg);
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/visitor/SimpleStringBuilderForIATypeVisitor.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/visitor/SimpleStringBuilderForIATypeVisitor.java
new file mode 100644
index 0000000..9f0c82b
--- /dev/null
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/visitor/SimpleStringBuilderForIATypeVisitor.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.om.types.visitor;
+
+import java.util.List;
+
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.IATypeVisitor;
+
+/**
+ * This visitor produces a oneliner JSON-like representation of {@link IAType} 
to be interpreted by the user.
+ */
+public class SimpleStringBuilderForIATypeVisitor implements 
IATypeVisitor<Void, StringBuilder> {
+    /**
+     * Example: {"field1":string,"field2":[bigint]}
+     */
+    @Override
+    public Void visit(ARecordType recordType, StringBuilder arg) {
+        String[] fieldNames = recordType.getFieldNames();
+        IAType[] fieldTypes = recordType.getFieldTypes();
+
+        arg.append("{");
+        for (int i = 0; i < fieldNames.length; i++) {
+            if (i > 0) {
+                arg.append(',');
+            }
+            arg.append(fieldNames[i]);
+            arg.append(':');
+            fieldTypes[i].accept(this, arg);
+        }
+        arg.append("}");
+        return null;
+    }
+
+    /**
+     * Example:
+     * - Array: [{"field1":bigint}]
+     * - Multiset: {{bigint}}
+     */
+    @Override
+    public Void visit(AbstractCollectionType collectionType, StringBuilder 
arg) {
+        IAType itemType = collectionType.getItemType();
+
+        arg.append(collectionType.getTypeTag() == ATypeTag.ARRAY ? "[" : "{{");
+        itemType.accept(this, arg);
+        arg.append(collectionType.getTypeTag() == ATypeTag.ARRAY ? "]" : "}}");
+        return null;
+    }
+
+    /**
+     * Example: A union type of array, object, and bigint
+     * - <[{"field1":...}],{"field1:...},bigint>
+     */
+    @Override
+    public Void visit(AUnionType unionType, StringBuilder arg) {
+        List<IAType> unionList = unionType.getUnionList();
+
+        arg.append("<");
+        for (int i = 0; i < unionList.size(); i++) {
+            if (i > 0) {
+                arg.append(',');
+            }
+            unionList.get(i).accept(this, arg);
+        }
+        arg.append(">");
+        return null;
+    }
+
+    /**
+     * Example:
+     * - bigint
+     * - string
+     */
+    @Override
+    public Void visitFlat(IAType flatType, StringBuilder arg) {
+        arg.append(flatType.getTypeTag());
+        return null;
+    }
+}
diff --git 
a/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/types/visitor/TypeSimpleStringBuilderTest.java
 
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/types/visitor/TypeSimpleStringBuilderTest.java
new file mode 100644
index 0000000..8186810
--- /dev/null
+++ 
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/test/om/types/visitor/TypeSimpleStringBuilderTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.test.om.types.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.visitor.SimpleStringBuilderForIATypeVisitor;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TypeSimpleStringBuilderTest {
+    private static final ARecordType ROOT_TYPE;
+    private static final String EXPECTED_STRING;
+
+    static {
+        StringBuilder expectedStringBuilder = new StringBuilder();
+        //Record with two fields
+        ARecordType recordType = createNestedRecord(expectedStringBuilder);
+        String recordTypeString = getStringAndReset(expectedStringBuilder);
+
+        //Array of records
+        AOrderedListType arrayOfRecords = new AOrderedListType(recordType, 
"arrayOfRecords");
+        surroundString(expectedStringBuilder, "[", "]", recordTypeString);
+        String arrayOfRecordsString = getStringAndReset(expectedStringBuilder);
+
+        //Multiset of records
+        AUnorderedListType multiSetOfRecords = new 
AUnorderedListType(recordType, "multiSetOfRecords");
+        surroundString(expectedStringBuilder, "{{", "}}", recordTypeString);
+        String multiSetOfRecordsString = 
getStringAndReset(expectedStringBuilder);
+
+        //Union
+        List<IAType> unionList = new ArrayList<>();
+        unionList.add(recordType);
+        unionList.add(arrayOfRecords);
+        unionList.add(multiSetOfRecords);
+        unionList.add(BuiltinType.AINT64);
+        AUnionType unionType = new AUnionType(unionList, "unionType");
+        surroundString(expectedStringBuilder, "<", ">", recordTypeString, 
arrayOfRecordsString, multiSetOfRecordsString,
+                BuiltinType.AINT64.getTypeTag().toString());
+        String unionTypeString = getStringAndReset(expectedStringBuilder);
+
+        //Root type
+        String[] rootFieldNames = { BuiltinType.ANY.getTypeName(), 
arrayOfRecords.getTypeName(),
+                multiSetOfRecords.getTypeName(), unionType.getTypeName() };
+        IAType[] rootFieldTypes = { BuiltinType.ANY, arrayOfRecords, 
multiSetOfRecords, unionType };
+        ROOT_TYPE = new ARecordType("rootType", rootFieldNames, 
rootFieldTypes, false);
+        buildRecordString(expectedStringBuilder, rootFieldNames, 
rootFieldTypes[0].getTypeTag().toString(),
+                arrayOfRecordsString, multiSetOfRecordsString, 
unionTypeString);
+        EXPECTED_STRING = getStringAndReset(expectedStringBuilder);
+    }
+
+    private static ARecordType createNestedRecord(StringBuilder builder) {
+        String[] fieldNames = { "field1", "field2" };
+        IAType[] fieldTypes = { BuiltinType.ASTRING, BuiltinType.AINT64 };
+        buildRecordString(builder, fieldNames, 
fieldTypes[0].getTypeTag().toString(),
+                fieldTypes[1].getTypeTag().toString());
+        return new ARecordType("nestedRecord", fieldNames, fieldTypes, true);
+    }
+
+    private static void surroundString(StringBuilder builder, String open, 
String close, String... strings) {
+        builder.append(open);
+        for (int i = 0; i < strings.length; i++) {
+            if (i > 0) {
+                builder.append(',');
+            }
+            builder.append(strings[i]);
+        }
+        builder.append(close);
+    }
+
+    private static void buildRecordString(StringBuilder builder, String[] 
fieldNames, String... fieldTypesStrings) {
+        builder.append('{');
+        for (int i = 0; i < fieldNames.length; i++) {
+            if (i > 0) {
+                builder.append(',');
+            }
+            builder.append(fieldNames[i]);
+            builder.append(':');
+            builder.append(fieldTypesStrings[i]);
+        }
+        builder.append('}');
+    }
+
+    private static String getStringAndReset(StringBuilder 
expectedStringBuilder) {
+        String value = expectedStringBuilder.toString();
+        expectedStringBuilder.setLength(0);
+        return value;
+    }
+
+    @Test
+    public void testSimpleStringBuilderForIAType() {
+        StringBuilder builder = new StringBuilder();
+        SimpleStringBuilderForIATypeVisitor visitor = new 
SimpleStringBuilderForIATypeVisitor();
+        ROOT_TYPE.accept(visitor, builder);
+        Assert.assertEquals(EXPECTED_STRING, builder.toString());
+    }
+
+}

Reply via email to