>From Wail Alkowaileet <[email protected]>:
Wail Alkowaileet has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17496 )
Change subject: [WIP] Fix column assembler for repeated complex values
......................................................................
[WIP] Fix column assembler for repeated complex values
Change-Id: Ib2cede772f3db534b6c0c93c10d51ec076747e19
---
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/PrimitiveValueAssembler.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/RepeatedPrimitiveValueAssembler.java
A
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/EndOfRepeatedGroupAssembler.java
M
asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyPrimitiveColumnValueReader.java
M
asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyRepeatedPrimitiveColumnValueReader.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/IColumnValuesReader.java
M
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/RepeatedPrimitiveColumnValuesReader.java
A
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerState.java
A
asterixdb/asterix-column/src/main/java/org/apache/asterix/column/util/SchemaStringBuilderVisitor.java
14 files changed, 392 insertions(+), 71 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/96/17496/1
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java
index 5e2ef28..0d7c9c88 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java
@@ -81,14 +81,18 @@
return reader.getColumnIndex();
}
- public final void skip(int count) throws HyracksDataException {
+ public void skip(int count) throws HyracksDataException {
reader.skip(count);
}
+ public boolean isEndOfGroupAssembler() {
+ return false;
+ }
+
/**
* Move to the next primitive value assembler
*
* @return the index of the next value
*/
- public abstract int next() throws HyracksDataException;
+ public abstract int next(AssemblerState state) throws HyracksDataException;
}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
index 969a091..43885f2 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
@@ -56,6 +56,7 @@
//Recursion info
private final IntList delimiters;
+ private IColumnValuesReader delegateRepeatedReader;
private int level;
public AssemblerBuilderVisitor(QueryColumnMetadata columnMetadata,
IColumnValuesReaderFactory readerFactory,
@@ -67,13 +68,13 @@
delimiters = new IntArrayList();
}
- public List<AbstractPrimitiveValueAssembler>
createValueAssemblers(AbstractSchemaNode requestedSchema,
+ public AbstractPrimitiveValueAssembler[]
createValueAssemblers(AbstractSchemaNode requestedSchema,
ARecordType declaredType) throws HyracksDataException {
EmptyAssembler root = new EmptyAssembler();
AssemblerInfo info = new AssemblerInfo(declaredType, root);
level = 0;
rootAssembler = requestedSchema.accept(this, info);
- return valueAssemblers;
+ return valueAssemblers.toArray(new AbstractPrimitiveValueAssembler[0]);
}
public AbstractValueAssembler getRootAssembler() {
@@ -147,14 +148,25 @@
delimiters.add(level - 1);
level++;
+ IColumnValuesReader previousDelegate = delegateRepeatedReader;
+ delegateRepeatedReader = null;
+
IAType itemDeclaredType = getChildType(itemNode,
declaredType.getItemType());
AssemblerInfo itemInfo = new AssemblerInfo(itemDeclaredType,
arrayAssembler, false);
itemNode.accept(this, itemInfo);
//Add the array assembler to the last repeated value assembler
- RepeatedPrimitiveValueAssembler repeatedAssembler =
- (RepeatedPrimitiveValueAssembler)
valueAssemblers.get(valueAssemblers.size() - 1);
- repeatedAssembler.addArray(arrayAssembler);
+ AbstractPrimitiveValueAssembler lastAssembler =
valueAssemblers.get(valueAssemblers.size() - 1);
+ EndOfRepeatedGroupAssembler endOfGroupAssembler;
+ if (lastAssembler.isEndOfGroupAssembler()) {
+ endOfGroupAssembler = (EndOfRepeatedGroupAssembler) lastAssembler;
+ } else {
+ endOfGroupAssembler = new
EndOfRepeatedGroupAssembler(delegateRepeatedReader);
+ valueAssemblers.add(endOfGroupAssembler);
+ }
+ endOfGroupAssembler.addArray(arrayAssembler);
+
+ delegateRepeatedReader = previousDelegate;
level--;
delimiters.removeInt(delimiters.size() - 1);
@@ -186,7 +198,8 @@
if (!delimiters.isEmpty()) {
IColumnValuesReader reader =
readerFactory.createValueReader(primitiveNode.getTypeTag(),
primitiveNode.getColumnIndex(), level, getDelimiters());
- assembler = new RepeatedPrimitiveValueAssembler(level, info,
reader, valueGetter);
+
+ assembler = new RepeatedPrimitiveValueAssembler(level, info,
reader, valueGetter, setDelegate(reader));
} else {
IColumnValuesReader reader =
readerFactory.createValueReader(primitiveNode.getTypeTag(),
@@ -220,4 +233,12 @@
return BuiltinType.getBuiltinType(childTypeTag);
}
}
+
+ private boolean setDelegate(IColumnValuesReader reader) {
+ if (delegateRepeatedReader == null ||
delegateRepeatedReader.getColumnIndex() > reader.getColumnIndex()) {
+ delegateRepeatedReader = reader;
+ return true;
+ }
+ return false;
+ }
}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerState.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerState.java
new file mode 100644
index 0000000..27df5b7
--- /dev/null
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerState.java
@@ -0,0 +1,39 @@
+/*
+ * 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.column.assembler;
+
+public class AssemblerState {
+ private boolean inGroup;
+
+ public AssemblerState() {
+ clear();
+ }
+
+ public void setInGroup() {
+ this.inGroup = true;
+ }
+
+ public boolean isInGroup() {
+ return inGroup;
+ }
+
+ public void clear() {
+ this.inGroup = false;
+ }
+}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/EndOfRepeatedGroupAssembler.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/EndOfRepeatedGroupAssembler.java
new file mode 100644
index 0000000..e7f2d9d
--- /dev/null
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/EndOfRepeatedGroupAssembler.java
@@ -0,0 +1,81 @@
+/*
+ * 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.column.assembler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.column.assembler.value.MissingValueGetter;
+import org.apache.asterix.column.values.IColumnValuesReader;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class EndOfRepeatedGroupAssembler extends
AbstractPrimitiveValueAssembler {
+ private final List<ArrayValueAssembler> arrays;
+
+ EndOfRepeatedGroupAssembler(IColumnValuesReader reader) {
+ super(reader.getLevel(), new AssemblerInfo(), reader,
MissingValueGetter.INSTANCE);
+ arrays = new ArrayList<>();
+ }
+
+ public void addArray(ArrayValueAssembler assembler) {
+ arrays.add(assembler);
+ }
+
+ @Override
+ public int next(AssemblerState state) throws HyracksDataException {
+ //Initially, go to the next primitive assembler
+ int nextIndex = NEXT_ASSEMBLER;
+ /*
+ * This assembler is a delegate of a repeated group
+ * The delimiter index tells us that this assembler is responsible for
a finished group
+ */
+ int delimiterIndex = reader.getDelimiterIndex();
+ if (delimiterIndex < arrays.size() && reader.isDelimiter()) {
+ //Also finish the next group
+ delimiterIndex++;
+ }
+
+ int numberOfFinishedGroups = Math.min(delimiterIndex, arrays.size());
+ for (int i = 0; i < numberOfFinishedGroups; i++) {
+ //I'm the delegate for this group of repeated values and the
group(s) is finished
+ ArrayValueAssembler assembler = arrays.get(i);
+ assembler.end();
+ }
+
+ //Is the repeated group (determined by the delimiter index) still
unfinished?
+ if (delimiterIndex < arrays.size()) {
+ //Yes, go to the first value of the unfinished repeated group
+ nextIndex = arrays.get(delimiterIndex).getFirstValueIndex();
+ state.setInGroup();
+ } else {
+ state.clear();
+ }
+ return nextIndex;
+ }
+
+ @Override
+ public boolean isEndOfGroupAssembler() {
+ return true;
+ }
+
+ @Override
+ public void skip(int count) throws HyracksDataException {
+ // noOp
+ }
+}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/PrimitiveValueAssembler.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/PrimitiveValueAssembler.java
index 4f7778c..eb88778 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/PrimitiveValueAssembler.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/PrimitiveValueAssembler.java
@@ -29,9 +29,9 @@
}
@Override
- public int next() throws HyracksDataException {
+ public int next(AssemblerState state) throws HyracksDataException {
if (!reader.next()) {
- throw new IllegalAccessError("no more values, column index: " +
getColumnIndex());
+ throw new IllegalStateException("no more values, column index: " +
getColumnIndex());
} else if (reader.isNull() && (isDelegate() || reader.getLevel() + 1
== level)) {
addNullToAncestor(reader.getLevel());
} else if (reader.isValue()) {
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/RepeatedPrimitiveValueAssembler.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/RepeatedPrimitiveValueAssembler.java
index d4455ec..6a8269f 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/RepeatedPrimitiveValueAssembler.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/RepeatedPrimitiveValueAssembler.java
@@ -18,38 +18,47 @@
*/
package org.apache.asterix.column.assembler;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.asterix.column.assembler.value.IValueGetter;
import org.apache.asterix.column.values.IColumnValuesReader;
import org.apache.hyracks.api.exceptions.HyracksDataException;
class RepeatedPrimitiveValueAssembler extends AbstractPrimitiveValueAssembler {
- private final List<ArrayValueAssembler> arrays;
+ private final boolean arrayDelegate;
RepeatedPrimitiveValueAssembler(int level, AssemblerInfo info,
IColumnValuesReader reader,
- IValueGetter primitiveValue) {
+ IValueGetter primitiveValue, boolean arrayDelegate) {
super(level, info, reader, primitiveValue);
- this.arrays = new ArrayList<>();
- }
-
- public void addArray(ArrayValueAssembler assembler) {
- arrays.add(assembler);
+ this.arrayDelegate = arrayDelegate;
}
@Override
- public int next() throws HyracksDataException {
+ public int next(AssemblerState state) throws HyracksDataException {
+ if (arrayDelegate || !state.isInGroup() || reader.isRepeatedValue())
+ /*(!reader.isRepeatedValue()
+ || !reader.isDelimiter() && reader.getDelimiterIndex() <
currentDelimiter))*/ {
+ next();
+ }
+
+ if (isDelegate()) {
+ getParent().end();
+ }
+
+ //Go to next value
+ return NEXT_ASSEMBLER;
+ }
+
+ private void next() throws HyracksDataException {
if (!reader.next()) {
- throw new IllegalAccessError("no more values, column index: " +
getColumnIndex());
- } else if (reader.isNull() && (!arrays.isEmpty() || reader.getLevel()
+ 1 == level)) {
+ throw new IllegalStateException("no more values, column index: " +
getColumnIndex());
+ } else if (reader.isNull() && (arrayDelegate || reader.getLevel() + 1
== level)) {
/*
* There are two cases here for where the null belongs to:
* 1- If the null is an array item, then add it
* 2- If the null is an ancestor, then we only add null if this
column is the array delegate
- * (i.e., !arrays.isEmpty())
+ * (i.e., arrayDelegate is true)
*/
addNullToAncestor(reader.getLevel());
+
} else if (reader.isMissing() && reader.getLevel() + 1 == level) {
/*
* Add a missing item
@@ -58,39 +67,5 @@
} else if (reader.isValue()) {
addValueToParent();
}
-
- if (isDelegate()) {
- getParent().end();
- }
-
- //Initially, go to the next primitive assembler
- int nextIndex = NEXT_ASSEMBLER;
- if (!arrays.isEmpty()) {
- /*
- * This assembler is a delegate of a repeated group
- * The delimiter index tells us that this assembler is responsible
for a finished group
- */
- int delimiterIndex = reader.getDelimiterIndex();
- if (delimiterIndex < arrays.size() && reader.isDelimiter()) {
- //Also finish the next group
- delimiterIndex++;
- }
-
- int numberOfFinishedGroups = Math.min(delimiterIndex,
arrays.size());
- for (int i = 0; i < numberOfFinishedGroups; i++) {
- //I'm the delegate for this group of repeated values and the
group(s) is finished
- ArrayValueAssembler assembler = arrays.get(i);
- assembler.end();
- }
-
- //Is the repeated group (determined by the delimiter index) still
unfinished?
- if (delimiterIndex < arrays.size()) {
- //Yes, go to the first value of the unfinished repeated group
- nextIndex = arrays.get(delimiterIndex).getFirstValueIndex();
- }
- }
-
- //Go to next value
- return nextIndex;
}
}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
index 71d3ac6..e86f063 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
@@ -18,10 +18,9 @@
*/
package org.apache.asterix.column.operation.query;
-import java.util.List;
-
import org.apache.asterix.column.assembler.AbstractPrimitiveValueAssembler;
import org.apache.asterix.column.assembler.AssemblerBuilderVisitor;
+import org.apache.asterix.column.assembler.AssemblerState;
import org.apache.asterix.column.assembler.ObjectValueAssembler;
import org.apache.asterix.column.assembler.value.IValueGetterFactory;
import org.apache.asterix.column.bytes.stream.in.AbstractBytesInputStream;
@@ -32,8 +31,9 @@
import org.apache.hyracks.data.std.api.IValueReference;
public final class ColumnAssembler {
- private final List<AbstractPrimitiveValueAssembler> assemblers;
+ private final AbstractPrimitiveValueAssembler[] assemblers;
private final ObjectValueAssembler rootAssembler;
+ private final AssemblerState state;
private int numberOfTuples;
private int tupleIndex;
@@ -44,6 +44,7 @@
new AssemblerBuilderVisitor(columnMetadata, readerFactory,
valueGetterFactory);
assemblers = builderVisitor.createValueAssemblers(node, declaredType);
rootAssembler = (ObjectValueAssembler)
builderVisitor.getRootAssembler();
+ state = new AssemblerState();
}
public void reset(int numberOfTuples) {
@@ -52,11 +53,11 @@
}
public void resetColumn(AbstractBytesInputStream stream, int ordinal)
throws HyracksDataException {
- assemblers.get(ordinal).reset(stream, numberOfTuples);
+ assemblers[ordinal].reset(stream, numberOfTuples);
}
public int getColumnIndex(int ordinal) {
- return assemblers.get(ordinal).getColumnIndex();
+ return assemblers[ordinal].getColumnIndex();
}
public boolean hasNext() {
@@ -72,9 +73,9 @@
}
int index = 0;
- while (index < assemblers.size()) {
- AbstractPrimitiveValueAssembler assembler = assemblers.get(index);
- int groupIndex = assembler.next();
+ while (index < assemblers.length) {
+ AbstractPrimitiveValueAssembler assembler = assemblers[index];
+ int groupIndex = assembler.next(state);
if (groupIndex != AbstractPrimitiveValueAssembler.NEXT_ASSEMBLER) {
index = groupIndex;
} else {
@@ -88,13 +89,13 @@
}
public int getNumberOfColumns() {
- return assemblers.size();
+ return assemblers.length;
}
public void skip(int count) throws HyracksDataException {
tupleIndex += count;
- for (int i = 0; i < assemblers.size(); i++) {
- assemblers.get(i).skip(count);
+ for (int i = 0; i < assemblers.length; i++) {
+ assemblers[i].skip(count);
}
}
}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
index b9babf1..58ddb5d 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
@@ -172,6 +172,9 @@
PrimitiveColumnValuesReader[] primaryKeyReaders =
createPrimaryKeyReaders(input, readerFactory,
numberOfPrimaryKeys);
+ // SchemaStringBuilderVisitor printer = new
SchemaStringBuilderVisitor(fieldNamesDictionary);
+ // System.err.println(printer.build(clippedRoot));
+
if (LOGGER.isInfoEnabled() && filterEvaluator !=
TrueColumnFilterEvaluator.INSTANCE) {
String filterString = filterEvaluator ==
FalseColumnFilterEvaluator.INSTANCE ? "SKIP_ALL"
:
LogRedactionUtil.userData(filterEvaluatorFactory.toString());
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/util/SchemaStringBuilderVisitor.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/util/SchemaStringBuilderVisitor.java
new file mode 100644
index 0000000..5786221
--- /dev/null
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/util/SchemaStringBuilderVisitor.java
@@ -0,0 +1,149 @@
+/*
+ * 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.column.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.column.metadata.FieldNamesDictionary;
+import org.apache.asterix.column.metadata.schema.AbstractSchemaNode;
+import org.apache.asterix.column.metadata.schema.ISchemaNodeVisitor;
+import org.apache.asterix.column.metadata.schema.ObjectSchemaNode;
+import org.apache.asterix.column.metadata.schema.UnionSchemaNode;
+import
org.apache.asterix.column.metadata.schema.collection.AbstractCollectionSchemaNode;
+import org.apache.asterix.column.metadata.schema.primitive.PrimitiveSchemaNode;
+import
org.apache.asterix.dataflow.data.nontagged.serde.AStringSerializerDeserializer;
+import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IValueReference;
+import org.apache.hyracks.data.std.util.ByteArrayAccessibleDataInputStream;
+import org.apache.hyracks.data.std.util.ByteArrayAccessibleInputStream;
+import org.apache.hyracks.util.string.UTF8StringReader;
+import org.apache.hyracks.util.string.UTF8StringWriter;
+
+import it.unimi.dsi.fastutil.ints.IntList;
+
+// TODO log schema changes (also redact)
+// TODO log query schema and redact
+public class SchemaStringBuilderVisitor implements ISchemaNodeVisitor<Void,
Void> {
+ private final StringBuilder builder;
+ private final List<String> fieldNames;
+
+ private int level;
+ private int indent;
+
+ public SchemaStringBuilderVisitor(FieldNamesDictionary dictionary) throws
HyracksDataException {
+ builder = new StringBuilder();
+ this.fieldNames = new ArrayList<>();
+ AStringSerializerDeserializer stringSerDer =
+ new AStringSerializerDeserializer(new UTF8StringWriter(), new
UTF8StringReader());
+ List<IValueReference> extractedFieldNames = dictionary.getFieldNames();
+
+ //Deserialize field names
+ ByteArrayAccessibleInputStream in = new
ByteArrayAccessibleInputStream(new byte[0], 0, 0);
+ ByteArrayAccessibleDataInputStream dataIn = new
ByteArrayAccessibleDataInputStream(in);
+ for (IValueReference serFieldName : extractedFieldNames) {
+ in.setContent(serFieldName.getByteArray(), 0,
serFieldName.getLength());
+ AString fieldName = stringSerDer.deserialize(dataIn);
+ this.fieldNames.add(fieldName.getStringValue());
+ }
+ level = 0;
+ indent = 0;
+ }
+
+ public String build(ObjectSchemaNode root) throws HyracksDataException {
+ builder.append("root\n");
+ visit(root, null);
+ return builder.toString();
+ }
+
+ @Override
+ public Void visit(ObjectSchemaNode objectNode, Void arg) throws
HyracksDataException {
+ List<AbstractSchemaNode> children = objectNode.getChildren();
+ IntList fieldNameIndexes = objectNode.getChildrenFieldNameIndexes();
+ level++;
+ indent++;
+
+ for (int i = 0; i < children.size(); i++) {
+ String fieldName = fieldNames.get(fieldNameIndexes.getInt(i));
+ AbstractSchemaNode child = children.get(i);
+ append(fieldName, child);
+ child.accept(this, null);
+ }
+
+ level--;
+ indent--;
+ return null;
+ }
+
+ @Override
+ public Void visit(AbstractCollectionSchemaNode collectionNode, Void arg)
throws HyracksDataException {
+ level++;
+ indent++;
+ AbstractSchemaNode itemNode = collectionNode.getItemNode();
+ append("item", itemNode);
+ itemNode.accept(this, null);
+ level--;
+ indent--;
+ return null;
+ }
+
+ @Override
+ public Void visit(UnionSchemaNode unionNode, Void arg) throws
HyracksDataException {
+ indent++;
+ for (AbstractSchemaNode child : unionNode.getChildren().values()) {
+ append(child.getTypeTag().toString(), child);
+ child.accept(this, null);
+ }
+ indent--;
+ return null;
+ }
+
+ @Override
+ public Void visit(PrimitiveSchemaNode primitiveNode, Void arg) throws
HyracksDataException {
+ return null;
+ }
+
+ private void appendLevels(String levels) {
+ appendDecor();
+ builder.append("Def ");
+ builder.append(levels);
+ builder.append('\n');
+ }
+
+ private void appendDecor() {
+ builder.append("| ".repeat(Math.max(0, indent - 1)));
+ builder.append("|-- ");
+ }
+
+ private void append(String key, AbstractSchemaNode node) {
+ appendDecor();
+ builder.append(key);
+ builder.append(": ");
+ builder.append(node.getTypeTag().toString());
+ builder.append(" <level: ");
+ builder.append(level);
+ if (!node.isNested()) {
+ final PrimitiveSchemaNode primitiveNode = (PrimitiveSchemaNode)
node;
+ builder.append(", index: ");
+ builder.append(primitiveNode.getColumnIndex());
+ }
+ builder.append(">\n");
+ }
+}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/IColumnValuesReader.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/IColumnValuesReader.java
index fe23b23..1ee6c36 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/IColumnValuesReader.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/IColumnValuesReader.java
@@ -86,6 +86,13 @@
boolean isDelimiter();
/**
+ * @return is the last delimiter (the end of all nested arrays)
+ */
+ boolean isLastDelimiter();
+
+ boolean isRepeatedValue();
+
+ /**
* @return which delimiter was returned (nested arrays have different
delimiter indexes)
*/
int getDelimiterIndex();
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java
index 7ae2954..6d2d87c 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java
@@ -74,6 +74,16 @@
}
@Override
+ public boolean isLastDelimiter() {
+ return false;
+ }
+
+ @Override
+ public boolean isRepeatedValue() {
+ return false;
+ }
+
+ @Override
public int getDelimiterIndex() {
throw new IllegalStateException("Not a repeated reader");
}
diff --git
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/RepeatedPrimitiveColumnValuesReader.java
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/RepeatedPrimitiveColumnValuesReader.java
index 1cd424b..f0044df 100644
---
a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/RepeatedPrimitiveColumnValuesReader.java
+++
b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/RepeatedPrimitiveColumnValuesReader.java
@@ -108,11 +108,13 @@
writer.writeLevel(level);
}
- private boolean isRepeatedValue() {
+ @Override
+ public boolean isRepeatedValue() {
return levelToDelimiterMap[level] < delimiters.length;
}
- private boolean isLastDelimiter() {
+ @Override
+ public boolean isLastDelimiter() {
return isDelimiter() && delimiterIndex == delimiters.length - 1;
}
diff --git
a/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyPrimitiveColumnValueReader.java
b/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyPrimitiveColumnValueReader.java
index 115f311..978ec14 100644
---
a/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyPrimitiveColumnValueReader.java
+++
b/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyPrimitiveColumnValueReader.java
@@ -55,6 +55,16 @@
}
@Override
+ public boolean isLastDelimiter() {
+ return false;
+ }
+
+ @Override
+ public boolean isRepeatedValue() {
+ return false;
+ }
+
+ @Override
public int getDelimiterIndex() {
throw new IllegalStateException("Not a repeated reader");
}
diff --git
a/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyRepeatedPrimitiveColumnValueReader.java
b/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyRepeatedPrimitiveColumnValueReader.java
index abd1927..c7744c2 100644
---
a/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyRepeatedPrimitiveColumnValueReader.java
+++
b/asterixdb/asterix-column/src/test/java/org/apache/asterix/column/values/reader/DummyRepeatedPrimitiveColumnValueReader.java
@@ -73,6 +73,16 @@
}
@Override
+ public boolean isLastDelimiter() {
+ return isDelimiter() && delimiterIndex == delimiters.length - 1;
+ }
+
+ @Override
+ public boolean isRepeatedValue() {
+ return levelToDelimiterMap[level] < delimiters.length;
+ }
+
+ @Override
public int getDelimiterIndex() {
return delimiterIndex;
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17496
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: Ib2cede772f3db534b6c0c93c10d51ec076747e19
Gerrit-Change-Number: 17496
Gerrit-PatchSet: 1
Gerrit-Owner: Wail Alkowaileet <[email protected]>
Gerrit-MessageType: newchange