diff --git a/pom.xml b/pom.xml index 9809bbfeeb..2352a6da2b 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.11.0 eclipse @@ -88,7 +88,7 @@ org.apache.maven.plugins maven-assembly-plugin - 3.1.1 + 3.6.0 @@ -178,7 +178,7 @@ com.diffplug.spotless spotless-maven-plugin - 1.26.0 + 2.36.0 verify diff --git a/src/main/java/org/rumbledb/api/SequenceOfItems.java b/src/main/java/org/rumbledb/api/SequenceOfItems.java index 7a32fde406..aa50df503e 100644 --- a/src/main/java/org/rumbledb/api/SequenceOfItems.java +++ b/src/main/java/org/rumbledb/api/SequenceOfItems.java @@ -2,11 +2,16 @@ import java.util.List; +import org.apache.spark.SparkRuntimeException; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import org.rumbledb.config.RumbleRuntimeConfiguration; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.CastException; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.RumbleException; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.RuntimeIterator; @@ -87,7 +92,25 @@ public boolean hasNext() { if (!this.isMaterialisable()) { return false; } - return this.iterator.hasNext(); + try { + return this.iterator.hasNext(); + } catch (NumberFormatException e) { + RumbleException ex = new CastException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } catch (SparkRuntimeException e) { + if (e.getMessage().contains("CAST_INVALID_INPUT")) { + RumbleException ex = new CastException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } else { + throw e; + } + } catch (UnsupportedOperationException e) { + RumbleException ex = new CastException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } } /** @@ -152,7 +175,25 @@ public JavaRDD getAsRDD() { if (this.isOpen) { throw new RuntimeException("Cannot obtain an RDD if the iterator is open."); } - return this.iterator.getRDD(this.dynamicContext); + try { + return this.iterator.getRDD(this.dynamicContext); + } catch (NumberFormatException e) { + RumbleException ex = new UnexpectedTypeException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } catch (SparkRuntimeException e) { + if (e.getMessage().contains("CAST_INVALID_INPUT")) { + RumbleException ex = new CastException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } else { + throw e; + } + } catch (UnsupportedOperationException e) { + RumbleException ex = new UnexpectedTypeException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } } /** @@ -226,8 +267,26 @@ public long populateListWithWarningOnlyIfCapReached(List resultList) { if (!this.isMaterialisable()) { return -1; } - JavaRDD rdd = this.iterator.getRDD(this.dynamicContext); - return SparkSessionManager.collectRDDwithLimitWarningOnly(rdd, resultList); + try { + JavaRDD rdd = this.iterator.getRDD(this.dynamicContext); + return SparkSessionManager.collectRDDwithLimitWarningOnly(rdd, resultList); + } catch (NumberFormatException e) { + RumbleException ex = new UnexpectedTypeException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } catch (SparkRuntimeException e) { + if (e.getMessage().contains("CAST_INVALID_INPUT")) { + RumbleException ex = new CastException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } else { + throw e; + } + } catch (UnsupportedOperationException e) { + RumbleException ex = new UnexpectedTypeException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(e); + throw ex; + } } else { return populateList(resultList); } diff --git a/src/main/java/org/rumbledb/cli/Main.java b/src/main/java/org/rumbledb/cli/Main.java index 2a0e84e5ed..cd90ba9011 100644 --- a/src/main/java/org/rumbledb/cli/Main.java +++ b/src/main/java/org/rumbledb/cli/Main.java @@ -24,9 +24,13 @@ import org.apache.commons.io.IOUtils; import org.apache.spark.SparkException; +import org.apache.spark.SparkRuntimeException; import org.rumbledb.config.RumbleRuntimeConfiguration; +import org.rumbledb.exceptions.CastException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.RumbleException; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.server.RumbleServer; import org.rumbledb.shell.RumbleJLineShell; @@ -81,29 +85,22 @@ public static void main(String[] args) throws IOException { } private static void handleException(Throwable ex, boolean showErrorInfo) { + ex = unboxException(ex); if (ex != null) { - if (ex instanceof SparkException) { - Throwable sparkExceptionCause = ex.getCause(); - if (sparkExceptionCause != null) { - handleException(sparkExceptionCause, showErrorInfo); - } else { - if (showErrorInfo) { - ex.printStackTrace(); - } - handleException( - new OurBadException( - "There was a problem with Spark, but Spark did not provide any cause or stracktrace. The message from Spark is: " - + ex.getMessage() - ), - showErrorInfo - ); - } - } else if (ex instanceof RumbleException && !(ex instanceof OurBadException)) { + if (ex instanceof RumbleException && !(ex instanceof OurBadException)) { System.err.println("⚠️ ️" + ex.getMessage()); if (showErrorInfo) { ex.printStackTrace(); } System.exit(42); + } else if (ex instanceof NumberFormatException) { + handleException( + new UnexpectedTypeException( + "A cast failed. However, since this happened in a native Spark SQL execution, we cannot show you where. You can get more information on this type error by retrying with --native-execution no.", + ExceptionMetadata.EMPTY_METADATA + ), + showErrorInfo + ); } else if (ex instanceof OutOfMemoryError) { System.err.println( "⚠️ Java went out of memory." @@ -154,24 +151,54 @@ private static void handleException(Throwable ex, boolean showErrorInfo) { ex.printStackTrace(); } System.exit(-42); - } else { - System.err.println( - "We are very embarrassed, because an error has occured that we did not anticipate 🙈: " - + ex.getMessage() - ); - System.err.println( - "We would like to investigate this and make sure to fix it. We would be very grateful if you could contact us or file an issue on GitHub with your query." + } + System.err.println( + "We are very embarrassed, because an error has occured that we did not anticipate 🙈: " + + ex.getMessage() + ); + System.err.println( + "We would like to investigate this and make sure to fix it. We would be very grateful if you could contact us or file an issue on GitHub with your query." + ); + System.err.println("Link: https://github.com/RumbleDB/rumble/issues"); + System.err.println( + "For more debug info (e.g., so you can communicate it to us), please try again using --show-error-info yes in your command line." + ); + if (showErrorInfo) { + ex.printStackTrace(); + } + System.exit(-42); + } + } + + public static Throwable unboxException(Throwable ex) { + if (ex != null) { + if (ex instanceof SparkException) { + Throwable sparkExceptionCause = ex.getCause(); + if (sparkExceptionCause != null) { + return sparkExceptionCause; + } + return new OurBadException( + "There was a problem with Spark, but Spark did not provide any cause or stracktrace. The message from Spark is: " + + ex.getMessage() ); - System.err.println("Link: https://github.com/RumbleDB/rumble/issues"); - System.err.println( - "For more debug info (e.g., so you can communicate it to us), please try again using --show-error-info yes in your command line." + } + if (ex instanceof NumberFormatException) { + return new UnexpectedTypeException( + "A cast failed. However, since this happened in a native Spark SQL execution, we cannot show you where. You can get more information on this type error by retrying with --native-execution no.", + ExceptionMetadata.EMPTY_METADATA ); - if (showErrorInfo) { - ex.printStackTrace(); + } + if (ex instanceof SparkRuntimeException) { + if (ex.getMessage().contains("CAST_INVALID_INPUT")) { + RumbleException nex = new CastException(ex.getMessage(), ExceptionMetadata.EMPTY_METADATA); + ex.initCause(ex); + return nex; } - System.exit(-42); + // general message. } + return ex; } + return new OurBadException("A null exception was returned."); } private static void runQueryExecutor(RumbleRuntimeConfiguration sparksoniqConf) throws IOException { diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index f0385020e7..6248a36060 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -128,6 +128,8 @@ import org.rumbledb.types.ItemType; import org.rumbledb.types.ItemTypeFactory; import org.rumbledb.types.SequenceType; +import org.rumbledb.types.SequenceType.Arity; + import sparksoniq.spark.SparkSessionManager; diff --git a/src/main/java/org/rumbledb/context/DynamicContext.java b/src/main/java/org/rumbledb/context/DynamicContext.java index 258dbd364c..40645effeb 100644 --- a/src/main/java/org/rumbledb/context/DynamicContext.java +++ b/src/main/java/org/rumbledb/context/DynamicContext.java @@ -142,13 +142,21 @@ public VariableValues getVariableValues() { @Override public void write(Kryo kryo, Output output) { kryo.writeObjectOrNull(output, this.parent, DynamicContext.class); + kryo.writeObject(output, this.conf); kryo.writeObject(output, this.variableValues); + // kryo.writeObject(output, this.namedFunctions); + kryo.writeObject(output, this.inScopeSchemaTypes); + kryo.writeObject(output, this.currentDateTime.getMillis()); } @Override public void read(Kryo kryo, Input input) { this.parent = kryo.readObjectOrNull(input, DynamicContext.class); + this.conf = kryo.readObject(input, RumbleRuntimeConfiguration.class); this.variableValues = kryo.readObject(input, VariableValues.class); + this.namedFunctions = new NamedFunctions(this.conf); + this.inScopeSchemaTypes = kryo.readObject(input, InScopeSchemaTypes.class); + this.currentDateTime = new DateTime(kryo.readObject(input, Long.class)); } public int getCurrentMutabilityLevel() { diff --git a/src/main/java/org/rumbledb/context/RuntimeStaticContext.java b/src/main/java/org/rumbledb/context/RuntimeStaticContext.java index e5cce1f65d..414cb50579 100644 --- a/src/main/java/org/rumbledb/context/RuntimeStaticContext.java +++ b/src/main/java/org/rumbledb/context/RuntimeStaticContext.java @@ -8,7 +8,12 @@ import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.types.SequenceType; -public class RuntimeStaticContext implements Serializable { +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoSerializable; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + +public class RuntimeStaticContext implements Serializable, KryoSerializable { private static final long serialVersionUID = 1L; private RumbleRuntimeConfiguration configuration; @@ -16,6 +21,13 @@ public class RuntimeStaticContext implements Serializable { private ExecutionMode executionMode; private ExceptionMetadata metadata; + public RuntimeStaticContext() { + this.configuration = null; + this.staticType = null; + this.executionMode = null; + this.metadata = null; + } + public RuntimeStaticContext( RumbleRuntimeConfiguration configuration, SequenceType staticType, @@ -62,4 +74,20 @@ public ExceptionMetadata getMetadata() { return this.metadata; } + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.configuration); + kryo.writeObject(output, this.staticType); + kryo.writeObject(output, this.executionMode); + kryo.writeObject(output, this.metadata); + } + + @Override + public void read(Kryo kryo, Input input) { + this.configuration = kryo.readObject(input, RumbleRuntimeConfiguration.class); + this.staticType = kryo.readObject(input, SequenceType.class); + this.executionMode = kryo.readObject(input, ExecutionMode.class); + this.metadata = kryo.readObject(input, ExceptionMetadata.class); + } + } diff --git a/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java b/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java index d4401e2b3d..283fe8dbb6 100644 --- a/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java +++ b/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java @@ -22,20 +22,36 @@ import java.io.Serializable; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoSerializable; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + /** * Metadata for error reporting (line and column number) * * @author Stefan Irimescu, Ghislain Fourny */ -public class ExceptionMetadata implements Serializable { +public class ExceptionMetadata implements Serializable, KryoSerializable { + + private String location; + private int tokenLineNumber; + private int tokenColumnNumber; + private String code; private static final long serialVersionUID = 1L; - private final String location; - private final int tokenLineNumber; - private final int tokenColumnNumber; - private final String code; public static final ExceptionMetadata EMPTY_METADATA = new ExceptionMetadata("none", 1, 0, ""); + /** + * Builds a new empty metadata object (for serialization and deserialization only) + */ + public ExceptionMetadata() { + this.location = ""; + this.tokenLineNumber = -1; + this.tokenColumnNumber = -1; + this.code = ""; + } + /** * Builds a new metadata object * @@ -118,4 +134,20 @@ public String toString() { + getTokenColumnNumber() + ":"; } + + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.location); + kryo.writeObject(output, this.tokenLineNumber); + kryo.writeObject(output, this.tokenColumnNumber); + kryo.writeObject(output, this.code); + } + + @Override + public void read(Kryo kryo, Input input) { + this.location = kryo.readObject(input, String.class); + this.tokenLineNumber = kryo.readObject(input, Integer.class); + this.tokenColumnNumber = kryo.readObject(input, Integer.class); + this.code = kryo.readObject(input, String.class); + } } diff --git a/src/main/java/org/rumbledb/items/AnnotatedItem.java b/src/main/java/org/rumbledb/items/AnnotatedItem.java index 9145197e8e..0e27d3eb4a 100644 --- a/src/main/java/org/rumbledb/items/AnnotatedItem.java +++ b/src/main/java/org/rumbledb/items/AnnotatedItem.java @@ -39,6 +39,9 @@ public AnnotatedItem() { public AnnotatedItem(Item itemToAnnotate, ItemType type) { this.itemToAnnotate = itemToAnnotate; this.type = type; + if (type == null) { + throw new OurBadException("It it not possible to annotate an item without a type."); + } if (type.getName() == null) { throw new OurBadException("It it not possible to annotate an item with an anonymous type."); } diff --git a/src/main/java/org/rumbledb/items/DateItem.java b/src/main/java/org/rumbledb/items/DateItem.java index dfab180d01..3c5cba77f4 100644 --- a/src/main/java/org/rumbledb/items/DateItem.java +++ b/src/main/java/org/rumbledb/items/DateItem.java @@ -35,6 +35,10 @@ public DateItem() { super(); this.value = value.toLocalDate().atStartOfDay(value.getOffset()).toOffsetDateTime(); this.hasTimeZone = hasTimeZone; + if (!hasTimeZone) { + this.value = this.value.withZoneRetainFields(DateTimeZone.UTC); + } + } DateItem(String dateTimeString) { @@ -84,6 +88,10 @@ private void getDateFromString(String dateString) { } } + private static boolean doesLexicalValueHaveNoTimeZone(String dateTimeString) { + return DateTimeItem.DATE_NOTIMEZONE_PATTERN.matcher(dateTimeString).matches(); + } + @Override public boolean equals(Object otherItem) { if (otherItem instanceof Item) { diff --git a/src/main/java/org/rumbledb/items/DateTimeItem.java b/src/main/java/org/rumbledb/items/DateTimeItem.java index 301266031f..e4b1b4fc4b 100644 --- a/src/main/java/org/rumbledb/items/DateTimeItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeItem.java @@ -35,6 +35,10 @@ public DateTimeItem() { super(); this.value = value; this.hasTimeZone = hasTimeZone; + if (!hasTimeZone) { + this.value = this.value.withZoneRetainFields(DateTimeZone.UTC); + } + } public DateTimeItem(String dateTimeString) { @@ -88,6 +92,10 @@ private void getDateTimeFromString(String dateTimeString) { } } + private static boolean doesLexicalValueHaveNoTimeZone(String dateTimeString) { + return DATETIME_NOTIMEZONE_PATTERN.matcher(dateTimeString).matches(); + } + @Override public boolean equals(Object otherItem) { if (otherItem instanceof Item) { diff --git a/src/main/java/org/rumbledb/items/DecimalItem.java b/src/main/java/org/rumbledb/items/DecimalItem.java index 69b1d207f5..3c19d4c20c 100644 --- a/src/main/java/org/rumbledb/items/DecimalItem.java +++ b/src/main/java/org/rumbledb/items/DecimalItem.java @@ -30,7 +30,6 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -133,7 +132,7 @@ public ItemType getDynamicType() { @Override public NativeClauseContext generateNativeQuery(NativeClauseContext context) { - return new NativeClauseContext(context, this.value.toString(), SequenceType.DECIMAL); + return new NativeClauseContext(context, "CAST (" + this.value + "BD AS DECIMAL(38, 19))"); } public boolean isNumeric() { diff --git a/src/main/java/org/rumbledb/items/DoubleItem.java b/src/main/java/org/rumbledb/items/DoubleItem.java index dd59e2a1f4..575b028359 100644 --- a/src/main/java/org/rumbledb/items/DoubleItem.java +++ b/src/main/java/org/rumbledb/items/DoubleItem.java @@ -33,7 +33,6 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -174,7 +173,7 @@ public ItemType getDynamicType() { @Override public NativeClauseContext generateNativeQuery(NativeClauseContext context) { - return new NativeClauseContext(context, "" + this.value, SequenceType.DOUBLE); + return new NativeClauseContext(context, "CAST (" + this.value + "D AS DOUBLE)"); } @Override diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 43b6da5f3d..79526af9ed 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -33,7 +33,6 @@ import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -188,7 +187,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext context) { if (Float.isNaN(this.value)) { return NativeClauseContext.NoNativeQuery; } - return new NativeClauseContext(context, "CAST (" + this.value + "D AS FLOAT)", SequenceType.FLOAT); + return new NativeClauseContext(context, "CAST (" + this.value + "F AS FLOAT)"); } @Override diff --git a/src/main/java/org/rumbledb/items/FunctionItem.java b/src/main/java/org/rumbledb/items/FunctionItem.java index d5719b7a8f..1f09274125 100644 --- a/src/main/java/org/rumbledb/items/FunctionItem.java +++ b/src/main/java/org/rumbledb/items/FunctionItem.java @@ -58,10 +58,9 @@ public class FunctionItem implements Item { private static final long serialVersionUID = 1L; + private FunctionIdentifier identifier; private List parameterNames; - - // signature contains type information for all parameters and the return value private FunctionSignature signature; private RuntimeIterator bodyIterator; private DynamicContext dynamicModuleContext; @@ -232,28 +231,20 @@ public int hashCode() { public void write(Kryo kryo, Output output) { kryo.writeObject(output, this.identifier); kryo.writeObject(output, this.parameterNames); - kryo.writeObject(output, this.signature.getParameterTypes()); - kryo.writeObject(output, this.signature.getReturnType()); - // kryo.writeObject(output, this.bodyIterator); + kryo.writeObject(output, this.signature); kryo.writeObject(output, this.localVariablesInClosure); - kryo.writeObject(output, this.RDDVariablesInClosure); - kryo.writeObject(output, this.dataFrameVariablesInClosure); - kryo.writeObject(output, this.dynamicModuleContext); - - // convert RuntimeIterator to byte[] data - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(this.bodyIterator); - oos.flush(); - byte[] data = bos.toByteArray(); - output.writeInt(data.length); - output.writeBytes(data); - } catch (Exception e) { + if (!this.RDDVariablesInClosure.isEmpty()) { + throw new OurBadException( + "We do not support serializing RDDs in function closures." + ); + } + if (!this.dataFrameVariablesInClosure.isEmpty()) { throw new OurBadException( - "Error converting functionItem-bodyRuntimeIterator to byte[]:" + e.getMessage() + "We do not support serializing DataFrames in function closures." ); } + kryo.writeObject(output, this.dynamicModuleContext); + kryo.writeClassAndObject(output, this.bodyIterator); } @SuppressWarnings("unchecked") @@ -261,26 +252,12 @@ public void write(Kryo kryo, Output output) { public void read(Kryo kryo, Input input) { this.identifier = kryo.readObject(input, FunctionIdentifier.class); this.parameterNames = kryo.readObject(input, ArrayList.class); - List parameters = kryo.readObject(input, ArrayList.class); - SequenceType returnType = kryo.readObject(input, SequenceType.class); - this.signature = new FunctionSignature(parameters, returnType); - // this.bodyIterator = kryo.readObject(input, RuntimeIterator.class); + this.signature = kryo.readObject(input, FunctionSignature.class); this.localVariablesInClosure = kryo.readObject(input, HashMap.class); - this.RDDVariablesInClosure = kryo.readObject(input, HashMap.class); - this.dataFrameVariablesInClosure = kryo.readObject(input, HashMap.class); + this.RDDVariablesInClosure = new HashMap<>(); + this.dataFrameVariablesInClosure = new HashMap<>(); this.dynamicModuleContext = kryo.readObject(input, DynamicContext.class); - - try { - int dataLength = input.readInt(); - byte[] data = input.readBytes(dataLength); - ByteArrayInputStream bis = new ByteArrayInputStream(data); - ObjectInputStream ois = new ObjectInputStream(bis); - this.bodyIterator = (RuntimeIterator) ois.readObject(); - } catch (Exception e) { - throw new OurBadException( - "Error converting functionItem-bodyRuntimeIterator to functionItem:" + e.getMessage() - ); - } + this.bodyIterator = (RuntimeIterator) kryo.readClassAndObject(input); } @Override diff --git a/src/main/java/org/rumbledb/items/IntItem.java b/src/main/java/org/rumbledb/items/IntItem.java index 37c7df6a72..b901f68611 100644 --- a/src/main/java/org/rumbledb/items/IntItem.java +++ b/src/main/java/org/rumbledb/items/IntItem.java @@ -31,7 +31,6 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -151,7 +150,7 @@ public ItemType getDynamicType() { @Override public NativeClauseContext generateNativeQuery(NativeClauseContext context) { - return new NativeClauseContext(context, "" + this.value, SequenceType.INT); + return new NativeClauseContext(context, "CAST (" + this.value + " AS INT)"); } public boolean isNumeric() { diff --git a/src/main/java/org/rumbledb/items/IntegerItem.java b/src/main/java/org/rumbledb/items/IntegerItem.java index a38122a040..f73390d34a 100644 --- a/src/main/java/org/rumbledb/items/IntegerItem.java +++ b/src/main/java/org/rumbledb/items/IntegerItem.java @@ -30,7 +30,6 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -140,7 +139,7 @@ public ItemType getDynamicType() { @Override public NativeClauseContext generateNativeQuery(NativeClauseContext context) { - return new NativeClauseContext(context, this.value.toString(), SequenceType.INTEGER); + return new NativeClauseContext(context, "CAST (" + this.value + "BD AS DECIMAL(38,0))"); } public boolean isNumeric() { diff --git a/src/main/java/org/rumbledb/items/StringItem.java b/src/main/java/org/rumbledb/items/StringItem.java index fc19ea73c5..4670486caa 100644 --- a/src/main/java/org/rumbledb/items/StringItem.java +++ b/src/main/java/org/rumbledb/items/StringItem.java @@ -31,7 +31,6 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -147,7 +146,7 @@ public ItemType getDynamicType() { @Override public NativeClauseContext generateNativeQuery(NativeClauseContext context) { - return new NativeClauseContext(context, '"' + this.value + '"', SequenceType.STRING); + return new NativeClauseContext(context, '"' + this.value + '"'); } @Override diff --git a/src/main/java/org/rumbledb/items/TimeItem.java b/src/main/java/org/rumbledb/items/TimeItem.java index 56f74fa6b5..7e7d9cb611 100644 --- a/src/main/java/org/rumbledb/items/TimeItem.java +++ b/src/main/java/org/rumbledb/items/TimeItem.java @@ -35,6 +35,9 @@ public TimeItem() { super(); this.value = value; this.hasTimeZone = hasTimeZone; + if (!hasTimeZone) { + this.value = this.value.withZoneRetainFields(DateTimeZone.UTC); + } } TimeItem(String timeString) { @@ -64,6 +67,10 @@ private void getTimeFromString(String timeString) { } } + private static boolean doesLexicalValueHaveNoTimeZone(String dateTimeString) { + return DateTimeItem.TIME_NOTIMEZONE_PATTERN.matcher(dateTimeString).matches(); + } + @Override public boolean equals(Object otherItem) { if (otherItem instanceof Item) { diff --git a/src/main/java/org/rumbledb/runtime/AtMostOneItemLocalRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/AtMostOneItemLocalRuntimeIterator.java index 8129d69339..44305e2379 100644 --- a/src/main/java/org/rumbledb/runtime/AtMostOneItemLocalRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/AtMostOneItemLocalRuntimeIterator.java @@ -33,6 +33,10 @@ import org.rumbledb.expressions.comparison.ComparisonExpression.ComparisonOperator; import org.rumbledb.types.BuiltinTypesCatalogue; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import sparksoniq.spark.SparkSessionManager; import org.rumbledb.runtime.misc.ComparisonIterator; @@ -47,6 +51,11 @@ public abstract class AtMostOneItemLocalRuntimeIterator extends RuntimeIterator private static final long serialVersionUID = 1L; private Item result; + protected AtMostOneItemLocalRuntimeIterator() { + super(); + this.result = null; + } + protected AtMostOneItemLocalRuntimeIterator( List children, RuntimeStaticContext staticContext @@ -197,4 +206,14 @@ public boolean getEffectiveBooleanValueOrCheckPosition(DynamicContext dynamicCon getMetadata() ); } + + @Override + public void write(Kryo kryo, Output output) { + super.write(kryo, output); + } + + @Override + public void read(Kryo kryo, Input input) { + super.read(kryo, input); + } } diff --git a/src/main/java/org/rumbledb/runtime/HybridRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/HybridRuntimeIterator.java index f6dfc708ac..09cee97781 100644 --- a/src/main/java/org/rumbledb/runtime/HybridRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/HybridRuntimeIterator.java @@ -43,6 +43,12 @@ public abstract class HybridRuntimeIterator extends RuntimeIterator { protected List result = null; private int currentResultIndex = 0; + protected HybridRuntimeIterator() { + super(); + this.result = null; + this.currentResultIndex = 0; + } + protected HybridRuntimeIterator( List children, RuntimeStaticContext staticContext diff --git a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java index 7198e0c1b4..5930d7b9ba 100644 --- a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java @@ -76,6 +76,15 @@ public abstract class RuntimeIterator implements RuntimeIteratorInterface, KryoS protected URI staticURI; // private StaticContext staticContext; + public RuntimeIterator() { + this.hasNext = false; + this.isOpen = false; + this.children = null; + this.currentDynamicContextForLocalExecution = null; + this.staticContext = null; + this.staticURI = null; + } + protected RuntimeIterator(List children, RuntimeStaticContext staticContext) { this.staticContext = staticContext; if (this.staticContext.getStaticType() == null) { @@ -238,6 +247,7 @@ public void reset(DynamicContext context) { @Override public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.staticContext); kryo.writeObject(output, this.children); // TODO serializer other fields } @@ -248,6 +258,7 @@ public void read(Kryo kryo, Input input) { this.hasNext = false; this.isOpen = false; this.currentDynamicContextForLocalExecution = null; + this.staticContext = kryo.readObject(input, RuntimeStaticContext.class); this.children = kryo.readObject(input, ArrayList.class); // TODO serializer other fields } diff --git a/src/main/java/org/rumbledb/runtime/arithmetics/AdditiveOperationIterator.java b/src/main/java/org/rumbledb/runtime/arithmetics/AdditiveOperationIterator.java index a9c62ff4ff..32e259a778 100644 --- a/src/main/java/org/rumbledb/runtime/arithmetics/AdditiveOperationIterator.java +++ b/src/main/java/org/rumbledb/runtime/arithmetics/AdditiveOperationIterator.java @@ -39,11 +39,12 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.BuiltinTypesCatalogue; -import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; import org.rumbledb.types.SequenceType.Arity; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; public class AdditiveOperationIterator extends AtMostOneItemLocalRuntimeIterator { @@ -122,7 +123,8 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { public static Item processItem(Item left, Item right, boolean isMinus) { // The integer 0 is considered the default neutral element for addition in sum(), even though // it is technically incompatible with durations. In the future, we should - // make sure an error is thrown if an actual 0 appears in the sum with durations. + // make sure an error is thrown if an actual 0 appears in the sum with + // durations. if (!isMinus && left.isInteger() && left.getIntegerValue().equals(BigInteger.ZERO)) { return right; } @@ -367,14 +369,14 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (leftResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (!leftResult.getResultingType().getArity().equals(Arity.One)) { + if (!this.leftIterator.getStaticType().getArity().equals(Arity.One)) { return NativeClauseContext.NoNativeQuery; } NativeClauseContext rightResult = this.rightIterator.generateNativeQuery(nativeClauseContext); if (rightResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (!rightResult.getResultingType().getArity().equals(Arity.One)) { + if (!this.rightIterator.getStaticType().getArity().equals(Arity.One)) { return NativeClauseContext.NoNativeQuery; } ItemType resultType; @@ -384,44 +386,38 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC leftResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM) && rightResult.getResultingType().getItemType().isNumeric() ) { - if (!rightResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM)) { + if (!this.rightIterator.getStaticType().isSubtypeOf(SequenceType.DOUBLE_QM)) { rightQuery = "(CAST (" + rightQuery + " AS DOUBLE))"; } - resultType = BuiltinTypesCatalogue.doubleItem; } else if ( rightResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM) && leftResult.getResultingType().getItemType().isNumeric() ) { - if (!leftResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM)) { + if (!this.leftIterator.getStaticType().isSubtypeOf(SequenceType.DOUBLE_QM)) { leftQuery = "(CAST (" + leftQuery + " AS DOUBLE))"; } - resultType = BuiltinTypesCatalogue.doubleItem; } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM) && rightResult.getResultingType().getItemType().isNumeric() ) { - if (!rightResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM)) { + if (!this.rightIterator.getStaticType().isSubtypeOf(SequenceType.FLOAT_QM)) { rightQuery = "(CAST (" + rightQuery + " AS FLOAT))"; } - resultType = BuiltinTypesCatalogue.floatItem; } else if ( rightResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM) && leftResult.getResultingType().getItemType().isNumeric() ) { - if (!leftResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM)) { + if (!this.leftIterator.getStaticType().isSubtypeOf(SequenceType.FLOAT_QM)) { leftQuery = "(CAST (" + leftQuery + " AS FLOAT))"; } - resultType = BuiltinTypesCatalogue.floatItem; } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.INTEGER_QM) && rightResult.getResultingType().isSubtypeOf(SequenceType.INTEGER_QM) ) { - resultType = BuiltinTypesCatalogue.integerItem; } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.DECIMAL_QM) && rightResult.getResultingType().isSubtypeOf(SequenceType.DECIMAL_QM) ) { - resultType = BuiltinTypesCatalogue.decimalItem; } else { return NativeClauseContext.NoNativeQuery; } diff --git a/src/main/java/org/rumbledb/runtime/arithmetics/MultiplicativeOperationIterator.java b/src/main/java/org/rumbledb/runtime/arithmetics/MultiplicativeOperationIterator.java index 0bcb4cc342..4f16b3de0d 100644 --- a/src/main/java/org/rumbledb/runtime/arithmetics/MultiplicativeOperationIterator.java +++ b/src/main/java/org/rumbledb/runtime/arithmetics/MultiplicativeOperationIterator.java @@ -38,8 +38,6 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.BuiltinTypesCatalogue; -import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; import org.rumbledb.types.SequenceType.Arity; @@ -546,14 +544,14 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (leftResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (!leftResult.getResultingType().getArity().equals(Arity.One)) { + if (!this.leftIterator.getStaticType().getArity().equals(Arity.One)) { return NativeClauseContext.NoNativeQuery; } NativeClauseContext rightResult = this.rightIterator.generateNativeQuery(nativeClauseContext); if (rightResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (!rightResult.getResultingType().getArity().equals(Arity.One)) { + if (!this.rightIterator.getStaticType().getArity().equals(Arity.One)) { return NativeClauseContext.NoNativeQuery; } ItemType resultType; @@ -563,48 +561,38 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC leftResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM) && rightResult.getResultingType().getItemType().isNumeric() ) { - if (!rightResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM)) { + if (!this.rightIterator.getStaticType().isSubtypeOf(SequenceType.DOUBLE_QM)) { rightQuery = "(CAST (" + rightQuery + " AS DOUBLE))"; } - resultType = BuiltinTypesCatalogue.doubleItem; } else if ( rightResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM) && leftResult.getResultingType().getItemType().isNumeric() ) { - if (!leftResult.getResultingType().isSubtypeOf(SequenceType.DOUBLE_QM)) { + if (!this.leftIterator.getStaticType().isSubtypeOf(SequenceType.DOUBLE_QM)) { leftQuery = "(CAST (" + leftQuery + " AS DOUBLE))"; } - resultType = BuiltinTypesCatalogue.doubleItem; } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM) && rightResult.getResultingType().getItemType().isNumeric() ) { - if (!rightResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM)) { + if (!this.rightIterator.getStaticType().isSubtypeOf(SequenceType.FLOAT_QM)) { rightQuery = "(CAST (" + rightQuery + " AS FLOAT))"; } - resultType = BuiltinTypesCatalogue.floatItem; } else if ( rightResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM) && leftResult.getResultingType().getItemType().isNumeric() ) { - if (!leftResult.getResultingType().isSubtypeOf(SequenceType.FLOAT_QM)) { + if (!this.leftIterator.getStaticType().isSubtypeOf(SequenceType.FLOAT_QM)) { leftQuery = "(CAST (" + leftQuery + " AS FLOAT))"; } - resultType = BuiltinTypesCatalogue.floatItem; } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.INTEGER_QM) && rightResult.getResultingType().isSubtypeOf(SequenceType.INTEGER_QM) ) { - if (this.multiplicativeOperator.equals(MultiplicativeExpression.MultiplicativeOperator.DIV)) { - resultType = BuiltinTypesCatalogue.decimalItem; - } else { - resultType = BuiltinTypesCatalogue.integerItem; - } } else if ( leftResult.getResultingType().isSubtypeOf(SequenceType.DECIMAL_QM) && rightResult.getResultingType().isSubtypeOf(SequenceType.DECIMAL_QM) ) { - resultType = BuiltinTypesCatalogue.decimalItem; } else { return NativeClauseContext.NoNativeQuery; } @@ -629,22 +617,19 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC resultingQuery = "( " + leftQuery + " * " + rightQuery + " )"; return new NativeClauseContext( nativeClauseContext, - resultingQuery, - new SequenceType(resultType, resultingArity) + resultingQuery ); case DIV: resultingQuery = "( " + leftQuery + " / " + rightQuery + " )"; return new NativeClauseContext( nativeClauseContext, - resultingQuery, - new SequenceType(resultType, resultingArity) + resultingQuery ); case MOD: resultingQuery = "( " + leftQuery + " % " + rightQuery + " )"; return new NativeClauseContext( nativeClauseContext, - resultingQuery, - new SequenceType(resultType, resultingArity) + resultingQuery ); default: return NativeClauseContext.NoNativeQuery; diff --git a/src/main/java/org/rumbledb/runtime/arithmetics/UnaryOperationIterator.java b/src/main/java/org/rumbledb/runtime/arithmetics/UnaryOperationIterator.java index 139b9f2a32..70ae6ce097 100644 --- a/src/main/java/org/rumbledb/runtime/arithmetics/UnaryOperationIterator.java +++ b/src/main/java/org/rumbledb/runtime/arithmetics/UnaryOperationIterator.java @@ -29,7 +29,6 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.SequenceType; import org.rumbledb.types.SequenceType.Arity; import java.math.BigDecimal; @@ -110,22 +109,21 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (leftResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (!leftResult.getResultingType().getArity().equals(Arity.One)) { + if (!this.child.getStaticType().getArity().equals(Arity.One)) { return NativeClauseContext.NoNativeQuery; } String leftQuery = leftResult.getResultingQuery(); - SequenceType resultType = leftResult.getResultingType(); if (this.negated) { String resultingQuery = "( " + " - " + leftQuery + " )"; - return new NativeClauseContext(nativeClauseContext, resultingQuery, resultType); + return new NativeClauseContext(nativeClauseContext, resultingQuery); } else { String resultingQuery = "( " + leftQuery + " )"; - return new NativeClauseContext(nativeClauseContext, resultingQuery, resultType); + return new NativeClauseContext(nativeClauseContext, resultingQuery); } } } diff --git a/src/main/java/org/rumbledb/runtime/control/AtMostOneItemIfRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/control/AtMostOneItemIfRuntimeIterator.java index f77614d0f8..3c7d9d0ebb 100644 --- a/src/main/java/org/rumbledb/runtime/control/AtMostOneItemIfRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/control/AtMostOneItemIfRuntimeIterator.java @@ -31,6 +31,10 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + public class AtMostOneItemIfRuntimeIterator extends AtMostOneItemLocalRuntimeIterator { diff --git a/src/main/java/org/rumbledb/runtime/flwor/FlworDataFrameUtils.java b/src/main/java/org/rumbledb/runtime/flwor/FlworDataFrameUtils.java index 4607d3925c..a81876295e 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/FlworDataFrameUtils.java +++ b/src/main/java/org/rumbledb/runtime/flwor/FlworDataFrameUtils.java @@ -82,7 +82,12 @@ import org.rumbledb.items.xml.DocumentItem; import org.rumbledb.items.xml.ElementItem; import org.rumbledb.items.xml.TextItem; +import org.rumbledb.runtime.arithmetics.AdditiveOperationIterator; import org.rumbledb.runtime.flwor.FlworDataFrameColumn.ColumnFormat; +import org.rumbledb.runtime.primary.VariableReferenceIterator; +import org.rumbledb.types.DerivedAtomicItemType; +import org.rumbledb.types.AtomicItemType; +import org.rumbledb.types.ItemItemType; import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; @@ -132,9 +137,13 @@ public static void registerKryoClassesKryo(Kryo kryo) { kryo.register(FunctionItem.class); kryo.register(FunctionIdentifier.class); kryo.register(Name.class); + kryo.register(SequenceType.class); kryo.register(SequenceType.Arity.class); kryo.register(ItemType.class); + kryo.register(ItemItemType.class); + kryo.register(AtomicItemType.class); + kryo.register(DerivedAtomicItemType.class); kryo.register(ArrayList.class); @@ -144,6 +153,9 @@ public static void registerKryoClassesKryo(Kryo kryo) { kryo.register(ElementItem.class); kryo.register(AttributeItem.class); kryo.register(TextItem.class); + + kryo.register(AdditiveOperationIterator.class); + kryo.register(VariableReferenceIterator.class); } public static byte[] serializeItem(Item toSerialize, Kryo kryo, Output output) { diff --git a/src/main/java/org/rumbledb/runtime/flwor/NativeClauseContext.java b/src/main/java/org/rumbledb/runtime/flwor/NativeClauseContext.java index 68e6e4d589..f595435234 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/NativeClauseContext.java +++ b/src/main/java/org/rumbledb/runtime/flwor/NativeClauseContext.java @@ -5,7 +5,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.expressions.flowr.FLWOR_CLAUSES; -import org.rumbledb.types.SequenceType; import sparksoniq.spark.SparkSessionManager; import java.util.ArrayList; diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java index dafe32cb97..c25438909c 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java @@ -574,8 +574,8 @@ private static NativeClauseContext createOrderExpression( // because of meaning mismatch between sparksql (where it is supposed to order by the i-th col) // and jsoniq (order by a constant, so no actual ordering is performed) if ( - (nativeQuery.getResultingType().isSubtypeOf(SequenceType.INTEGER_QM) - || nativeQuery.getResultingType().isSubtypeOf(SequenceType.INT_QM)) + (orderIterator.getIterator().getStaticType().isSubtypeOf(SequenceType.INTEGER_QM) + || orderIterator.getIterator().getStaticType().isSubtypeOf(SequenceType.INT_QM)) && nativeQuery.getResultingQuery().matches("\\s*-?\\s*\\d+\\s*") ) { orderSql.append('"'); diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java index 00559190f3..f905c49a94 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java @@ -125,6 +125,8 @@ public JavaRDD getRDDAux(DynamicContext context) { return result; } Dataset df = this.child.getDataFrame(context).getDataFrame(); + df.show(); + df.printSchema(); StructType oldSchema = df.schema(); List UDFcolumns = FlworDataFrameUtils.getColumns( oldSchema, diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java index 853b502f4a..a507150026 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java @@ -453,7 +453,7 @@ public static FlworDataFrame tryNativeQuery( .info( "Rumble was able to optimize a where clause to a native SQL query: " + String.format( - "select %s from (%s) where %s", + "select %s from (%s) where true and %s", FlworDataFrameUtils.getSQLColumnProjection(allColumns, false), nativeQuery.getView(), nativeQuery.getResultingQuery() @@ -464,7 +464,8 @@ public static FlworDataFrame tryNativeQuery( .sparkSession() .sql( String.format( - "select %s from (%s) where %s", + // Spark SQL but confusing where (FALSE) with a table and column name. + "select %s from (%s) where true and %s", FlworDataFrameUtils.getSQLColumnProjection(allColumns, false), nativeQuery.getView(), nativeQuery.getResultingQuery() diff --git a/src/main/java/org/rumbledb/runtime/flwor/udfs/DataFrameContext.java b/src/main/java/org/rumbledb/runtime/flwor/udfs/DataFrameContext.java index a51dedd78b..e8842db69b 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/udfs/DataFrameContext.java +++ b/src/main/java/org/rumbledb/runtime/flwor/udfs/DataFrameContext.java @@ -37,6 +37,7 @@ import org.rumbledb.runtime.flwor.FlworDataFrameColumn; import org.rumbledb.runtime.flwor.FlworDataFrameUtils; import org.rumbledb.types.ItemType; +import org.rumbledb.types.TypeMappings; import java.io.IOException; import java.io.Serializable; @@ -128,6 +129,12 @@ public void setFromRow(Row row, ItemType itemType) { } if (!column.isCount()) { List i = readColumnAsSequenceOfItems(row, itemType, columnIndex); + /* + * for (Item j : i) { + * System.err.println(j.getDynamicType()); + * System.err.println(j.serialize()); + * } + */ this.context.getVariableValues() .addVariableValue( column.getVariableName(), @@ -252,6 +259,9 @@ private List readColumnAsSequenceOfItems(Row row, ItemType itemType, int c return items; } } + if (itemType == null) { + itemType = TypeMappings.getItemTypeFromDataFrameDataType(dt); + } Item item = ItemParser.convertValueToItem(o, dt, ExceptionMetadata.EMPTY_METADATA, itemType); return Collections.singletonList(item); } diff --git a/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java index eed1500e60..574b4e22ab 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java @@ -29,6 +29,7 @@ import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; +import org.rumbledb.runtime.flwor.NativeClauseContext; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java index d1ee30b835..a7a6b6b09f 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java @@ -147,7 +147,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (SequenceType.Arity.OneOrMore.isSubtypeOf(value.getResultingType().getArity())) { return NativeClauseContext.NoNativeQuery; } - if (!value.getResultingType().getItemType().equals(BuiltinTypesCatalogue.floatItem)) { + if (!this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem)) { return NativeClauseContext.NoNativeQuery; } String resultingQuery = "( CAST (" diff --git a/src/main/java/org/rumbledb/runtime/logics/AndOperationIterator.java b/src/main/java/org/rumbledb/runtime/logics/AndOperationIterator.java index 0646ac901d..dd3a9f3d3b 100644 --- a/src/main/java/org/rumbledb/runtime/logics/AndOperationIterator.java +++ b/src/main/java/org/rumbledb/runtime/logics/AndOperationIterator.java @@ -80,14 +80,14 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC return NativeClauseContext.NoNativeQuery; } if ( - SequenceType.Arity.OneOrMore.isSubtypeOf(leftResult.getResultingType().getArity()) + SequenceType.Arity.OneOrMore.isSubtypeOf(this.leftIterator.getStaticType().getArity()) || SequenceType.Arity.OneOrMore.isSubtypeOf(rightResult.getResultingType().getArity()) ) { return NativeClauseContext.NoNativeQuery; } SequenceType.Arity resultingArity = (leftResult.getResultingType().getArity() == SequenceType.Arity.One - && rightResult.getResultingType().getArity() == SequenceType.Arity.One) + && this.leftIterator.getStaticType().getArity() == SequenceType.Arity.One) ? SequenceType.Arity.One : SequenceType.Arity.OneOrZero; String resultingQuery = "( " diff --git a/src/main/java/org/rumbledb/runtime/logics/NotOperationIterator.java b/src/main/java/org/rumbledb/runtime/logics/NotOperationIterator.java index 79f8fe41fc..353fa5f9c2 100644 --- a/src/main/java/org/rumbledb/runtime/logics/NotOperationIterator.java +++ b/src/main/java/org/rumbledb/runtime/logics/NotOperationIterator.java @@ -57,7 +57,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (childResult == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - if (SequenceType.Arity.OneOrMore.isSubtypeOf(childResult.getResultingType().getArity())) { + if (SequenceType.Arity.OneOrMore.isSubtypeOf(this.child.getStaticType().getArity())) { return NativeClauseContext.NoNativeQuery; } String resultingQuery = "( NOT " + childResult.getResultingQuery() + " )"; diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 901bfae4ce..299f23fd7d 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -37,7 +37,6 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; import java.math.BigDecimal; import java.math.BigInteger; @@ -522,19 +521,21 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC return NativeClauseContext.NoNativeQuery; } if ( - SequenceType.Arity.OneOrMore.isSubtypeOf(leftResult.getResultingType().getArity()) + SequenceType.Arity.OneOrMore.isSubtypeOf(this.leftIterator.getStaticType().getArity()) || - SequenceType.Arity.OneOrMore.isSubtypeOf(rightResult.getResultingType().getArity()) + SequenceType.Arity.OneOrMore.isSubtypeOf(this.rightIterator.getStaticType().getArity()) ) { return NativeClauseContext.NoNativeQuery; } // TODO: once done type system do proper comparison if ( - !(leftResult.getResultingType() != null - && rightResult.getResultingType() != null - && leftResult.getResultingType().getItemType().isNumeric() - && rightResult.getResultingType().getItemType().isNumeric() - || leftResult.getResultingType().getItemType().equals(rightResult.getResultingType().getItemType())) + !(this.leftIterator.getStaticType() != null + && this.rightIterator.getStaticType() != null + && this.leftIterator.getStaticType().getItemType().isNumeric() + && this.rightIterator.getStaticType().getItemType().isNumeric() + || this.leftIterator.getStaticType() + .getItemType() + .equals(this.rightIterator.getStaticType().getItemType())) ) { return NativeClauseContext.NoNativeQuery; } diff --git a/src/main/java/org/rumbledb/runtime/navigation/ArrayLookupIterator.java b/src/main/java/org/rumbledb/runtime/navigation/ArrayLookupIterator.java index 9c4a8c0143..915a8c503b 100644 --- a/src/main/java/org/rumbledb/runtime/navigation/ArrayLookupIterator.java +++ b/src/main/java/org/rumbledb/runtime/navigation/ArrayLookupIterator.java @@ -189,7 +189,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC initLookupPosition(newContext.getContext()); - ItemType resultType = newContext.getResultingType().getItemType(); + ItemType resultType = this.iterator.getStaticType().getItemType(); if (!(resultType.isArrayItemType())) { if (getConfiguration().doStaticAnalysis()) { throw new UnexpectedStaticTypeException( @@ -224,12 +224,6 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC ); return NativeClauseContext.NoNativeQuery; } - newContext.setResultingType( - new SequenceType( - resultType.getArrayContentFacet(), - SequenceType.Arity.OneOrZero - ) - ); newContext.setSchema(((ArrayType) newContext.getSchema()).elementType()); newContext.setResultingQuery(newContext.getResultingQuery() + "[" + (this.lookup - 1) + "]"); } diff --git a/src/main/java/org/rumbledb/runtime/navigation/ArrayUnboxingIterator.java b/src/main/java/org/rumbledb/runtime/navigation/ArrayUnboxingIterator.java index f4d63a42cd..1e7a65b3e3 100644 --- a/src/main/java/org/rumbledb/runtime/navigation/ArrayUnboxingIterator.java +++ b/src/main/java/org/rumbledb/runtime/navigation/ArrayUnboxingIterator.java @@ -142,7 +142,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (newContext == NativeClauseContext.NoNativeQuery) { return NativeClauseContext.NoNativeQuery; } - ItemType newContextType = newContext.getResultingType().getItemType(); + ItemType newContextType = this.iterator.getStaticType().getItemType(); if (!newContextType.isArrayItemType()) { // let control to UDF when what we are unboxing is not an array if (getConfiguration().doStaticAnalysis()) { @@ -160,12 +160,6 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC ); return NativeClauseContext.NoNativeQuery; } - newContext.setResultingType( - new SequenceType( - newContextType.getArrayContentFacet(), - SequenceType.Arity.ZeroOrMore - ) - ); List lateralViewPart = newContext.getLateralViewPart(); if (lateralViewPart.size() == 0) { diff --git a/src/main/java/org/rumbledb/runtime/navigation/ObjectLookupIterator.java b/src/main/java/org/rumbledb/runtime/navigation/ObjectLookupIterator.java index 41b7e07727..756e8f5750 100644 --- a/src/main/java/org/rumbledb/runtime/navigation/ObjectLookupIterator.java +++ b/src/main/java/org/rumbledb/runtime/navigation/ObjectLookupIterator.java @@ -264,8 +264,7 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (leftSchema instanceof StructType) { newContext = new NativeClauseContext( nativeClauseContext, - null, - nativeClauseContext.getResultingType() + null ); } else { if (leftSchema instanceof ArrayType) { diff --git a/src/main/java/org/rumbledb/runtime/primary/BooleanRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/primary/BooleanRuntimeIterator.java index b9dc00bfe3..b76af014ab 100644 --- a/src/main/java/org/rumbledb/runtime/primary/BooleanRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/BooleanRuntimeIterator.java @@ -28,6 +28,7 @@ import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; +import org.rumbledb.runtime.flwor.NativeClauseContext; public class BooleanRuntimeIterator extends AtMostOneItemLocalRuntimeIterator { @@ -53,5 +54,13 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC new SequenceType(BuiltinTypesCatalogue.booleanItem, SequenceType.Arity.One) ); } + + @Override + public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { + return new NativeClauseContext( + nativeClauseContext, + this.item.getBooleanValue() ? "(TRUE)" : "(FALSE)" + ); + } } diff --git a/src/main/java/org/rumbledb/runtime/primary/ContextExpressionIterator.java b/src/main/java/org/rumbledb/runtime/primary/ContextExpressionIterator.java index d0214264ee..14e6feabf9 100644 --- a/src/main/java/org/rumbledb/runtime/primary/ContextExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/ContextExpressionIterator.java @@ -21,7 +21,6 @@ package org.rumbledb.runtime.primary; import org.apache.spark.sql.types.DataType; -import org.apache.spark.sql.types.StructField; import org.apache.spark.sql.types.StructType; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; @@ -30,9 +29,6 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.flwor.FlworDataFrameUtils; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.ItemType; -import org.rumbledb.types.SequenceType; -import org.rumbledb.types.TypeMappings; import sparksoniq.spark.SparkSessionManager; @@ -83,15 +79,9 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC if (!FlworDataFrameUtils.isVariableAvailableAsNativeItem(structSchema, Name.CONTEXT_ITEM)) { return NativeClauseContext.NoNativeQuery; } - StructField field = structSchema.fields()[structSchema.fieldIndex( - SparkSessionManager.atomicJSONiqItemColumnName - )]; - DataType fieldType = field.dataType(); - ItemType variableType = TypeMappings.getItemTypeFromDataFrameDataType(fieldType); return new NativeClauseContext( nativeClauseContext, - "`" + SparkSessionManager.atomicJSONiqItemColumnName + "`", - new SequenceType(variableType, SequenceType.Arity.One) + "`" + SparkSessionManager.atomicJSONiqItemColumnName + "`" ); } } diff --git a/src/main/java/org/rumbledb/runtime/primary/DecimalRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/primary/DecimalRuntimeIterator.java index 5f4454bdea..3dc235fe7d 100644 --- a/src/main/java/org/rumbledb/runtime/primary/DecimalRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/DecimalRuntimeIterator.java @@ -25,7 +25,6 @@ import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.SequenceType; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import java.math.BigDecimal; @@ -50,8 +49,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { return new NativeClauseContext( nativeClauseContext, - "" + this.item.getDecimalValue(), - SequenceType.DECIMAL + "CAST (" + this.item.getDecimalValue() + "BD AS DECIMAL(38, 19))" ); } } diff --git a/src/main/java/org/rumbledb/runtime/primary/DoubleRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/primary/DoubleRuntimeIterator.java index d1600fb4c7..02b35e4733 100644 --- a/src/main/java/org/rumbledb/runtime/primary/DoubleRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/DoubleRuntimeIterator.java @@ -25,7 +25,6 @@ import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.SequenceType; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; public class DoubleRuntimeIterator extends AtMostOneItemLocalRuntimeIterator { @@ -49,8 +48,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { return new NativeClauseContext( nativeClauseContext, - "" + this.item.getDoubleValue(), - SequenceType.DOUBLE + "CAST (" + this.item.getDoubleValue() + "D AS DOUBLE)" ); } } diff --git a/src/main/java/org/rumbledb/runtime/primary/IntegerRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/primary/IntegerRuntimeIterator.java index 9c96c48fe4..f652bae245 100644 --- a/src/main/java/org/rumbledb/runtime/primary/IntegerRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/IntegerRuntimeIterator.java @@ -25,7 +25,11 @@ import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.SequenceType; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; public class IntegerRuntimeIterator extends AtMostOneItemLocalRuntimeIterator { @@ -51,8 +55,19 @@ public Item materializeFirstItemOrNull(DynamicContext context) { public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { return new NativeClauseContext( nativeClauseContext, - "" + this.item.getIntValue(), - SequenceType.INTEGER + "CAST (" + this.item.getIntValue() + "BD AS DECIMAL(38, 0))" ); } + + @Override + public void write(Kryo kryo, Output output) { + super.write(kryo, output); + kryo.writeClassAndObject(output, this.item); + } + + @Override + public void read(Kryo kryo, Input input) { + super.read(kryo, input); + this.item = (Item) kryo.readClassAndObject(input); + } } diff --git a/src/main/java/org/rumbledb/runtime/primary/StringRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/primary/StringRuntimeIterator.java index 60564d1751..35306dfd97 100644 --- a/src/main/java/org/rumbledb/runtime/primary/StringRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/StringRuntimeIterator.java @@ -27,7 +27,6 @@ import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.types.SequenceType; public class StringRuntimeIterator extends AtMostOneItemLocalRuntimeIterator { @@ -48,8 +47,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { return new NativeClauseContext( nativeClauseContext, - '"' + this.item.getStringValue() + '"', - SequenceType.STRING + '"' + this.item.getStringValue() + '"' ); } } diff --git a/src/main/java/org/rumbledb/runtime/primary/VariableReferenceIterator.java b/src/main/java/org/rumbledb/runtime/primary/VariableReferenceIterator.java index 9fbbcd8f1a..32b43fef89 100644 --- a/src/main/java/org/rumbledb/runtime/primary/VariableReferenceIterator.java +++ b/src/main/java/org/rumbledb/runtime/primary/VariableReferenceIterator.java @@ -33,6 +33,10 @@ import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.FlworDataFrameUtils; import org.rumbledb.runtime.flwor.NativeClauseContext; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; import org.rumbledb.types.TypeMappings; @@ -49,6 +53,13 @@ public class VariableReferenceIterator extends HybridRuntimeIterator { private List items = null; private int currentIndex = 0; + public VariableReferenceIterator() { + super(); + this.variableName = null; + this.items = null; + this.currentIndex = 0; + } + public VariableReferenceIterator( Name variableName, RuntimeStaticContext staticContext @@ -175,4 +186,16 @@ public Map getVariableDependencies() { result.put(this.variableName, DynamicContext.VariableDependency.FULL); return result; } + + @Override + public void write(Kryo kryo, Output output) { + super.write(kryo, output); + kryo.writeObject(output, this.variableName); + } + + @Override + public void read(Kryo kryo, Input input) { + super.read(kryo, input); + this.variableName = kryo.readObject(input, Name.class); + } } diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index bee3632e2d..7de63ebf5b 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -160,8 +160,18 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (StringUtils.isNumeric(item.getStringValue())) { result = ItemFactory.getInstance().createBooleanItem(item.castToIntValue() != 0); } else { - result = ItemFactory.getInstance() - .createBooleanItem(Boolean.parseBoolean(item.getStringValue().trim())); + switch (item.getStringValue()) { + case "true": + case "1": + result = ItemFactory.getInstance().createBooleanItem(true); + break; + case "false": + case "0": + result = ItemFactory.getInstance().createBooleanItem(false); + break; + default: + return null; + } } } else if (item.isInt()) { result = ItemFactory.getInstance().createBooleanItem(item.getIntValue() != 0); @@ -274,7 +284,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return result; } if (targetType.isSubtypeOf(BuiltinTypesCatalogue.intItem)) { - result = ItemFactory.getInstance().createIntItem(item.castToIntValue()); + result = ItemFactory.getInstance().createIntItem(result.castToIntValue()); if (targetType.equals(BuiltinTypesCatalogue.intItem)) { return result; } @@ -898,5 +908,210 @@ public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseC } return NativeClauseContext.NoNativeQuery; } + + @Override + public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { + NativeClauseContext value = this.children.get(0).generateNativeQuery(nativeClauseContext); + if (value.equals(NativeClauseContext.NoNativeQuery)) { + return NativeClauseContext.NoNativeQuery; + } + if (this.children.get(0).getStaticType().getArity() != Arity.One) { + return NativeClauseContext.NoNativeQuery; + } + String resultingQuery = ""; + if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.booleanItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "BOOLEAN" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.byteItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "BYTE" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.shortItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "SHORT" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.intItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "INT" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.longItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "LONG" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.integerItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "DECIMAL(38,0)" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.decimalItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "DECIMAL(38,19)" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.doubleItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "DOUBLE" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.floatItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.booleanItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.doubleItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.floatItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "FLOAT" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.stringItem)) { + if (this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + return NativeClauseContext.NoNativeQuery; + // resultingQuery = " (date_format(" + value.getResultingQuery() + ", \"yyyy-MM-dd'T'HH:mm:ss.SZZZZZ\")) + // "; + } else if (this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateItem)) { + if (getConfiguration().dateWithTimezone()) { + return NativeClauseContext.NoNativeQuery; + } + return NativeClauseContext.NoNativeQuery; + // resultingQuery = " (date_format(" + value.getResultingQuery() + ", 'yyyy-MM-dd')) "; + } else if ( + this.children.get(0).getStaticType().getItemType().isSubtypeOf(BuiltinTypesCatalogue.decimalItem) + ) { + resultingQuery = " (format_number(" + value.getResultingQuery() + ", '#.###################')) "; + } else { + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "STRING" + ")) "; + } + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.anyURIItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.anyURIItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "STRING" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.dateItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateTimeItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .equals(BuiltinTypesCatalogue.dateTimeStampItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + if (getConfiguration().dateWithTimezone()) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "DATE" + ")) "; + } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + if ( + !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.stringItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateItem) + && !this.children.get(0).getStaticType().getItemType().equals(BuiltinTypesCatalogue.dateTimeItem) + && !this.children.get(0) + .getStaticType() + .getItemType() + .equals(BuiltinTypesCatalogue.dateTimeStampItem) + ) { + return NativeClauseContext.NoNativeQuery; + } + resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "TIMESTAMP" + ")) "; + /* + * } else if (this.sequenceType.getItemType().equals(BuiltinTypesCatalogue.hexBinaryItem)) { + * resultingQuery = " (CAST (" + value.getResultingQuery() + " AS " + "BINARY" + ")) "; + * System.err.println("HexBinary"); + */ + } else { + return NativeClauseContext.NoNativeQuery; + } + return new NativeClauseContext( + nativeClauseContext, + resultingQuery + ); + } } diff --git a/src/main/java/org/rumbledb/server/MainPageHandler.java b/src/main/java/org/rumbledb/server/MainPageHandler.java index 39045d7329..c1458d4c0c 100644 --- a/src/main/java/org/rumbledb/server/MainPageHandler.java +++ b/src/main/java/org/rumbledb/server/MainPageHandler.java @@ -9,7 +9,6 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; -@SuppressWarnings("restriction") public class MainPageHandler implements HttpHandler { public MainPageHandler() { diff --git a/src/main/java/org/rumbledb/server/RumbleHttpHandler.java b/src/main/java/org/rumbledb/server/RumbleHttpHandler.java index cd52a78091..456f9b515f 100644 --- a/src/main/java/org/rumbledb/server/RumbleHttpHandler.java +++ b/src/main/java/org/rumbledb/server/RumbleHttpHandler.java @@ -28,7 +28,6 @@ import sparksoniq.spark.SparkSessionManager; -@SuppressWarnings("restriction") public class RumbleHttpHandler implements HttpHandler { private RumbleRuntimeConfiguration rumbleRuntimeConfiguration; diff --git a/src/main/java/org/rumbledb/server/RumbleServer.java b/src/main/java/org/rumbledb/server/RumbleServer.java index 2cf3797bc6..23fc13444e 100644 --- a/src/main/java/org/rumbledb/server/RumbleServer.java +++ b/src/main/java/org/rumbledb/server/RumbleServer.java @@ -10,7 +10,6 @@ import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpServer; -@SuppressWarnings("restriction") public class RumbleServer { private RumbleRuntimeConfiguration rumbleRuntimeConfiguration; diff --git a/src/main/java/org/rumbledb/server/ValidatorPageHandler.java b/src/main/java/org/rumbledb/server/ValidatorPageHandler.java index 8a98082802..9ecc9624a5 100644 --- a/src/main/java/org/rumbledb/server/ValidatorPageHandler.java +++ b/src/main/java/org/rumbledb/server/ValidatorPageHandler.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.io.OutputStream; -@SuppressWarnings("restriction") public class ValidatorPageHandler implements HttpHandler { public ValidatorPageHandler() { diff --git a/src/main/java/org/rumbledb/shell/RumbleJLineShell.java b/src/main/java/org/rumbledb/shell/RumbleJLineShell.java index 77f7a7acfb..36ac5267e8 100644 --- a/src/main/java/org/rumbledb/shell/RumbleJLineShell.java +++ b/src/main/java/org/rumbledb/shell/RumbleJLineShell.java @@ -22,7 +22,6 @@ import javassist.CannotCompileException; import org.apache.commons.io.IOUtils; -import org.apache.spark.SparkException; import org.jline.reader.EndOfFileException; import org.jline.reader.LineReader; import org.jline.reader.LineReaderBuilder; @@ -163,25 +162,10 @@ private void initialize() throws IOException { } private void handleException(Throwable ex, boolean showErrorInfo) { + ex = Main.unboxException(ex); if (ex != null) { if (ex instanceof EndOfFileException) { this.currentLine = RumbleJLineShell.EXIT_COMMAND; - } else if (ex instanceof SparkException) { - Throwable sparkExceptionCause = ex.getCause(); - if (sparkExceptionCause != null) { - handleException(sparkExceptionCause, showErrorInfo); - } else { - if (showErrorInfo) { - ex.printStackTrace(); - } - handleException( - new OurBadException( - "There was a problem with Spark, but Spark did not provide any cause or stracktrace. The message from Spark is: " - + ex.getMessage() - ), - showErrorInfo - ); - } } else if (ex instanceof RumbleException && !(ex instanceof OurBadException)) { System.err.println("⚠️ ️" + ex.getMessage()); if (showErrorInfo) { diff --git a/src/main/java/org/rumbledb/types/AtomicItemType.java b/src/main/java/org/rumbledb/types/AtomicItemType.java index 8109f1c6e2..453ac2b622 100644 --- a/src/main/java/org/rumbledb/types/AtomicItemType.java +++ b/src/main/java/org/rumbledb/types/AtomicItemType.java @@ -4,6 +4,10 @@ import org.rumbledb.config.RumbleRuntimeConfiguration; import org.rumbledb.context.Name; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import java.util.*; import static org.rumbledb.types.BuiltinTypesCatalogue.*; @@ -380,4 +384,24 @@ public String getSparkSQLType() { } throw new UnsupportedOperationException("getSparkSQLType is unsupported for " + this.getPrimitiveType()); } + + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.name); + kryo.writeObject(output, this.allowedFacets.size()); + for (FacetTypes f : this.allowedFacets) { + kryo.writeObject(output, f); + } + } + + @Override + public void read(Kryo kryo, Input input) { + this.name = kryo.readObject(input, Name.class); + int n = kryo.readObject(input, Integer.class); + this.allowedFacets = new HashSet<>(n); + for (int i = 0; i < n; ++i) { + FacetTypes t = kryo.readObject(input, FacetTypes.class); + this.allowedFacets.add(t); + } + } } diff --git a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java index 136ad24123..92715091f2 100644 --- a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java +++ b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java @@ -11,6 +11,10 @@ import org.rumbledb.expressions.comparison.ComparisonExpression; import org.rumbledb.runtime.misc.ComparisonIterator; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import java.util.List; import java.util.Set; @@ -18,11 +22,14 @@ public class DerivedAtomicItemType implements ItemType, com.esotericsoftware.kry private static final long serialVersionUID = 1L; + private ItemType baseType; private ItemType baseType; private ItemType primitiveType; private int typeTreeDepth; private boolean isUserDefined; private Name name; + private boolean isUserDefined; + private Name name; private Item minInclusive, maxInclusive, minExclusive, maxExclusive; private Integer minLength, length, maxLength, totalDigits, fractionDigits; private List constraints; @@ -32,6 +39,9 @@ public class DerivedAtomicItemType implements ItemType, com.esotericsoftware.kry DerivedAtomicItemType() { } + DerivedAtomicItemType() { + } + DerivedAtomicItemType(Name name, ItemType baseType, ItemType primitiveType, Facets facets) { this(name, baseType, primitiveType, facets, true); } @@ -705,4 +715,46 @@ public String getSparkSQLType() { } return this.primitiveType.getSparkSQLType(); } + + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.name); + kryo.writeClassAndObject(output, this.baseType); + kryo.writeClassAndObject(output, this.primitiveType); + kryo.writeObject(output, this.typeTreeDepth); + kryo.writeObject(output, this.isUserDefined); + kryo.writeClassAndObject(output, this.minInclusive); + kryo.writeClassAndObject(output, this.maxInclusive); + kryo.writeClassAndObject(output, this.minExclusive); + kryo.writeClassAndObject(output, this.maxExclusive); + kryo.writeObjectOrNull(output, this.minLength, Integer.class); + kryo.writeObjectOrNull(output, this.length, Integer.class); + kryo.writeObjectOrNull(output, this.maxLength, Integer.class); + kryo.writeObjectOrNull(output, this.totalDigits, Integer.class); + kryo.writeObjectOrNull(output, this.fractionDigits, Integer.class); + // kryo.writeObject(output, this.constraints); + // kryo.writeObjectOrNull(output, this.enumeration, ArrayList.class); + // kryo.writeObject(output, this.explicitTimezone); + } + + @Override + public void read(Kryo kryo, Input input) { + this.name = kryo.readObject(input, Name.class); + this.baseType = (ItemType) kryo.readClassAndObject(input); + this.primitiveType = (ItemType) kryo.readClassAndObject(input); + this.typeTreeDepth = kryo.readObject(input, Integer.class); + this.isUserDefined = kryo.readObject(input, Boolean.class); + this.minInclusive = (Item) kryo.readClassAndObject(input); + this.maxInclusive = (Item) kryo.readClassAndObject(input); + this.minExclusive = (Item) kryo.readClassAndObject(input); + this.maxExclusive = (Item) kryo.readClassAndObject(input); + this.minLength = kryo.readObjectOrNull(input, Integer.class); + this.length = kryo.readObjectOrNull(input, Integer.class); + this.maxLength = kryo.readObjectOrNull(input, Integer.class); + this.totalDigits = kryo.readObjectOrNull(input, Integer.class); + this.fractionDigits = kryo.readObjectOrNull(input, Integer.class); + // this.constraints = kryo.readObject(input, ArrayList.class); + // this.enumeration = kryo.readObjectOrNull(input, ArrayList.class); + // this.explicitTimezone = kryo.readObject(input, TimezoneFacet.class); + } } diff --git a/src/main/java/org/rumbledb/types/Facets.java b/src/main/java/org/rumbledb/types/Facets.java index 37b67515c6..b58624d77e 100644 --- a/src/main/java/org/rumbledb/types/Facets.java +++ b/src/main/java/org/rumbledb/types/Facets.java @@ -2,7 +2,7 @@ import org.rumbledb.api.Item; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; /** @@ -61,7 +61,7 @@ public static Facets createTimezoneFacets(TimezoneFacet explicitTimezone) { private Item minInclusive, maxInclusive; private Item minExclusive, maxExclusive; private Integer minLength, length, maxLength, totalDigits, fractionDigits; - private List constraints = Collections.emptyList(); + private List constraints = new ArrayList<>(); private List enumeration; private TimezoneFacet explicitTimezone; diff --git a/src/main/java/org/rumbledb/types/FunctionSignature.java b/src/main/java/org/rumbledb/types/FunctionSignature.java index 8e5369e121..e1b5e5513b 100644 --- a/src/main/java/org/rumbledb/types/FunctionSignature.java +++ b/src/main/java/org/rumbledb/types/FunctionSignature.java @@ -21,9 +21,15 @@ package org.rumbledb.types; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; -public class FunctionSignature implements Serializable { +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoSerializable; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + +public class FunctionSignature implements Serializable, KryoSerializable { private List parameterTypes; private SequenceType returnType; private boolean isUpdating; @@ -46,6 +52,11 @@ public FunctionSignature( this(parameterTypes, returnType, false); } + public FunctionSignature() { + this.parameterTypes = new ArrayList<>(); + this.returnType = SequenceType.ITEM_STAR; + } + public List getParameterTypes() { return this.parameterTypes; @@ -105,4 +116,18 @@ public String toString() { sb.append(this.returnType); return sb.toString(); } + + + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.parameterTypes); + kryo.writeObject(output, this.returnType); + } + + @SuppressWarnings("unchecked") + @Override + public void read(Kryo kryo, Input input) { + this.parameterTypes = kryo.readObject(input, ArrayList.class); + this.returnType = kryo.readObject(input, SequenceType.class); + } } diff --git a/src/main/java/org/rumbledb/types/ItemItemType.java b/src/main/java/org/rumbledb/types/ItemItemType.java index 831856e706..449fee457f 100644 --- a/src/main/java/org/rumbledb/types/ItemItemType.java +++ b/src/main/java/org/rumbledb/types/ItemItemType.java @@ -3,6 +3,10 @@ import org.rumbledb.config.RumbleRuntimeConfiguration; import org.rumbledb.context.Name; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import java.util.Set; /** @@ -88,4 +92,14 @@ public boolean isResolved() { public boolean isCompatibleWithDataFrames(RumbleRuntimeConfiguration configuration) { return false; } + + @Override + public void write(Kryo kryo, Output output) { + kryo.writeObject(output, this.name); + } + + @Override + public void read(Kryo kryo, Input input) { + this.name = kryo.readObject(input, Name.class); + } } diff --git a/src/main/java/org/rumbledb/types/ItemType.java b/src/main/java/org/rumbledb/types/ItemType.java index 2c0d06a423..95c50f16ee 100644 --- a/src/main/java/org/rumbledb/types/ItemType.java +++ b/src/main/java/org/rumbledb/types/ItemType.java @@ -27,6 +27,12 @@ import org.rumbledb.context.Name; import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoSerializable; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.kryo.KryoSerializable; @@ -477,4 +483,18 @@ default void resolve(DynamicContext context, ExceptionMetadata metadata) { default void resolve(StaticContext context, ExceptionMetadata metadata) { return; } + + @Override + default void write(Kryo kryo, Output output) { + throw new OurBadException( + "Kryo serialization for type " + this.getClass().getCanonicalName() + " not implemented." + ); + } + + @Override + default void read(Kryo kryo, Input input) { + throw new OurBadException( + "Kryo deserialization for type " + this.getClass().getCanonicalName() + " not implemented." + ); + } } diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index c73f68accc..25d22eb3b4 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -27,12 +27,17 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.KryoSerializable; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; + import java.io.Serializable; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -public class SequenceType implements Serializable { +public class SequenceType implements Serializable, KryoSerializable { private static final long serialVersionUID = 1L; private ItemType itemType; @@ -749,5 +754,16 @@ public static SequenceType createSequenceType(String userFriendlyName) { } + @Override + public void write(Kryo kryo, Output output) { + kryo.writeClassAndObject(output, this.itemType); + kryo.writeObject(output, this.arity); + } + + @Override + public void read(Kryo kryo, Input input) { + this.itemType = (ItemType) kryo.readClassAndObject(input); + this.arity = kryo.readObject(input, Arity.class); + } } diff --git a/src/main/java/org/rumbledb/types/TypeMappings.java b/src/main/java/org/rumbledb/types/TypeMappings.java index 2e44041932..0444470ca5 100644 --- a/src/main/java/org/rumbledb/types/TypeMappings.java +++ b/src/main/java/org/rumbledb/types/TypeMappings.java @@ -125,7 +125,7 @@ public static ItemType getItemTypeFromDataFrameDataType(DataType dataType) { return BuiltinTypesCatalogue.dateItem; } if (DataTypes.TimestampType.equals(dataType)) { - return BuiltinTypesCatalogue.dateTimeItem; + return BuiltinTypesCatalogue.dateTimeStampItem; } if (DataTypes.BinaryType.equals(dataType)) { return BuiltinTypesCatalogue.hexBinaryItem; diff --git a/src/main/java/sparksoniq/spark/SparkSessionManager.java b/src/main/java/sparksoniq/spark/SparkSessionManager.java index 9a234d8650..d34f6b70b5 100644 --- a/src/main/java/sparksoniq/spark/SparkSessionManager.java +++ b/src/main/java/sparksoniq/spark/SparkSessionManager.java @@ -137,6 +137,7 @@ private void setDefaultConfiguration() { "spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog" ); + this.configuration.set("spark.sql.ansi.enabled", "true"); // enables throwing errors in SPark SQL if (!this.configuration.contains("spark.master")) { this.configuration.set("spark.master", "local[*]"); } diff --git a/src/test/java/iq/RuntimeTests.java b/src/test/java/iq/RuntimeTests.java index fb4a724293..f31ad2a78d 100644 --- a/src/test/java/iq/RuntimeTests.java +++ b/src/test/java/iq/RuntimeTests.java @@ -120,6 +120,7 @@ public static void setupSparkSession() { sparkConfiguration.set("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog"); // enables // delta // store + sparkConfiguration.set("spark.sql.ansi.enabled", "true"); // prevents spark from failing to start on MacOS when disconnected from the internet sparkConfiguration.set("spark.driver.host", "127.0.0.1"); diff --git a/src/test/java/iq/base/AnnotationsTestsBase.java b/src/test/java/iq/base/AnnotationsTestsBase.java index c3a7dff39a..78c8189144 100644 --- a/src/test/java/iq/base/AnnotationsTestsBase.java +++ b/src/test/java/iq/base/AnnotationsTestsBase.java @@ -195,8 +195,17 @@ protected void testAnnotations(String path, RumbleRuntimeConfiguration configura ) { try { checkExpectedOutput(this.currentAnnotation.getOutput(), sequence); + } catch (RumbleException exception) { + String errorOutput = exception.getMessage(); + checkErrorCode( + errorOutput, + this.currentAnnotation.getErrorCode(), + this.currentAnnotation.getErrorMetadata() + ); + return; } catch (Exception exception) { String errorOutput = exception.getMessage(); + exception.printStackTrace(); checkErrorCode( errorOutput, this.currentAnnotation.getErrorCode(), diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/castError1.jq b/src/test/resources/test_files/runtime-native-flwor/literals/castError1.jq new file mode 100644 index 0000000000..bab0e733c3 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/castError1.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldCrash; ErrorCode="XPTY0004"; ErrorMetadata="LINE:4:COLUMN:10:" :) +for $i in parallelize((1 to 10), 10) +let $a := date("2023-01-01") +let $b := xs:boolean($a) +return $b diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/castError2.jq b/src/test/resources/test_files/runtime-native-flwor/literals/castError2.jq new file mode 100644 index 0000000000..0cb0698883 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/castError2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldCrash; ErrorCode="FORG0001" :) +for $i in parallelize((1 to 10), 10) +let $a := xs:boolean("falsea") +return $a diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/decimal.jq b/src/test/resources/test_files/runtime-native-flwor/literals/decimal.jq new file mode 100644 index 0000000000..9689d5496f --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/decimal.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="(123456792.4123456789, 123456793.4123456789, 123456794.4123456789, 123456795.4123456789, 123456796.4123456789, 123456797.4123456789, 123456798.4123456789, 123456799.4123456789, 123456800.4123456789, 123456801.4123456789, 123456802.4123456789, 123456803.4123456789, 123456804.4123456789, 123456805.4123456789, 123456806.4123456789, 123456807.4123456789, 123456808.4123456789, 123456809.4123456789, 123456810.4123456789, 123456811.4123456789, 123456812.4123456789, 123456813.4123456789, 123456814.4123456789, 123456815.4123456789, 123456816.4123456789, 123456817.4123456789, 123456818.4123456789, 123456819.4123456789, 123456820.4123456789, 123456821.4123456789, 123456822.4123456789, 123456823.4123456789, 123456824.4123456789, 123456825.4123456789, 123456826.4123456789, 123456827.4123456789, 123456828.4123456789, 123456829.4123456789, 123456830.4123456789, 123456831.4123456789, 123456832.4123456789, 123456833.4123456789, 123456834.4123456789, 123456835.4123456789, 123456836.4123456789, 123456837.4123456789, 123456838.4123456789, 123456839.4123456789, 123456840.4123456789, 123456841.4123456789, 123456842.4123456789, 123456843.4123456789, 123456844.4123456789, 123456845.4123456789, 123456846.4123456789, 123456847.4123456789, 123456848.4123456789, 123456849.4123456789, 123456850.4123456789, 123456851.4123456789, 123456852.4123456789, 123456853.4123456789, 123456854.4123456789, 123456855.4123456789, 123456856.4123456789, 123456857.4123456789, 123456858.4123456789, 123456859.4123456789, 123456860.4123456789, 123456861.4123456789, 123456862.4123456789, 123456863.4123456789, 123456864.4123456789, 123456865.4123456789, 123456866.4123456789, 123456867.4123456789, 123456868.4123456789, 123456869.4123456789, 123456870.4123456789, 123456871.4123456789, 123456872.4123456789, 123456873.4123456789, 123456874.4123456789, 123456875.4123456789, 123456876.4123456789, 123456877.4123456789, 123456878.4123456789, 123456879.4123456789, 123456880.4123456789, 123456881.4123456789, 123456882.4123456789, 123456883.4123456789, 123456884.4123456789, 123456885.4123456789, 123456886.4123456789, 123456887.4123456789, 123456888.4123456789, 123456889.4123456789, 123456890.4123456789, 123456891.4123456789)" :) +for $i in parallelize((1 to 100) ! ($$ cast as decimal), 10) +let $a := decimal(2.4) +let $b := 123456789.0123456789 +let $j := $i + $a + $b +return $j diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/double.jq b/src/test/resources/test_files/runtime-native-flwor/literals/double.jq new file mode 100644 index 0000000000..66748e6d62 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/double.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="(31003, 31004, 31005, 31006, 31007, 31008, 31009, 31010, 31011, 31012, 31013, 31014, 31015, 31016, 31017, 31018, 31019, 31020, 31021, 31022, 31023, 31024, 31025, 31026, 31027, 31028, 31029, 31030, 31031, 31032, 31033, 31034, 31035, 31036, 31037, 31038, 31039, 31040, 31041, 31042, 31043, 31044, 31045, 31046, 31047, 31048, 31049, 31050, 31051, 31052, 31053, 31054, 31055, 31056, 31057, 31058, 31059, 31060, 31061, 31062, 31063, 31064, 31065, 31066, 31067, 31068, 31069, 31070, 31071, 31072, 31073, 31074, 31075, 31076, 31077, 31078, 31079, 31080, 31081, 31082, 31083, 31084, 31085, 31086, 31087, 31088, 31089, 31090, 31091, 31092, 31093, 31094, 31095, 31096, 31097, 31098, 31099, 31100, 31101, 31102)" :) +for $i in parallelize((1 to 100) ! ($$ cast as double), 10) +let $a := double(2) +let $b := 3.1e4 +let $j := $i + $a + $b +return $j diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/float.jq b/src/test/resources/test_files/runtime-native-flwor/literals/float.jq new file mode 100644 index 0000000000..1ea3116006 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/float.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102)" :) +for $i in parallelize((1 to 100) ! ($$ cast as float), 10) +let $a := float(2) +let $j := $i + $a +return $j diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/int.jq b/src/test/resources/test_files/runtime-native-flwor/literals/int.jq new file mode 100644 index 0000000000..0865437938 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/int.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102)" :) +for $i as int in parallelize((1 to 100) ! ($$ cast as int), 10) +let $a := int(2) +let $j := $i + $a +return $j diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/integer.jq b/src/test/resources/test_files/runtime-native-flwor/literals/integer.jq new file mode 100644 index 0000000000..01236e0f37 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/integer.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="(1234567890123456792, 1234567890123456793, 1234567890123456794, 1234567890123456795, 1234567890123456796, 1234567890123456797, 1234567890123456798, 1234567890123456799, 1234567890123456800, 1234567890123456801, 1234567890123456802, 1234567890123456803, 1234567890123456804, 1234567890123456805, 1234567890123456806, 1234567890123456807, 1234567890123456808, 1234567890123456809, 1234567890123456810, 1234567890123456811, 1234567890123456812, 1234567890123456813, 1234567890123456814, 1234567890123456815, 1234567890123456816, 1234567890123456817, 1234567890123456818, 1234567890123456819, 1234567890123456820, 1234567890123456821, 1234567890123456822, 1234567890123456823, 1234567890123456824, 1234567890123456825, 1234567890123456826, 1234567890123456827, 1234567890123456828, 1234567890123456829, 1234567890123456830, 1234567890123456831, 1234567890123456832, 1234567890123456833, 1234567890123456834, 1234567890123456835, 1234567890123456836, 1234567890123456837, 1234567890123456838, 1234567890123456839, 1234567890123456840, 1234567890123456841, 1234567890123456842, 1234567890123456843, 1234567890123456844, 1234567890123456845, 1234567890123456846, 1234567890123456847, 1234567890123456848, 1234567890123456849, 1234567890123456850, 1234567890123456851, 1234567890123456852, 1234567890123456853, 1234567890123456854, 1234567890123456855, 1234567890123456856, 1234567890123456857, 1234567890123456858, 1234567890123456859, 1234567890123456860, 1234567890123456861, 1234567890123456862, 1234567890123456863, 1234567890123456864, 1234567890123456865, 1234567890123456866, 1234567890123456867, 1234567890123456868, 1234567890123456869, 1234567890123456870, 1234567890123456871, 1234567890123456872, 1234567890123456873, 1234567890123456874, 1234567890123456875, 1234567890123456876, 1234567890123456877, 1234567890123456878, 1234567890123456879, 1234567890123456880, 1234567890123456881, 1234567890123456882, 1234567890123456883, 1234567890123456884, 1234567890123456885, 1234567890123456886, 1234567890123456887, 1234567890123456888, 1234567890123456889, 1234567890123456890, 1234567890123456891)" :) +for $i in parallelize((1 to 100) ! ($$ cast as integer), 10) +let $a := integer(2) +let $b := 1234567890123456789 +let $j := $i + integer(2) + 1234567890123456789 +return $j diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/types-dates.jq b/src/test/resources/test_files/runtime-native-flwor/literals/types-dates.jq new file mode 100644 index 0000000000..158a40af53 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/types-dates.jq @@ -0,0 +1,16 @@ +(:JIQS: ShouldRun; Output="({ "string10" : "2023-05-12", "string11" : "2023-05-12T12:34:56-07:00", "date" : "2023-05-12", "dateTimeStamp" : "2023-05-12T12:34:56+02:00", "dateTimeStamp2" : "2023-05-12T00:00:00Z" }, { "string10" : "2023-05-12", "string11" : "2023-05-12T12:34:56-07:00", "date" : "2023-05-12", "dateTimeStamp" : "2023-05-12T12:34:56+02:00", "dateTimeStamp2" : "2023-05-12T00:00:00Z" })" :) +for $i in parallelize((1 to 2), 10) +let $string10 := string(date("2023-05-12")) +let $string11 := string(dateTimeStamp("2023-05-12T12:34:56-07:00")) +let $date := date("2023-05-12") +let $date2 := date(dateTimeStamp("2023-05-12T12:34:56Z")) +let $dateTimeStamp := dateTimeStamp("2023-05-12T12:34:56+02:00") +let $dateTimeStamp2 := dateTimeStamp($date) +return { + "string10": $string10, + "string11": $string11, + "date" : $date, +(: "date2" : $date2, :) + "dateTimeStamp" : $dateTimeStamp, + "dateTimeStamp2" : $dateTimeStamp2 +} diff --git a/src/test/resources/test_files/runtime-native-flwor/literals/types.jq b/src/test/resources/test_files/runtime-native-flwor/literals/types.jq new file mode 100644 index 0000000000..48e81097a5 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/literals/types.jq @@ -0,0 +1,178 @@ +(:JIQS: ShouldRun; Output="({ "boolean" : true, "boolean2" : false, "boolean3" : false, "boolean4" : false, "boolean5" : false, "boolean6" : true, "boolean7" : true, "boolean8" : true, "boolean9" : true, "boolean10" : true, "byte" : 12, "byte2" : 1, "byte3" : 0, "byte4" : 1, "byte5" : 2, "byte6" : 3, "short" : 12345, "short2" : 1, "short3" : 0, "short4" : 1, "short5" : 2, "short6" : 3, "int" : 12345, "int2" : 122345, "int3" : 1, "int4" : 0, "int5" : 1, "int6" : 2, "int7" : 3, "long" : 12345, "long2" : 12345, "long3" : 123546789000000, "long4" : 1, "long5" : 0, "long6" : 1, "long7" : 2, "long8" : 3, "integer" : 1235467890000001230498761230948, "integer2" : 12345, "integer3" : 1, "integer4" : 0, "integer5" : 1, "integer6" : 2, "integer7" : 3, "decimal" : 12354678900000.01230498761230948, "decimal2" : 12, "decimal3" : 12345, "decimal4" : 12345, "decimal5" : 12354678900000, "decimal6" : 1, "decimal7" : 0, "decimal8" : 1, "decimal9" : 2, "double" : 1.2354678900000012E13, "double2" : 0, "double3" : 12, "double4" : 12345, "double5" : 12345, "double6" : 12345, "double7" : 1.2354678900000012E30, "double8" : 1.2354678900000012E13, "double9" : 1, "double10" : 0, "float" : 1.23546789E13, "float2" : 0, "float3" : 12, "float4" : 12345, "float5" : 12345, "float6" : 12345, "float7" : 1.23546786E30, "float8" : 1.23546789E13, "float9" : 1, "float10" : 0, "string" : "123465789", "string2" : "12", "string3" : "12345", "string4" : "12345", "string5" : "12345", "string6" : "1235467890000001230498761230948", "string7" : "12354678900000.01230498761230948", "string8" : "1.2354678900000012E13", "string9" : "1.23546789E13", "string12" : "1ABF", "anyURI" : "123465789", "hexBinary" : "1ABF", "null" : null }, { "boolean" : true, "boolean2" : false, "boolean3" : false, "boolean4" : false, "boolean5" : false, "boolean6" : true, "boolean7" : true, "boolean8" : true, "boolean9" : true, "boolean10" : true, "byte" : 12, "byte2" : 1, "byte3" : 0, "byte4" : 1, "byte5" : 2, "byte6" : 3, "short" : 12345, "short2" : 1, "short3" : 0, "short4" : 1, "short5" : 2, "short6" : 3, "int" : 12345, "int2" : 122345, "int3" : 1, "int4" : 0, "int5" : 1, "int6" : 2, "int7" : 3, "long" : 12345, "long2" : 12345, "long3" : 123546789000000, "long4" : 1, "long5" : 0, "long6" : 1, "long7" : 2, "long8" : 3, "integer" : 1235467890000001230498761230948, "integer2" : 12345, "integer3" : 1, "integer4" : 0, "integer5" : 1, "integer6" : 2, "integer7" : 3, "decimal" : 12354678900000.01230498761230948, "decimal2" : 12, "decimal3" : 12345, "decimal4" : 12345, "decimal5" : 12354678900000, "decimal6" : 1, "decimal7" : 0, "decimal8" : 1, "decimal9" : 2, "double" : 1.2354678900000012E13, "double2" : 0, "double3" : 12, "double4" : 12345, "double5" : 12345, "double6" : 12345, "double7" : 1.2354678900000012E30, "double8" : 1.2354678900000012E13, "double9" : 1, "double10" : 0, "float" : 1.23546789E13, "float2" : 0, "float3" : 12, "float4" : 12345, "float5" : 12345, "float6" : 12345, "float7" : 1.23546786E30, "float8" : 1.23546789E13, "float9" : 1, "float10" : 0, "string" : "123465789", "string2" : "12", "string3" : "12345", "string4" : "12345", "string5" : "12345", "string6" : "1235467890000001230498761230948", "string7" : "12354678900000.01230498761230948", "string8" : "1.2354678900000012E13", "string9" : "1.23546789E13", "string12" : "1ABF", "anyURI" : "123465789", "hexBinary" : "1ABF", "null" : null })" :) +for $i in parallelize((1 to 2), 10) +let $boolean := boolean("false") +let $boolean := boolean(anyURI("false")) +let $boolean2 := boolean(integer(0)) +let $boolean3 := boolean(decimal(0)) +let $boolean4 := boolean(double(0)) +let $boolean5 := boolean(float(0)) +let $boolean6 := boolean("true") +let $boolean6 := boolean(anyURI("true")) +let $boolean7 := boolean(integer(1)) +let $boolean8 := boolean(decimal(1)) +let $boolean9 := boolean(double(1)) +let $boolean10 := boolean(float(1)) +let $byte := byte("12") +let $byte2 := byte(true) +let $byte3 := byte(false) +let $byte4 := byte(double(1)) +let $byte5 := byte(float(2)) +let $byte6 := byte(decimal(3)) +let $short := short("12345") +let $short2 := short(true) +let $short3 := short(false) +let $short4 := short(double(1)) +let $short5 := short(float(2)) +let $short6 := short(decimal(3)) +let $int := int($short) +let $int2 := int("122345") +let $int3 := int(true) +let $int4 := int(false) +let $int5 := int(double(1)) +let $int6 := int(float(2)) +let $int7 := int(decimal(3)) +let $long := long($int) +let $long2 := long($short) +let $long3 := long("123546789000000") +let $long4 := long(true) +let $long5 := long(false) +let $long6 := long(double(1)) +let $long7 := long(float(2)) +let $long8 := long(decimal(3)) +let $integer := integer("1235467890000001230498761230948") +let $integer2 := integer($int) +let $integer3 := integer(true) +let $integer4 := integer(false) +let $integer5 := integer(double(1)) +let $integer6 := integer(float(2)) +let $integer7 := integer(decimal(3)) +let $decimal := decimal("12354678900000.01230498761230948") +let $decimal2 := decimal($byte) +let $decimal3 := decimal($short) +let $decimal4 := decimal($int) +let $decimal5 := decimal(integer("12354678900000")) +let $decimal6 := decimal(true) +let $decimal7 := decimal(false) +let $decimal8 := decimal(double(1)) +let $decimal9 := decimal(float(2)) +let $double := double($decimal) +let $double2 := double("1234.345e-2345") +let $double3 := double($byte) +let $double4 := double($short) +let $double5 := double($int) +let $double6 := double($long) +let $double7 := double($integer) +let $double8 := double($decimal) +let $double9 := double(true) +let $double10 := double(false) +let $float := float($decimal) +let $float2 := float("1234.345e-2345") +let $float3 := float($byte) +let $float4 := float($short) +let $float5 := float($int) +let $float6 := float($long) +let $float7 := float($integer) +let $float8 := float($decimal) +let $float9 := float(true) +let $float10 := float(false) +let $string := string(123465789) +let $string2 := string($byte) +let $string3 := string($short) +let $string4 := string($int) +let $string5 := string($long) +let $string6 := string($integer) +let $string7 := string($decimal) +let $string8 := string($double) +let $string9 := string($float) +let $string12 := string(hexBinary("1ABF")) +let $anyURI := anyURI($string) +let $hexBinary := hexBinary("1ABF") +let $null := "null" cast as null +return { + "boolean" : $boolean, + "boolean2" : $boolean2, + "boolean3" : $boolean3, + "boolean4" : $boolean4, + "boolean5" : $boolean5, + "boolean6" : $boolean6, + "boolean7" : $boolean7, + "boolean8" : $boolean8, + "boolean9" : $boolean9, + "boolean10" : $boolean10, + "byte" : $byte, + "byte2" : $byte2, + "byte3" : $byte3, + "byte4" : $byte4, + "byte5" : $byte5, + "byte6" : $byte6, + "short" : $short, + "short2" : $short2, + "short3" : $short3, + "short4" : $short4, + "short5" : $short5, + "short6" : $short6, + "int" : $int, + "int2" : $int2, + "int3" : $int3, + "int4" : $int4, + "int5" : $int5, + "int6" : $int6, + "int7" : $int7, + "long" : $long, + "long2" : $long2, + "long3" : $long3, + "long4" : $long4, + "long5" : $long5, + "long6" : $long6, + "long7" : $long7, + "long8" : $long8, + "integer" : $integer, + "integer2" : $integer2, + "integer3" : $integer3, + "integer4" : $integer4, + "integer5" : $integer5, + "integer6" : $integer6, + "integer7" : $integer7, + "decimal" : $decimal, + "decimal2" : $decimal2, + "decimal3" : $decimal3, + "decimal4" : $decimal4, + "decimal5" : $decimal5, + "decimal6" : $decimal6, + "decimal7" : $decimal7, + "decimal8" : $decimal8, + "decimal9" : $decimal9, + "double" : $double, + "double2" : $double2, + "double3" : $double3, + "double4" : $double4, + "double5" : $double5, + "double6" : $double6, + "double7" : $double7, + "double8" : $double8, + "double9" : $double9, + "double10" : $double10, + "float" : $float, + "float2" : $float2, + "float3" : $float3, + "float4" : $float4, + "float5" : $float5, + "float6" : $float6, + "float7" : $float7, + "float8" : $float8, + "float9" : $float9, + "float10" : $float10, + "string": $string, + "string2": $string2, + "string3": $string3, + "string4": $string4, + "string5": $string5, + "string6": $string6, + "string7": $string7, + "string8": $string8, + "string9": $string9, + "string12": $string12, + "anyURI" : $anyURI, + "hexBinary" : $hexBinary, + "null" : $null +}