From b1f9a3dbee5b6af03aafd42336dc8a2646a822e2 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 7 Jun 2021 19:18:02 +0200 Subject: [PATCH 001/142] test with error --- .../strings/LowerCaseFunctionIterator.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java index 74befc29bd..19131e1c15 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java @@ -21,16 +21,18 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; +import java.util.Locale; -public class LowerCaseFunctionIterator extends LocalFunctionCallIterator { +public class LowerCaseFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -42,6 +44,20 @@ public LowerCaseFunctionIterator( super(arguments, executionMode, iteratorMetadata); } + @Override + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item stringItem = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (stringItem == null) { + return ItemFactory.getInstance().createStringItem("test"); + //return ItemFactory.getInstance().createStringItem(""); + } else { + String input = stringItem.getStringValue(); + return ItemFactory.getInstance().createStringItem(input.toUpperCase()); + } + + } + + /* @Override public Item next() { if (this.hasNext) { @@ -62,4 +78,5 @@ public Item next() { getMetadata() ); } + */ } From e6942f202a28a542a17d07684e3f0072bc182f89 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 7 Jun 2021 19:49:34 +0200 Subject: [PATCH 002/142] AtMostOneItem LowerCaseFunction --- .../strings/LowerCaseFunctionIterator.java | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java index 19131e1c15..260d145123 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java @@ -47,36 +47,14 @@ public LowerCaseFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { Item stringItem = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (stringItem == null) { - return ItemFactory.getInstance().createStringItem("test"); - //return ItemFactory.getInstance().createStringItem(""); + return ItemFactory.getInstance().createStringItem(""); } else { String input = stringItem.getStringValue(); - return ItemFactory.getInstance().createStringItem(input.toUpperCase()); + return ItemFactory.getInstance().createStringItem(input.toLowerCase()); } } - /* - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - - if (stringItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } else { - String input = stringItem.getStringValue(); - return ItemFactory.getInstance().createStringItem(input.toLowerCase()); - } - - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " replace function", - getMetadata() - ); - } - */ } From a17a2072642621dd77f1402bfb940f51084d81cb Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 7 Jun 2021 20:01:40 +0200 Subject: [PATCH 003/142] LowerCase pass spotless test --- .../runtime/functions/strings/LowerCaseFunctionIterator.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java index 260d145123..450afbad4b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/LowerCaseFunctionIterator.java @@ -23,14 +23,12 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import java.util.List; -import java.util.Locale; public class LowerCaseFunctionIterator extends AtMostOneItemLocalRuntimeIterator { From 95e89d32c50af5897fcd15dd37b86ff9e1a7ebec Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 7 Jun 2021 20:09:20 +0200 Subject: [PATCH 004/142] AtMostOneItem UpperCaseFunction --- .../strings/UpperCaseFunctionIterator.java | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/UpperCaseFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/UpperCaseFunctionIterator.java index dabc1da3f3..9c613187b4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/UpperCaseFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/UpperCaseFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class UpperCaseFunctionIterator extends LocalFunctionCallIterator { +public class UpperCaseFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,23 +43,14 @@ public UpperCaseFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - - if (stringItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } else { - String input = stringItem.getStringValue(); - return ItemFactory.getInstance().createStringItem(input.toUpperCase()); - } - - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " replace function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item stringItem = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + + if (stringItem == null) { + return ItemFactory.getInstance().createStringItem(""); + } else { + String input = stringItem.getStringValue(); + return ItemFactory.getInstance().createStringItem(input.toUpperCase()); + } } } From d03b29b59526f4be618d1cf359c33f53d058ea0d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 8 Jun 2021 11:26:54 +0200 Subject: [PATCH 005/142] AtMostOne: Trigo (acos, asin, atan) and sumFunction AtMostOne: Trigo (acos, asin, atan) and sumFunction --- .../trigonometric/ACosFunctionIterator.java | 37 ++++++------------- .../trigonometric/ASinFunctionIterator.java | 35 ++++++------------ .../trigonometric/ATanFunctionIterator.java | 35 ++++++------------ .../aggregate/SumFunctionIterator.java | 23 ++---------- 4 files changed, 37 insertions(+), 93 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java index 841d114efa..925ae189c2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java @@ -23,20 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ACosFunctionIterator extends LocalFunctionCallIterator { +public class ACosFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; - public ACosFunctionIterator( List arguments, ExecutionMode executionMode, @@ -46,28 +43,16 @@ public ACosFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.acos( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " acos function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.acos(dvalue)); } - } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java index 46e38a01d3..1f236216b8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java @@ -23,19 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ASinFunctionIterator extends LocalFunctionCallIterator { +public class ASinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public ASinFunctionIterator( List arguments, @@ -46,27 +44,16 @@ public ASinFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.asin( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " asin function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.asin(dvalue)); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java index caeab58ee4..9596054447 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java @@ -23,19 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ATanFunctionIterator extends LocalFunctionCallIterator { +public class ATanFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public ATanFunctionIterator( List arguments, @@ -46,27 +44,16 @@ public ATanFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.atan( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " atan function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.atan(dvalue)); } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java index 48423d1723..03ca5e3032 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java @@ -26,13 +26,12 @@ import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.arithmetics.AdditiveOperationIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import sparksoniq.spark.SparkSessionManager; @@ -42,7 +41,7 @@ import java.util.Map; import java.util.TreeMap; -public class SumFunctionIterator extends LocalFunctionCallIterator { +public class SumFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -57,28 +56,14 @@ public SumFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); + public Item materializeFirstItemOrNull(DynamicContext context) { this.item = computeSum( zeroElement(), this.children.get(0), this.currentDynamicContextForLocalExecution, getMetadata() ); - this.hasNext = this.item != null; - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return this.item; - } else { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + "SUM function", - getMetadata() - ); - } + return this.item; } private Item zeroElement() { From 3ea5cff0990636c7074f1b68e4bd8a6cd0ac6b24 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 8 Jun 2021 23:00:08 +0200 Subject: [PATCH 006/142] Trigo Arc (cos, sin, tan) Trigo Arc (cos, sin, tan) --- .../trigonometric/ACosFunctionIterator.java | 37 ++++++------------- .../trigonometric/ASinFunctionIterator.java | 35 ++++++------------ .../trigonometric/ATanFunctionIterator.java | 35 ++++++------------ 3 files changed, 33 insertions(+), 74 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java index 841d114efa..925ae189c2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ACosFunctionIterator.java @@ -23,20 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ACosFunctionIterator extends LocalFunctionCallIterator { +public class ACosFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; - public ACosFunctionIterator( List arguments, ExecutionMode executionMode, @@ -46,28 +43,16 @@ public ACosFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.acos( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " acos function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.acos(dvalue)); } - } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java index 46e38a01d3..1f236216b8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ASinFunctionIterator.java @@ -23,19 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ASinFunctionIterator extends LocalFunctionCallIterator { +public class ASinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public ASinFunctionIterator( List arguments, @@ -46,27 +44,16 @@ public ASinFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.asin( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " asin function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.asin(dvalue)); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java index caeab58ee4..9596054447 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/ATanFunctionIterator.java @@ -23,19 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ATanFunctionIterator extends LocalFunctionCallIterator { +public class ATanFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public ATanFunctionIterator( List arguments, @@ -46,27 +44,16 @@ public ATanFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.atan( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " atan function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.atan(dvalue)); } From 7b8f54e57668ca3752080e8764c1b90e838cf202 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 11:06:00 +0200 Subject: [PATCH 007/142] back to localCall SumFunction --- .../aggregate/SumFunctionIterator.java | 77 +++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java index 03ca5e3032..82aa256479 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java @@ -26,12 +26,13 @@ import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; +import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; -import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.arithmetics.AdditiveOperationIterator; +import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import sparksoniq.spark.SparkSessionManager; @@ -41,7 +42,7 @@ import java.util.Map; import java.util.TreeMap; -public class SumFunctionIterator extends AtMostOneItemLocalRuntimeIterator { +public class SumFunctionIterator extends LocalFunctionCallIterator { private static final long serialVersionUID = 1L; @@ -56,14 +57,28 @@ public SumFunctionIterator( } @Override - public Item materializeFirstItemOrNull(DynamicContext context) { + public void open(DynamicContext context) { + super.open(context); this.item = computeSum( - zeroElement(), - this.children.get(0), - this.currentDynamicContextForLocalExecution, - getMetadata() + zeroElement(), + this.children.get(0), + this.currentDynamicContextForLocalExecution, + getMetadata() ); - return this.item; + this.hasNext = this.item != null; + } + + @Override + public Item next() { + if (this.hasNext) { + this.hasNext = false; + return this.item; + } else { + throw new IteratorFlowException( + FLOW_EXCEPTION_MESSAGE + "SUM function", + getMetadata() + ); + } } private Item zeroElement() { @@ -82,24 +97,24 @@ public static Item computeSum( ) { if (iterator.isDataFrame()) { return computeDataFrame( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } else if (iterator.isRDDOrDataFrame()) { return computeRDD( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } else { return computeLocally( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } } @@ -121,10 +136,10 @@ private static Item computeLocally( if (sum == null) { throw new InvalidArgumentTypeException( " \"+\": operation not possible with parameters of type \"" - + result.getDynamicType().toString() - + "\" and \"" - + results.get(i).getDynamicType().toString() - + "\"", + + result.getDynamicType().toString() + + "\" and \"" + + results.get(i).getDynamicType().toString() + + "\"", metadata ); } @@ -156,12 +171,12 @@ private static Item computeDataFrame( } df.createOrReplaceTempView("input"); JSoundDataFrame summedDF = df.evaluateSQL( - String.format( - "SELECT SUM(`%s`) as `%s` FROM input", - SparkSessionManager.atomicJSONiqItemColumnName, - SparkSessionManager.atomicJSONiqItemColumnName - ), - df.getItemType() + String.format( + "SELECT SUM(`%s`) as `%s` FROM input", + SparkSessionManager.atomicJSONiqItemColumnName, + SparkSessionManager.atomicJSONiqItemColumnName + ), + df.getItemType() ); return summedDF.getExactlyOneItem(); } @@ -170,7 +185,7 @@ public Map getVariableDependencies() { if (this.children.get(0) instanceof VariableReferenceIterator) { VariableReferenceIterator expr = (VariableReferenceIterator) this.children.get(0); Map result = - new TreeMap(); + new TreeMap(); result.put(expr.getVariableName(), DynamicContext.VariableDependency.SUM); return result; } else { From 2764b693c7570b37d28a108b39519c4bd65518c7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 11:18:28 +0200 Subject: [PATCH 008/142] spotless --- .../aggregate/SumFunctionIterator.java | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java index 82aa256479..48423d1723 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java @@ -60,10 +60,10 @@ public SumFunctionIterator( public void open(DynamicContext context) { super.open(context); this.item = computeSum( - zeroElement(), - this.children.get(0), - this.currentDynamicContextForLocalExecution, - getMetadata() + zeroElement(), + this.children.get(0), + this.currentDynamicContextForLocalExecution, + getMetadata() ); this.hasNext = this.item != null; } @@ -97,24 +97,24 @@ public static Item computeSum( ) { if (iterator.isDataFrame()) { return computeDataFrame( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } else if (iterator.isRDDOrDataFrame()) { return computeRDD( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } else { return computeLocally( - zeroElement, - iterator, - context, - metadata + zeroElement, + iterator, + context, + metadata ); } } @@ -136,10 +136,10 @@ private static Item computeLocally( if (sum == null) { throw new InvalidArgumentTypeException( " \"+\": operation not possible with parameters of type \"" - + result.getDynamicType().toString() - + "\" and \"" - + results.get(i).getDynamicType().toString() - + "\"", + + result.getDynamicType().toString() + + "\" and \"" + + results.get(i).getDynamicType().toString() + + "\"", metadata ); } @@ -171,12 +171,12 @@ private static Item computeDataFrame( } df.createOrReplaceTempView("input"); JSoundDataFrame summedDF = df.evaluateSQL( - String.format( - "SELECT SUM(`%s`) as `%s` FROM input", - SparkSessionManager.atomicJSONiqItemColumnName, - SparkSessionManager.atomicJSONiqItemColumnName - ), - df.getItemType() + String.format( + "SELECT SUM(`%s`) as `%s` FROM input", + SparkSessionManager.atomicJSONiqItemColumnName, + SparkSessionManager.atomicJSONiqItemColumnName + ), + df.getItemType() ); return summedDF.getExactlyOneItem(); } @@ -185,7 +185,7 @@ public Map getVariableDependencies() { if (this.children.get(0) instanceof VariableReferenceIterator) { VariableReferenceIterator expr = (VariableReferenceIterator) this.children.get(0); Map result = - new TreeMap(); + new TreeMap(); result.put(expr.getVariableName(), DynamicContext.VariableDependency.SUM); return result; } else { From 1cd496e9713908318c3e0afd9dd09c20c7d03908 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 13:21:21 +0200 Subject: [PATCH 009/142] AtMost MinFunction --- .../aggregate/MinFunctionIterator.java | 74 ++++++++----------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 884f805506..9607f158b3 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -26,12 +26,11 @@ import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import java.util.Collections; @@ -39,7 +38,7 @@ import java.util.Map; import java.util.TreeMap; -public class MinFunctionIterator extends LocalFunctionCallIterator { +public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -56,58 +55,43 @@ public MinFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - if (!this.iterator.isRDDOrDataFrame()) { - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - return; - } - JavaRDD rdd = this.iterator.getRDD(this.currentDynamicContextForLocalExecution); - if (rdd.isEmpty()) { - this.hasNext = false; - return; - } + public Item materializeFirstItemOrNull(DynamicContext context) { ItemComparator comparator = new ItemComparator( new InvalidArgumentTypeException( "Min expression input error. Input has to be non-null atomics of matching types", getMetadata() ) ); - this.result = rdd.min(comparator); - } - @Override - public Item next() { - if (!this.hasNext) { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + "Min function", - getMetadata() - ); - } - this.hasNext = false; - ItemComparator comparator = new ItemComparator( - new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types", + if (!this.iterator.isRDDOrDataFrame()) { + + List results = this.iterator.materialize(context); + if (results.size() == 0) { + return null; + } + + try { + return Collections.min(results, comparator); + } catch (RumbleException e) { + RumbleException ex = new InvalidArgumentTypeException( + "Max expression input error. Input has to be non-null atomics of matching types.", getMetadata() - ) - ); - if (this.iterator.isRDDOrDataFrame()) { - return this.result; + ); + ex.initCause(e); + throw ex; + } } - List results = this.iterator.materialize(this.currentDynamicContextForLocalExecution); - - try { - return Collections.min(results, comparator); - } catch (RumbleException e) { - RumbleException ex = new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types.", - getMetadata() - ); - ex.initCause(e); - throw ex; + + JavaRDD rdd = this.iterator.getRDD(context); + this.iterator.close(); + if (rdd.isEmpty()) { + return null; } + + this.result = rdd.min(comparator); + return this.result; + + } public Map getVariableDependencies() { From e3df9038f1d5566dcba34ccdb37d41aa84aa02e3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 14:27:51 +0200 Subject: [PATCH 010/142] AtMostOne FloorFunction --- .../numerics/FloorFunctionIterator.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index c616d4d3ac..5a30edea65 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -23,21 +23,19 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; -public class FloorFunctionIterator extends LocalFunctionCallIterator { +public class FloorFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public FloorFunctionIterator( List arguments, @@ -48,27 +46,19 @@ public FloorFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.floor( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item value = this.children.get(0).materializeFirstItemOrNull(context); + if (value == null) { + return null; } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " floor function", getMetadata()); + return ItemFactory.getInstance() + .createDoubleItem( + Math.floor( + this.children.get(0) + .materializeFirstItemOrNull(context) + .castToDoubleValue() + ) + ); } @Override From 36f6fe1d938b6a7681fef9aa9037b477cebfe38b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 14:32:26 +0200 Subject: [PATCH 011/142] AtMostOne Ceiling Correct Floor to re-use value --- .../numerics/CeilingFunctionIterator.java | 34 +++++++------------ .../numerics/FloorFunctionIterator.java | 4 +-- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java index fb5ace24b2..c9566a0fe4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java @@ -26,12 +26,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CeilingFunctionIterator extends LocalFunctionCallIterator { +public class CeilingFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -46,27 +47,18 @@ public CeilingFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.ceil( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item value = this.children.get(0).materializeFirstItemOrNull(context); + if (value == null) { + return null; } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " ceiling function", getMetadata()); + return ItemFactory.getInstance() + .createDoubleItem( + Math.ceil( + value.castToDoubleValue() + ) + ); + } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index 5a30edea65..b5a6351847 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -54,9 +54,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance() .createDoubleItem( Math.floor( - this.children.get(0) - .materializeFirstItemOrNull(context) - .castToDoubleValue() + value.castToDoubleValue() ) ); } From 5beb18d541a3a9259c3638a5e468b21183fd472e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 16:21:24 +0200 Subject: [PATCH 012/142] Ceiling, Floor, Pow, Number, RoundHalf, Max, fix Min --- .../numerics/CeilingFunctionIterator.java | 2 - .../numerics/FloorFunctionIterator.java | 2 +- .../numerics/NumberFunctionIterator.java | 33 ++++----- .../RoundHalfToEvenFunctionIterator.java | 58 +++++++-------- .../exponential/PowFunctionIterator.java | 36 ++++------ .../aggregate/MaxFunctionIterator.java | 70 +++++++------------ .../aggregate/MinFunctionIterator.java | 3 +- 7 files changed, 78 insertions(+), 126 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java index c9566a0fe4..7811c5ea12 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index b5a6351847..4ea1f013ab 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -54,7 +54,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance() .createDoubleItem( Math.floor( - value.castToDoubleValue() + value.castToDoubleValue() ) ); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java index b3e64d2550..d51b0637ec 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java @@ -21,17 +21,17 @@ package org.rumbledb.runtime.functions.numerics; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.typing.CastIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; -public class NumberFunctionIterator extends LocalFunctionCallIterator { +public class NumberFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -44,23 +44,18 @@ public NumberFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item anyItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (anyItem == null) { - return ItemFactory.getInstance().createDoubleItem(Double.NaN); - } + public Item materializeFirstItemOrNull(DynamicContext context) { - Item result = CastIterator.castItemToType(anyItem, BuiltinTypesCatalogue.doubleItem, getMetadata()); - if (result != null) { - return result; - } + Item anyItem = this.children.get(0).materializeFirstItemOrNull(context); + if (anyItem == null) { return ItemFactory.getInstance().createDoubleItem(Double.NaN); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " number function", - getMetadata() - ); + } + + Item result = CastIterator.castItemToType(anyItem, BuiltinTypesCatalogue.doubleItem, getMetadata()); + if (result != null) { + return result; + } + return ItemFactory.getInstance().createDoubleItem(Double.NaN); + } } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 0082820e9b..3d6bd94dbe 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -26,14 +26,14 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; -public class RoundHalfToEvenFunctionIterator extends LocalFunctionCallIterator { +public class RoundHalfToEvenFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -48,41 +48,31 @@ public RoundHalfToEvenFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + Item value = this.children.get(0).materializeFirstItemOrNull(context); + if (value == null) { + return null; + } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item value = this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item precision; - if (this.children.size() > 1) { - precision = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - } - // if second param is not given precision is set as 0 (rounds to a whole number) - else { - precision = ItemFactory.getInstance().createIntItem(0); - } - try { - BigDecimal bd = new BigDecimal(value.castToDoubleValue()); - bd = bd.setScale(precision.getIntValue(), RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + int precision; + if (this.children.size() > 1) { + precision = this.children.get(1) + .materializeFirstItemOrNull(context) + .getIntValue(); + } + // if second param is not given precision is set as 0 (rounds to a whole number) + else { + precision = 0; + } + try { + BigDecimal bd = new BigDecimal(value.castToDoubleValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); - } catch (IteratorFlowException e) { - throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); - } + } catch (IteratorFlowException e) { + throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " round-half-to-even function", - getMetadata() - ); + } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java index 71b63325f7..950f777cf0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java @@ -26,12 +26,12 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class PowFunctionIterator extends LocalFunctionCallIterator { +public class PowFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -46,29 +46,17 @@ public PowFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - Item base = this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item exponent = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - try { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem(Math.pow(base.castToDoubleValue(), exponent.castToDoubleValue())); - } catch (IteratorFlowException e) { - throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + Item base = this.children.get(0).materializeFirstItemOrNull(context); + Item exponent = this.children.get(1) + .materializeFirstItemOrNull(context); + try { + return ItemFactory.getInstance() + .createDoubleItem(Math.pow(base.castToDoubleValue(), exponent.castToDoubleValue())); + } catch (IteratorFlowException e) { + throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " pow function", getMetadata()); + } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index 23e1e383f0..aab3046b02 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -26,12 +26,11 @@ import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import java.util.Collections; @@ -39,7 +38,7 @@ import java.util.Map; import java.util.TreeMap; -public class MaxFunctionIterator extends LocalFunctionCallIterator { +public class MaxFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -56,58 +55,41 @@ public MaxFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - if (!this.iterator.isRDDOrDataFrame()) { - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - return; - } - JavaRDD rdd = this.iterator.getRDD(this.currentDynamicContextForLocalExecution); - if (rdd.isEmpty()) { - this.hasNext = false; - return; - } + public Item materializeFirstItemOrNull(DynamicContext context) { ItemComparator comparator = new ItemComparator( new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types", getMetadata() ) ); - this.result = rdd.max(comparator); - } - @Override - public Item next() { - if (!this.hasNext) { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + "MAX function", - getMetadata() - ); - } - this.hasNext = false; - ItemComparator comparator = new ItemComparator( - new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types", + if (!this.iterator.isRDDOrDataFrame()) { + + List results = this.iterator.materialize(context); + if (results.size() == 0) { + return null; + } + + try { + return Collections.max(results, comparator); + } catch (RumbleException e) { + RumbleException ex = new InvalidArgumentTypeException( + "Max expression input error. Input has to be non-null atomics of matching types.", getMetadata() - ) - ); - if (this.iterator.isRDDOrDataFrame()) { - return this.result; + ); + ex.initCause(e); + throw ex; + } } - List results = this.iterator.materialize(this.currentDynamicContextForLocalExecution); - try { - return Collections.max(results, comparator); - } catch (RumbleException e) { - RumbleException ex = new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types.", - getMetadata() - ); - ex.initCause(e); - throw ex; + JavaRDD rdd = this.iterator.getRDD(context); + if (rdd.isEmpty()) { + return null; } + + this.result = rdd.max(comparator); + return this.result; + } public Map getVariableDependencies() { diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 9607f158b3..ea637426df 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -74,7 +74,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return Collections.min(results, comparator); } catch (RumbleException e) { RumbleException ex = new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types.", + "Min expression input error. Input has to be non-null atomics of matching types.", getMetadata() ); ex.initCause(e); @@ -83,7 +83,6 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } JavaRDD rdd = this.iterator.getRDD(context); - this.iterator.close(); if (rdd.isEmpty()) { return null; } From 0b4f4fa7f06bd3ceeb4a0790796b445da635f86e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 20:08:36 +0200 Subject: [PATCH 013/142] fix Pow nullException --- .../functions/numerics/exponential/PowFunctionIterator.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java index 950f777cf0..6ffcc590a6 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/PowFunctionIterator.java @@ -48,8 +48,14 @@ public PowFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { Item base = this.children.get(0).materializeFirstItemOrNull(context); + if (base == null) { + return null; + } Item exponent = this.children.get(1) .materializeFirstItemOrNull(context); + if (exponent == null) { + return null; + } try { return ItemFactory.getInstance() .createDoubleItem(Math.pow(base.castToDoubleValue(), exponent.castToDoubleValue())); From c1dbace330758b22d8bf765879c08066894a3440 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 23:04:43 +0200 Subject: [PATCH 014/142] Exp10, Log10, Pi, Tan, YFromDateTime --- .../YearFromDateTimeFunctionIterator.java | 25 +++++--------- .../numerics/PiFunctionIterator.java | 14 +++----- .../exponential/Exp10FunctionIterator.java | 34 ++++++------------- .../exponential/Log10FunctionIterator.java | 33 +++++++----------- .../trigonometric/TanFunctionIterator.java | 34 +++++++------------ 5 files changed, 49 insertions(+), 91 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java index ad0b3c33e7..3a34a7ddc6 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java @@ -6,12 +6,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class YearFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class YearFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +26,13 @@ public YearFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getYear()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " year-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getYear()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java index b059cd564a..331f7c3dcf 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java @@ -21,16 +21,18 @@ package org.rumbledb.runtime.functions.numerics; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class PiFunctionIterator extends LocalFunctionCallIterator { +public class PiFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,14 +45,8 @@ public PiFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createDoubleItem(Math.PI); - } else { - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " pi function", getMetadata()); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createDoubleItem(Math.PI); } - } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java index 983c9a9fc3..bebec8164b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java @@ -23,15 +23,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class Exp10FunctionIterator extends LocalFunctionCallIterator { +public class Exp10FunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -46,27 +45,16 @@ public Exp10FunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item exponent = this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - try { - return ItemFactory.getInstance().createDoubleItem(Math.pow(10.0, exponent.castToDoubleValue())); - } catch (IteratorFlowException e) { - throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + Item exponent = this.iterator.materializeFirstItemOrNull(context); + if (exponent == null) { + return null; } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " exp10 function", getMetadata()); + double dexponent = exponent.getDoubleValue(); + if (Double.isNaN(dexponent) || Double.isInfinite(dexponent)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); + } + return ItemFactory.getInstance().createDoubleItem(Math.pow(10.0, dexponent)); } - } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java index 1e7198ed42..72b265d90a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java @@ -26,12 +26,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class Log10FunctionIterator extends LocalFunctionCallIterator { +public class Log10FunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -46,26 +47,16 @@ public Log10FunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item value = this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - try { - return ItemFactory.getInstance().createDoubleItem(Math.log10(value.castToDoubleValue())); - - } catch (IteratorFlowException e) { - throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + Item value = this.iterator.materializeFirstItemOrNull(context); + if (value == null) { + return null; + } + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " log10 function", getMetadata()); + return ItemFactory.getInstance().createDoubleItem(Math.log10(dvalue)); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java index 5d88473c2b..e03124905e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java @@ -26,12 +26,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class TanFunctionIterator extends LocalFunctionCallIterator { +public class TanFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -46,26 +47,17 @@ public TanFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); - this.iterator.open(this.currentDynamicContextForLocalExecution); - this.hasNext = this.iterator.hasNext(); - this.iterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDoubleItem( - Math.tan( - this.iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) - .castToDoubleValue() - ) - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item value = this.children.get(0).materializeFirstItemOrNull(context); + if (value == null) { + return null; } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " tan function", getMetadata()); + double dvalue = value.getDoubleValue(); + if (Double.isNaN(dvalue) || Double.isInfinite(dvalue)) { + return ItemFactory.getInstance().createDoubleItem(Double.NaN); + } + return ItemFactory.getInstance().createDoubleItem(Math.tan(dvalue)); + } + } From 7b53eb69a01c6ebd5a2934c22dfe10aeccfffb14 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 23:07:01 +0200 Subject: [PATCH 015/142] Spotless --- .../datetime/components/YearFromDateTimeFunctionIterator.java | 4 +--- .../runtime/functions/numerics/PiFunctionIterator.java | 2 -- .../functions/numerics/exponential/Log10FunctionIterator.java | 2 -- .../functions/numerics/trigonometric/TanFunctionIterator.java | 2 -- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java index 3a34a7ddc6..67415c9690 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java @@ -3,12 +3,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -28,7 +26,7 @@ public YearFromDateTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.dateTimeItem == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java index 331f7c3dcf..a7faf61a51 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java index 72b265d90a..3a64da2907 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java index e03124905e..52a61824e9 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; From 8ccfc95b31293f894a665c866131ebdacc72341b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 9 Jun 2021 23:07:01 +0200 Subject: [PATCH 016/142] Spotless --- .../components/YearFromDateTimeFunctionIterator.java | 4 +--- .../runtime/functions/numerics/PiFunctionIterator.java | 2 -- .../numerics/exponential/Exp10FunctionIterator.java | 3 +-- .../numerics/exponential/Log10FunctionIterator.java | 5 +---- .../numerics/trigonometric/TanFunctionIterator.java | 2 -- 5 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java index 3a34a7ddc6..67415c9690 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateTimeFunctionIterator.java @@ -3,12 +3,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -28,7 +26,7 @@ public YearFromDateTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.dateTimeItem == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java index 331f7c3dcf..a7faf61a51 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/PiFunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java index bebec8164b..1a8c78cd3c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Exp10FunctionIterator.java @@ -34,7 +34,6 @@ public class Exp10FunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public Exp10FunctionIterator( List arguments, @@ -46,7 +45,7 @@ public Exp10FunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { - Item exponent = this.iterator.materializeFirstItemOrNull(context); + Item exponent = this.children.get(0).materializeFirstItemOrNull(context); if (exponent == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java index 72b265d90a..3591e711bd 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/exponential/Log10FunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -36,7 +34,6 @@ public class Log10FunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public Log10FunctionIterator( List arguments, @@ -48,7 +45,7 @@ public Log10FunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { - Item value = this.iterator.materializeFirstItemOrNull(context); + Item value = this.children.get(0).materializeFirstItemOrNull(context); if (value == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java index e03124905e..52a61824e9 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/trigonometric/TanFunctionIterator.java @@ -23,12 +23,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; From fc5665e2a2d7a4ee7100bf650ce6f70ff19697fa Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 11 Jun 2021 11:45:34 +0200 Subject: [PATCH 017/142] AtMostOne - Avg, Count, Sum --- .../aggregate/AvgFunctionIterator.java | 33 ++++---------- .../aggregate/CountFunctionIterator.java | 45 ++++++++----------- .../aggregate/SumFunctionIterator.java | 32 +++++-------- 3 files changed, 37 insertions(+), 73 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/AvgFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/AvgFunctionIterator.java index 71c664a316..08885034f2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/AvgFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/AvgFunctionIterator.java @@ -24,13 +24,12 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.arithmetic.MultiplicativeExpression; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.arithmetics.MultiplicativeOperationIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import java.math.BigInteger; @@ -38,7 +37,7 @@ import java.util.Map; import java.util.TreeMap; -public class AvgFunctionIterator extends LocalFunctionCallIterator { +public class AvgFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -53,25 +52,22 @@ public AvgFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); + public Item materializeFirstItemOrNull(DynamicContext context) { Item count = CountFunctionIterator.computeCount( this.children.get(0), - this.currentDynamicContextForLocalExecution, + context, getMetadata() ); if (count.isInt() && count.getIntValue() == 0) { - this.hasNext = false; - return; + return null; } if (count.isInteger() && count.getIntegerValue().equals(BigInteger.ZERO)) { - this.hasNext = false; - return; + return null; } Item sum = SumFunctionIterator.computeSum( ItemFactory.getInstance().createIntegerItem(BigInteger.ZERO), this.children.get(0), - this.currentDynamicContextForLocalExecution, + context, getMetadata() ); this.item = MultiplicativeOperationIterator.processItem( @@ -80,20 +76,7 @@ public void open(DynamicContext context) { MultiplicativeExpression.MultiplicativeOperator.DIV, getMetadata() ); - this.hasNext = true; - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return this.item; - } else { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + "SUM function", - getMetadata() - ); - } + return this.item; } public Map getVariableDependencies() { diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/CountFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/CountFunctionIterator.java index 66bf52522c..c4a7b79764 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/CountFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/CountFunctionIterator.java @@ -24,19 +24,18 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import java.util.List; import java.util.Map; import java.util.TreeMap; -public class CountFunctionIterator extends LocalFunctionCallIterator { +public class CountFunctionIterator extends AtMostOneItemLocalRuntimeIterator { /** * */ @@ -50,32 +49,26 @@ public CountFunctionIterator( super(arguments, executionMode, iteratorMetadata); } + @Override - public Item next() { - if (this.hasNext) { - RuntimeIterator iterator = this.children.get(0); + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator iterator = this.children.get(0); - // the count($x) case is treated separately because we can short-circuit the - // count, e.g., if it comes from the group-by aggregation of a non-grouping - // key. - if (iterator instanceof VariableReferenceIterator) { - VariableReferenceIterator expr = (VariableReferenceIterator) iterator; - this.hasNext = false; - return this.currentDynamicContextForLocalExecution.getVariableValues() - .getVariableCount(expr.getVariableName()); - } - this.hasNext = false; - return computeCount( - this.children.get(0), - this.currentDynamicContextForLocalExecution, - getMetadata() - ); - } else { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + " count function", - getMetadata() - ); + // the count($x) case is treated separately because we can short-circuit the + // count, e.g., if it comes from the group-by aggregation of a non-grouping + // key. + if (iterator instanceof VariableReferenceIterator) { + VariableReferenceIterator expr = (VariableReferenceIterator) iterator; + // this.hasNext = false; + return context.getVariableValues() + .getVariableCount(expr.getVariableName()); } + return computeCount( + iterator, + context, + getMetadata() + ); + } public static Item computeCount( diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java index 48423d1723..5ed560f999 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/SumFunctionIterator.java @@ -26,13 +26,12 @@ import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.arithmetics.AdditiveOperationIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import sparksoniq.spark.SparkSessionManager; @@ -42,7 +41,7 @@ import java.util.Map; import java.util.TreeMap; -public class SumFunctionIterator extends LocalFunctionCallIterator { +public class SumFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -57,33 +56,22 @@ public SumFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); + public Item materializeFirstItemOrNull(DynamicContext context) { this.item = computeSum( - zeroElement(), + zeroElement(context), this.children.get(0), - this.currentDynamicContextForLocalExecution, + context, getMetadata() ); - this.hasNext = this.item != null; - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return this.item; - } else { - throw new IteratorFlowException( - FLOW_EXCEPTION_MESSAGE + "SUM function", - getMetadata() - ); + if (this.item == null) { + return null; } + return this.item; } - private Item zeroElement() { + private Item zeroElement(DynamicContext context) { if (this.children.size() > 1) { - return this.children.get(1).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + return this.children.get(1).materializeFirstItemOrNull(context); } else { return ItemFactory.getInstance().createIntegerItem(BigInteger.ZERO); } From 7b9ff713a4303a0b524bd92c14d7956fbf9b0a81 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 11 Jun 2021 16:17:19 +0200 Subject: [PATCH 018/142] AtMostOne: ZeroOrOne (Cardinality) and Replace --- .../CardinalityFunctionIterator.java | 4 +- .../cardinality/ZeroOrOneIterator.java | 49 +++------- .../strings/ReplaceFunctionIterator.java | 93 +++++++++---------- 3 files changed, 62 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/CardinalityFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/CardinalityFunctionIterator.java index 0c7f8f0835..e775cbb6f5 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/CardinalityFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/CardinalityFunctionIterator.java @@ -22,12 +22,12 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public abstract class CardinalityFunctionIterator extends LocalFunctionCallIterator { +public abstract class CardinalityFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java index d9461867d5..2a9012932e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java @@ -24,7 +24,6 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.SequenceExceptionZeroOrOne; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.RuntimeIterator; @@ -46,47 +45,27 @@ public ZeroOrOneIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return this.nextResult; - } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " ZERO-OR-ONE function", - getMetadata() - ); - } - - @Override - public void open(DynamicContext context) { - super.open(context); - + public Item materializeFirstItemOrNull(DynamicContext context) { RuntimeIterator sequenceIterator = this.children.get(0); - if (!sequenceIterator.isRDDOrDataFrame()) { - sequenceIterator.open(context); - if (!sequenceIterator.hasNext()) { - this.hasNext = false; + List results = sequenceIterator.materialize(context); + if (results.size() == 0) { + return null; + } else if (results.size() == 1) { + return results.get(0); } else { - this.nextResult = sequenceIterator.next(); - if (sequenceIterator.hasNext()) { - throw new SequenceExceptionZeroOrOne( - "fn:zero-or-one() called with a sequence containing more than one item", - getMetadata() - ); - } else { - this.hasNext = true; - } + throw new SequenceExceptionZeroOrOne( + "fn:zero-or-one() called with a sequence containing more than one item", + getMetadata() + ); } - sequenceIterator.close(); } else { - JavaRDD rdd = sequenceIterator.getRDD(this.currentDynamicContextForLocalExecution); + JavaRDD rdd = sequenceIterator.getRDD(context); List results = rdd.take(2); if (results.size() == 0) { - this.hasNext = false; + return null; } else if (results.size() == 1) { - this.hasNext = true; - this.nextResult = results.get(0); + return results.get(0); } else if (results.size() > 1) { throw new SequenceExceptionZeroOrOne( "fn:zero-or-one() called with a sequence containing more than one item", @@ -94,5 +73,7 @@ public void open(DynamicContext context) { ); } } + return null; } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ReplaceFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ReplaceFunctionIterator.java index 7c5cd988e8..4e1b23afd8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/ReplaceFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ReplaceFunctionIterator.java @@ -21,22 +21,22 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidRegexPatternException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.MatchesEmptyStringException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.exceptions.InvalidReplacementStringException; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.regex.PatternSyntaxException; -public class ReplaceFunctionIterator extends LocalFunctionCallIterator { +public class ReplaceFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -49,56 +49,53 @@ public ReplaceFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + Item patternStringItem = this.children.get(1) + .materializeFirstItemOrNull(context); - Item patternStringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - String pattern = patternStringItem.getStringValue(); - - Pattern p; - try { - p = Pattern.compile(pattern); - } catch (PatternSyntaxException e) { - throw new InvalidRegexPatternException( - e.getDescription(), - getMetadata() - ); - } - if ("".matches(pattern)) { - throw new MatchesEmptyStringException( - "'" + pattern + "' matches empty string", - getMetadata() - ); - } - - Item replacementStringItem = this.children.get(2) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - String replacement = replacementStringItem.getStringValue(); - if (!(checkReplacementStringForValidity(replacement))) { - throw new InvalidReplacementStringException( - "'" + replacement + "' contains a disallowed sequence of characters", - getMetadata() - ); - } + if (patternStringItem == null) { + return null; + } + String pattern = patternStringItem.getStringValue(); + Pattern p; - String input; - if (stringItem == null) { - input = ""; - } else { - input = stringItem.getStringValue(); - } + try { + p = Pattern.compile(pattern); + } catch (PatternSyntaxException e) { + throw new InvalidRegexPatternException( + e.getDescription(), + getMetadata() + ); + } + if ("".matches(pattern)) { + throw new MatchesEmptyStringException( + "'" + pattern + "' matches empty string", + getMetadata() + ); + } - Matcher m = p.matcher(input); - return ItemFactory.getInstance().createStringItem(m.replaceAll(replacement)); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " replace function", + Item replacementStringItem = this.children.get(2) + .materializeFirstItemOrNull(context); + String replacement = replacementStringItem.getStringValue(); + if (!(checkReplacementStringForValidity(replacement))) { + throw new InvalidReplacementStringException( + "'" + replacement + "' contains a disallowed sequence of characters", getMetadata() ); + } + + String input; + if (stringItem == null) { + input = ""; + } else { + input = stringItem.getStringValue(); + } + + Matcher m = p.matcher(input); + return ItemFactory.getInstance().createStringItem(m.replaceAll(replacement)); + } private static boolean checkReplacementStringForValidity(String repl) { From 7614f864ff8a2640671c27415c70f5ea70fdc8c2 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 11 Jun 2021 16:54:09 +0200 Subject: [PATCH 019/142] AtMostOne String functions Contains, Matches, Substring, Substring After/Before, Translate --- .../strings/ContainsFunctionIterator.java | 45 +++++------ .../strings/MatchesFunctionIterator.java | 36 ++++----- .../SubstringAfterFunctionIterator.java | 58 ++++++-------- .../SubstringBeforeFunctionIterator.java | 64 +++++++-------- .../strings/SubstringFunctionIterator.java | 74 ++++++++--------- .../strings/TranslateFunctionIterator.java | 79 +++++++++---------- 6 files changed, 155 insertions(+), 201 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java index 96ae94b26b..2c46ee4802 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ContainsFunctionIterator extends LocalFunctionCallIterator { +public class ContainsFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,29 +43,22 @@ public ContainsFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item substringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (substringItem == null || substringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(true); - } - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (stringItem == null || stringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(false); - } - boolean result = stringItem.getStringValue() - .contains( - substringItem.getStringValue() - ); - return ItemFactory.getInstance().createBooleanItem(result); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " contains function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item substringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (substringItem == null || substringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(true); + } + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (stringItem == null || stringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(false); } + boolean result = stringItem.getStringValue() + .contains( + substringItem.getStringValue() + ); + return ItemFactory.getInstance().createBooleanItem(result); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/MatchesFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/MatchesFunctionIterator.java index 1938269fd7..a616a4ba68 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/MatchesFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/MatchesFunctionIterator.java @@ -21,18 +21,18 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class MatchesFunctionIterator extends LocalFunctionCallIterator { +public class MatchesFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -45,26 +45,18 @@ public MatchesFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; + public Item materializeFirstItemOrNull(DynamicContext context) { + Item regexpItem = this.children.get(1) + .materializeFirstItemOrNull(context); + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (stringItem == null) { + stringItem = ItemFactory.getInstance().createStringItem(""); + } - Item regexpItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (stringItem == null) { - stringItem = ItemFactory.getInstance().createStringItem(""); - } + Matcher matcher = Pattern.compile(regexpItem.getStringValue()).matcher(stringItem.getStringValue()); + boolean result = matcher.find(); + return ItemFactory.getInstance().createBooleanItem(result); - Matcher matcher = Pattern.compile(regexpItem.getStringValue()).matcher(stringItem.getStringValue()); - boolean result = matcher.find(); - return ItemFactory.getInstance().createBooleanItem(result); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " matches function", - getMetadata() - ); - } } } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java index 25902f4beb..bbc91f2275 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java @@ -1,16 +1,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class SubstringAfterFunctionIterator extends LocalFunctionCallIterator { +public class SubstringAfterFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -23,37 +23,29 @@ public SubstringAfterFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item substringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - - if (stringItem == null || stringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createStringItem(""); - } - if (substringItem == null || substringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createStringItem(stringItem.getStringValue()); - } - - int indexOfOccurrence = stringItem.getStringValue().indexOf(substringItem.getStringValue()); - return indexOfOccurrence == -1 - ? ItemFactory.getInstance().createStringItem("") - : ItemFactory.getInstance() - .createStringItem( - stringItem.getStringValue() - .substring( - indexOfOccurrence + substringItem.getStringValue().length() - ) - ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " substring-after function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + Item substringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + + if (stringItem == null || stringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createStringItem(""); + } + if (substringItem == null || substringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createStringItem(stringItem.getStringValue()); } + int indexOfOccurrence = stringItem.getStringValue().indexOf(substringItem.getStringValue()); + return indexOfOccurrence == -1 + ? ItemFactory.getInstance().createStringItem("") + : ItemFactory.getInstance() + .createStringItem( + stringItem.getStringValue() + .substring( + indexOfOccurrence + substringItem.getStringValue().length() + ) + ); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java index f389b42f69..eafc21e68b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java @@ -1,16 +1,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class SubstringBeforeFunctionIterator extends LocalFunctionCallIterator { +public class SubstringBeforeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -23,39 +23,31 @@ public SubstringBeforeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item substringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if ( - substringItem == null - || substringItem.getStringValue().isEmpty() - || - stringItem == null - || stringItem.getStringValue().isEmpty() - ) { - return ItemFactory.getInstance().createStringItem(""); - } - int indexOfOccurrence = stringItem.getStringValue().indexOf(substringItem.getStringValue()); - return indexOfOccurrence == -1 - ? ItemFactory.getInstance().createStringItem("") - : ItemFactory.getInstance() - .createStringItem( - stringItem.getStringValue() - .substring( - 0, - indexOfOccurrence - ) - ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " substring-before function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + Item substringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if ( + substringItem == null + || substringItem.getStringValue().isEmpty() + || + stringItem == null + || stringItem.getStringValue().isEmpty() + ) { + return ItemFactory.getInstance().createStringItem(""); } - + int indexOfOccurrence = stringItem.getStringValue().indexOf(substringItem.getStringValue()); + return indexOfOccurrence == -1 + ? ItemFactory.getInstance().createStringItem("") + : ItemFactory.getInstance() + .createStringItem( + stringItem.getStringValue() + .substring( + 0, + indexOfOccurrence + ) + ); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringFunctionIterator.java index 0621871418..19da188cef 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringFunctionIterator.java @@ -21,17 +21,17 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class SubstringFunctionIterator extends LocalFunctionCallIterator { +public class SubstringFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -44,52 +44,44 @@ public SubstringFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - String result; - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (stringItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } - Item indexItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (indexItem == null) { + public Item materializeFirstItemOrNull(DynamicContext context) { + String result; + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (stringItem == null) { + return ItemFactory.getInstance().createStringItem(""); + } + Item indexItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (indexItem == null) { + throw new UnexpectedTypeException( + "Type error; Start index parameter can't be empty sequence ", + getMetadata() + ); + } + int index = (int) Math.round(indexItem.getDoubleValue() - 1); + if (index >= stringItem.getStringValue().length()) { + return ItemFactory.getInstance().createStringItem(""); + } + if (this.children.size() > 2) { + Item endIndexItem = this.children.get(2) + .materializeFirstItemOrNull(context); + if (endIndexItem == null) { throw new UnexpectedTypeException( - "Type error; Start index parameter can't be empty sequence ", + "Type error; End index parameter can't be empty sequence ", getMetadata() ); } - int index = (int) Math.round(indexItem.getDoubleValue() - 1); - if (index >= stringItem.getStringValue().length()) { + double endIndex = sanitizeEndIndex(stringItem, endIndexItem, index); + if (endIndex < index) { return ItemFactory.getInstance().createStringItem(""); } - if (this.children.size() > 2) { - Item endIndexItem = this.children.get(2) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (endIndexItem == null) { - throw new UnexpectedTypeException( - "Type error; End index parameter can't be empty sequence ", - getMetadata() - ); - } - double endIndex = sanitizeEndIndex(stringItem, endIndexItem, index); - if (endIndex < index) { - return ItemFactory.getInstance().createStringItem(""); - } - result = stringItem.getStringValue().substring(Math.max(index, 0), (int) Math.round(endIndex)); - } else { - result = stringItem.getStringValue().substring(index); - } - - return ItemFactory.getInstance().createStringItem(result); + result = stringItem.getStringValue().substring(Math.max(index, 0), (int) Math.round(endIndex)); } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " substring function", - getMetadata() - ); + result = stringItem.getStringValue().substring(index); } + + return ItemFactory.getInstance().createStringItem(result); } private double sanitizeEndIndex(Item stringItem, Item endIndexItem, int startIndex) { diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/TranslateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/TranslateFunctionIterator.java index bd0a87497f..f0302909af 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/TranslateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/TranslateFunctionIterator.java @@ -21,18 +21,18 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; import java.util.HashMap; import java.util.stream.Collectors; -public class TranslateFunctionIterator extends LocalFunctionCallIterator { +public class TranslateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -45,51 +45,44 @@ public TranslateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item inputItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item mapStringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - Item transStringItem = this.children.get(2) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item inputItem = this.children.get(0) + .materializeFirstItemOrNull(context); + Item mapStringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + Item transStringItem = this.children.get(2) + .materializeFirstItemOrNull(context); - if (inputItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } + if (inputItem == null) { + return ItemFactory.getInstance().createStringItem(""); + } - String input = inputItem.getStringValue(); - String mapString = mapStringItem.getStringValue(); - String transString = transStringItem.getStringValue(); + String input = inputItem.getStringValue(); + String mapString = mapStringItem.getStringValue(); + String transString = transStringItem.getStringValue(); - HashMap mp = new HashMap<>(); - for (int i = 0; i < mapString.length(); i++) { - char c = mapString.charAt(i); - if (!(mp.containsKey(c))) { - mp.put(c, i < transString.length() ? transString.charAt(i) : '\0'); - } + HashMap mp = new HashMap<>(); + for (int i = 0; i < mapString.length(); i++) { + char c = mapString.charAt(i); + if (!(mp.containsKey(c))) { + mp.put(c, i < transString.length() ? transString.charAt(i) : '\0'); } + } - String output = input - .codePoints() - .mapToObj(c -> (char) c) - .filter(s -> !(mp.containsKey(s) && mp.get(s) == '\0')) - .map(s -> { - if (mp.containsKey(s)) { - return mp.get(s); - } - return s; - }) - .map(String::valueOf) - .collect(Collectors.joining()); - - return ItemFactory.getInstance().createStringItem(output); + String output = input + .codePoints() + .mapToObj(c -> (char) c) + .filter(s -> !(mp.containsKey(s) && mp.get(s) == '\0')) + .map(s -> { + if (mp.containsKey(s)) { + return mp.get(s); + } + return s; + }) + .map(String::valueOf) + .collect(Collectors.joining()); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " translate function", - getMetadata() - ); + return ItemFactory.getInstance().createStringItem(output); } + } From 4024df36ccb18a2cf1212006c195c79ff226e3b7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 11 Jun 2021 17:14:20 +0200 Subject: [PATCH 020/142] Normalize Space and Unicode, Codepoints2String. --- .../CodepointsToStringFunctionIterator.java | 48 +++++----- .../NormalizeSpaceFunctionIterator.java | 30 +++---- .../NormalizeUnicodeFunctionIterator.java | 87 +++++++++---------- 3 files changed, 72 insertions(+), 93 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/CodepointsToStringFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/CodepointsToStringFunctionIterator.java index ad59b87c53..35a9dca6d5 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/CodepointsToStringFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/CodepointsToStringFunctionIterator.java @@ -21,18 +21,18 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.exceptions.CodepointNotValidException; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CodepointsToStringFunctionIterator extends LocalFunctionCallIterator { +public class CodepointsToStringFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -45,34 +45,28 @@ public CodepointsToStringFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - List codepoints = this.children.get(0).materialize(this.currentDynamicContextForLocalExecution); + public Item materializeFirstItemOrNull(DynamicContext context) { + List codepoints = this.children.get(0).materialize(context); - StringBuilder stringBuilder = new StringBuilder(); - for (Item item : codepoints) { - if (!(item.isInt())) { - throw new UnexpectedTypeException( - "Int item expected", - this.children.get(0).getMetadata() - ); - } else if (!(isValidCodePoint(item.getIntValue()))) { - throw new CodepointNotValidException( - "Non-XML-conformant codepoint: " + item.getIntValue(), - this.children.get(0).getMetadata() - ); - } - stringBuilder.appendCodePoint(item.getIntValue()); + StringBuilder stringBuilder = new StringBuilder(); + for (Item item : codepoints) { + if (!(item.isInt())) { + throw new UnexpectedTypeException( + "Int item expected", + this.children.get(0).getMetadata() + ); + } else if (!(isValidCodePoint(item.getIntValue()))) { + throw new CodepointNotValidException( + "Non-XML-conformant codepoint: " + item.getIntValue(), + this.children.get(0).getMetadata() + ); } - this.hasNext = false; - return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " codepoints-to-string function", - getMetadata() - ); + stringBuilder.appendCodePoint(item.getIntValue()); + } + return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); } + private static boolean isValidCodePoint(int codepoint) { /* Checks if the codepoints are within the ranges allowed for in the XML 1.1 specification. */ return 1 <= codepoint && codepoint <= 55295 diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java index 604aab5ad6..69819b1ecf 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java @@ -22,16 +22,16 @@ import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class NormalizeSpaceFunctionIterator extends LocalFunctionCallIterator { +public class NormalizeSpaceFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -44,23 +44,15 @@ public NormalizeSpaceFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; + public Item materializeFirstItemOrNull(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - - if (stringItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } - - return ItemFactory.getInstance().createStringItem(StringUtils.normalizeSpace(stringItem.getStringValue())); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " normalize-space function", - getMetadata() - ); + if (stringItem == null) { + return ItemFactory.getInstance().createStringItem(""); } + + return ItemFactory.getInstance().createStringItem(StringUtils.normalizeSpace(stringItem.getStringValue())); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeUnicodeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeUnicodeFunctionIterator.java index 37082d2905..606871c5fe 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeUnicodeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeUnicodeFunctionIterator.java @@ -21,20 +21,20 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidNormalizationException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.text.Normalizer; import java.util.Arrays; import java.util.HashSet; import java.util.List; -public class NormalizeUnicodeFunctionIterator extends LocalFunctionCallIterator { +public class NormalizeUnicodeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private static final HashSet exclusionCharacters = new HashSet( @@ -133,56 +133,49 @@ public NormalizeUnicodeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - boolean fullyNormalized = false; - Normalizer.Form normalizationForm = Normalizer.Form.NFC; - Item inputItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + public Item materializeFirstItemOrNull(DynamicContext context) { + boolean fullyNormalized = false; + Normalizer.Form normalizationForm = Normalizer.Form.NFC; + Item inputItem = this.children.get(0) + .materializeFirstItemOrNull(context); - if (inputItem == null) { - return ItemFactory.getInstance().createStringItem(""); - } - - if (this.children.size() > 1) { - Item normalizationFormItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + if (inputItem == null) { + return ItemFactory.getInstance().createStringItem(""); + } - String normalizationFormRaw = normalizationFormItem.getStringValue(); - if (normalizationFormRaw.length() == 0) { - return inputItem; - } + if (this.children.size() > 1) { + Item normalizationFormItem = this.children.get(1) + .materializeFirstItemOrNull(context); - if ( - normalizationFormRaw.equals("NFC") - || normalizationFormRaw.equals("NFD") - || normalizationFormRaw.equals("NFKC") - || normalizationFormRaw.equals("NFKD") - ) { - normalizationForm = Normalizer.Form.valueOf(normalizationFormItem.getStringValue()); - } else if (normalizationFormRaw.equals("FULLY-NORMALIZED")) { - fullyNormalized = true; - normalizationForm = Normalizer.Form.NFC; - } else { - throw new InvalidNormalizationException( - normalizationFormRaw + " is not a valid normalization form", - getMetadata() - ); - } + String normalizationFormRaw = normalizationFormItem.getStringValue(); + if (normalizationFormRaw.length() == 0) { + return inputItem; } - String input = inputItem.getStringValue(); - if (fullyNormalized && exclusionCharacters.contains(input.codePointAt(0))) { - input = " " + input; + if ( + normalizationFormRaw.equals("NFC") + || normalizationFormRaw.equals("NFD") + || normalizationFormRaw.equals("NFKC") + || normalizationFormRaw.equals("NFKD") + ) { + normalizationForm = Normalizer.Form.valueOf(normalizationFormItem.getStringValue()); + } else if (normalizationFormRaw.equals("FULLY-NORMALIZED")) { + fullyNormalized = true; + normalizationForm = Normalizer.Form.NFC; + } else { + throw new InvalidNormalizationException( + normalizationFormRaw + " is not a valid normalization form", + getMetadata() + ); } - String normalizedString = Normalizer.normalize(input, normalizationForm); - return ItemFactory.getInstance().createStringItem(normalizedString); + } - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " translate function", - getMetadata() - ); + String input = inputItem.getStringValue(); + if (fullyNormalized && exclusionCharacters.contains(input.codePointAt(0))) { + input = " " + input; + } + String normalizedString = Normalizer.normalize(input, normalizationForm); + return ItemFactory.getInstance().createStringItem(normalizedString); } + } From 254b637ee23649a40872d610fadd3000c2106231 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 13 Jun 2021 15:26:43 +0200 Subject: [PATCH 021/142] AtMostOne - Time functions --- .../datetime/CurrentDateFunctionIterator.java | 16 +- .../CurrentDateTimeFunctionIterator.java | 16 +- .../datetime/CurrentTimeFunctionIterator.java | 16 +- .../datetime/FormatDateFunctionIterator.java | 224 ++++++++--------- .../FormatDateTimeFunctionIterator.java | 232 +++++++++--------- .../datetime/FormatTimeFunctionIterator.java | 232 +++++++++--------- .../components/AdjustDateTimeToTimezone.java | 103 ++++---- .../components/AdjustDateToTimezone.java | 103 ++++---- .../components/AdjustTimeToTimezone.java | 103 ++++---- .../DayFromDateFunctionIterator.java | 23 +- .../DayFromDateTimeFunctionIterator.java | 25 +- .../TimezoneFromDateFunctionIterator.java | 28 +-- .../TimezoneFromDateTimeFunctionIterator.java | 28 +-- .../TimezoneFromTimeFunctionIterator.java | 27 +- .../DayTimeDurationFunctionIterator.java | 39 ++- .../DaysFromDurationFunctionIterator.java | 25 +- 16 files changed, 553 insertions(+), 687 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java index 443f4b0d5a..3a97d2019b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java @@ -2,16 +2,18 @@ import org.joda.time.DateTime; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CurrentDateFunctionIterator extends LocalFunctionCallIterator { +public class CurrentDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -24,14 +26,8 @@ public CurrentDateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createDateItem(new DateTime(), true); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " current-date function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createDateItem(new DateTime(), true); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java index 0cbbabf901..902d2cd933 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java @@ -2,16 +2,18 @@ import org.joda.time.DateTime; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CurrentDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class CurrentDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -24,14 +26,8 @@ public CurrentDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createDateTimeItem(new DateTime(), true); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " current-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createDateTimeItem(new DateTime(), true); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java index cc6984b144..b45a605eff 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java @@ -2,16 +2,18 @@ import org.joda.time.DateTime; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CurrentTimeFunctionIterator extends LocalFunctionCallIterator { +public class CurrentTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -24,14 +26,8 @@ public CurrentTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createTimeItem(new DateTime(), true); - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " current-time function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createTimeItem(new DateTime(), true); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java index bfaebd15c7..2839571d30 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java @@ -11,6 +11,7 @@ import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; @@ -19,7 +20,7 @@ import java.util.Calendar; import java.util.List; -public class FormatDateFunctionIterator extends LocalFunctionCallIterator { +public class FormatDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item valueDateItem = null; @@ -33,6 +34,112 @@ public FormatDateFunctionIterator( super(arguments, executionMode, iteratorMetadata); } + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + this.valueDateItem = this.children.get(0) + .materializeFirstItemOrNull(context); + this.pictureStringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (this.valueDateItem == null || this.pictureStringItem == null) { + return null; + } + try { + if (this.valueDateItem.isNull()) { + return this.valueDateItem; + } + + DateTime dateValue = this.valueDateItem.getDateTimeValue(); + String pictureString = this.pictureStringItem.getStringValue(); + + int startOfSequence = 0; + boolean variableMarkerSequence = false; + + StringBuilder result = new StringBuilder(); + + // Iterate over picture + for (int i = 0; i < pictureString.length(); i++) { + char c = pictureString.charAt(i); + if (variableMarkerSequence) { + if (c == ']') { + String variableMarker = pictureString.substring(startOfSequence, i); + String pattern = parseVariableMarker(variableMarker, result); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); + Calendar formatCalendar = Calendar.getInstance(); + formatCalendar.set( + dateValue.getYear(), + dateValue.getMonthOfYear() - 1, + dateValue.getDayOfMonth() + ); + result.append(simpleDateFormat.format(formatCalendar.getTime())); + + variableMarkerSequence = false; + startOfSequence = i + 1; + } + } else { + if (c == ']') { + if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } + } else if (c == '[') { + if (i == pictureString.length() - 1) { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } + + if (pictureString.charAt(i + 1) == '[') { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } else { + String literalSubstring = pictureString.substring(startOfSequence, i); + result.append(literalSubstring); + variableMarkerSequence = true; + startOfSequence = i + 1; + } + } + } + } + + if (startOfSequence != pictureString.length()) { + if (variableMarkerSequence) { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring( + startOfSequence, + pictureString.length() + ); + result.append(literalSubstring); + } + } + return ItemFactory.getInstance().createStringItem(result.toString()); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( + "\"%s\": not castable to type %s", + this.valueDateItem.serialize(), + "date" + ); + throw new CastException(message, getMetadata()); + } + } + private String parsePresentationModifiers(String presentationModifiers) { String presentationModifier1 = ""; @@ -235,119 +342,4 @@ private String parseVariableMarker(String variableMarker, StringBuilder result) return pattern.toString(); } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - if (this.valueDateItem.isNull()) { - return this.valueDateItem; - } - - DateTime dateValue = this.valueDateItem.getDateTimeValue(); - String pictureString = this.pictureStringItem.getStringValue(); - - int startOfSequence = 0; - boolean variableMarkerSequence = false; - - StringBuilder result = new StringBuilder(); - - // Iterate over picture - for (int i = 0; i < pictureString.length(); i++) { - char c = pictureString.charAt(i); - if (variableMarkerSequence) { - if (c == ']') { - String variableMarker = pictureString.substring(startOfSequence, i); - String pattern = parseVariableMarker(variableMarker, result); - - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); - Calendar formatCalendar = Calendar.getInstance(); - formatCalendar.set( - dateValue.getYear(), - dateValue.getMonthOfYear() - 1, - dateValue.getDayOfMonth() - ); - result.append(simpleDateFormat.format(formatCalendar.getTime())); - - variableMarkerSequence = false; - startOfSequence = i + 1; - } - } else { - if (c == ']') { - if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } - } else if (c == '[') { - if (i == pictureString.length() - 1) { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } - - if (pictureString.charAt(i + 1) == '[') { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } else { - String literalSubstring = pictureString.substring(startOfSequence, i); - result.append(literalSubstring); - variableMarkerSequence = true; - startOfSequence = i + 1; - } - } - } - } - - if (startOfSequence != pictureString.length()) { - if (variableMarkerSequence) { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() - ); - result.append(literalSubstring); - } - } - return ItemFactory.getInstance().createStringItem(result.toString()); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": not castable to type %s", - this.valueDateItem.serialize(), - "date" - ); - throw new CastException(message, getMetadata()); - } - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " format-date function", - getMetadata() - ); - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.valueDateItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.valueDateItem != null && this.pictureStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java index 2ea82ec9df..93912bb288 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java @@ -11,6 +11,7 @@ import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; @@ -19,7 +20,7 @@ import java.util.Calendar; import java.util.List; -public class FormatDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class FormatDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item valueDateTimeItem = null; @@ -33,6 +34,116 @@ public FormatDateTimeFunctionIterator( super(arguments, executionMode, iteratorMetadata); } + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + this.valueDateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + this.pictureStringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (this.valueDateTimeItem == null || this.pictureStringItem == null) { + return null; + } + try { + if (this.valueDateTimeItem.isNull()) { + return this.valueDateTimeItem; + } + + DateTime dateTimeValue = this.valueDateTimeItem.getDateTimeValue(); + String pictureString = this.pictureStringItem.getStringValue(); + + // Start sequence + int startOfSequence = 0; + boolean variableMarkerSequence = false; + + StringBuilder result = new StringBuilder(); + + // Iterate over picture + for (int i = 0; i < pictureString.length(); i++) { + char c = pictureString.charAt(i); + if (variableMarkerSequence) { + if (c == ']') { + String variableMarker = pictureString.substring(startOfSequence, i); + String pattern = parseVariableMarker(variableMarker, result); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); + Calendar formatCalendar = Calendar.getInstance(); + formatCalendar.set( + dateTimeValue.getYear(), + dateTimeValue.getMonthOfYear() - 1, + dateTimeValue.getDayOfMonth(), + dateTimeValue.getHourOfDay(), + dateTimeValue.getMinuteOfHour(), + dateTimeValue.getSecondOfMinute() + ); + result.append(simpleDateFormat.format(formatCalendar.getTime())); + + variableMarkerSequence = false; + startOfSequence = i + 1; + } + } else { + if (c == ']') { + if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } + } else if (c == '[') { + if (i == pictureString.length() - 1) { + String message = String.format( + "\"%s\": incorrect syntax lala", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } + + if (pictureString.charAt(i + 1) == '[') { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } else { + String literalSubstring = pictureString.substring(startOfSequence, i); + result.append(literalSubstring); + variableMarkerSequence = true; + startOfSequence = i + 1; + } + } + } + } + + if (startOfSequence != pictureString.length()) { + if (variableMarkerSequence) { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring( + startOfSequence, + pictureString.length() + ); + result.append(literalSubstring); + } + } + return ItemFactory.getInstance().createStringItem(result.toString()); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( + "\"%s\": not castable to type %s", + this.valueDateTimeItem.serialize(), + "dateTime" + ); + throw new CastException(message, getMetadata()); + } + } + private String parsePresentationModifiers(String presentationModifiers) { String presentationModifier1 = ""; @@ -249,123 +360,4 @@ private String parseVariableMarker(String variableMarker, StringBuilder result) return pattern.toString(); } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - if (this.valueDateTimeItem.isNull()) { - return this.valueDateTimeItem; - } - - DateTime dateTimeValue = this.valueDateTimeItem.getDateTimeValue(); - String pictureString = this.pictureStringItem.getStringValue(); - - // Start sequence - int startOfSequence = 0; - boolean variableMarkerSequence = false; - - StringBuilder result = new StringBuilder(); - - // Iterate over picture - for (int i = 0; i < pictureString.length(); i++) { - char c = pictureString.charAt(i); - if (variableMarkerSequence) { - if (c == ']') { - String variableMarker = pictureString.substring(startOfSequence, i); - String pattern = parseVariableMarker(variableMarker, result); - - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); - Calendar formatCalendar = Calendar.getInstance(); - formatCalendar.set( - dateTimeValue.getYear(), - dateTimeValue.getMonthOfYear() - 1, - dateTimeValue.getDayOfMonth(), - dateTimeValue.getHourOfDay(), - dateTimeValue.getMinuteOfHour(), - dateTimeValue.getSecondOfMinute() - ); - result.append(simpleDateFormat.format(formatCalendar.getTime())); - - variableMarkerSequence = false; - startOfSequence = i + 1; - } - } else { - if (c == ']') { - if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } - } else if (c == '[') { - if (i == pictureString.length() - 1) { - String message = String.format( - "\"%s\": incorrect syntax lala", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } - - if (pictureString.charAt(i + 1) == '[') { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } else { - String literalSubstring = pictureString.substring(startOfSequence, i); - result.append(literalSubstring); - variableMarkerSequence = true; - startOfSequence = i + 1; - } - } - } - } - - if (startOfSequence != pictureString.length()) { - if (variableMarkerSequence) { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() - ); - result.append(literalSubstring); - } - } - return ItemFactory.getInstance().createStringItem(result.toString()); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": not castable to type %s", - this.valueDateTimeItem.serialize(), - "dateTime" - ); - throw new CastException(message, getMetadata()); - } - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " format-dateTime function", - getMetadata() - ); - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.valueDateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.valueDateTimeItem != null && this.pictureStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java index cdea9f166c..5091e92f32 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java @@ -11,6 +11,7 @@ import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; @@ -19,7 +20,7 @@ import java.util.Calendar; import java.util.List; -public class FormatTimeFunctionIterator extends LocalFunctionCallIterator { +public class FormatTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item valueTimeItem = null; @@ -33,6 +34,116 @@ public FormatTimeFunctionIterator( super(arguments, executionMode, iteratorMetadata); } + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + this.valueTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + this.pictureStringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (this.valueTimeItem == null || this.pictureStringItem == null) { + return null; + } + try { + if (this.valueTimeItem.isNull()) { + return this.valueTimeItem; + } + + DateTime timeValue = this.valueTimeItem.getDateTimeValue(); + String pictureString = this.pictureStringItem.getStringValue(); + + // Start sequence + int startOfSequence = 0; + boolean variableMarkerSequence = false; + + StringBuilder result = new StringBuilder(); + + // Iterate over picture + for (int i = 0; i < pictureString.length(); i++) { + char c = pictureString.charAt(i); + if (variableMarkerSequence) { + if (c == ']') { + String variableMarker = pictureString.substring(startOfSequence, i); + String pattern = parseVariableMarker(variableMarker, result); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); + Calendar formatCalendar = Calendar.getInstance(); + formatCalendar.set( + timeValue.getYear(), + timeValue.getMonthOfYear() - 1, + timeValue.getDayOfMonth(), + timeValue.getHourOfDay(), + timeValue.getMinuteOfHour(), + timeValue.getSecondOfMinute() + ); + result.append(simpleDateFormat.format(formatCalendar.getTime())); + + variableMarkerSequence = false; + startOfSequence = i + 1; + } + } else { + if (c == ']') { + if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } + } else if (c == '[') { + if (i == pictureString.length() - 1) { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } + + if (pictureString.charAt(i + 1) == '[') { + String literalSubstring = pictureString.substring(startOfSequence, i + 1); + result.append(literalSubstring); + startOfSequence = i + 2; + i++; + } else { + String literalSubstring = pictureString.substring(startOfSequence, i); + result.append(literalSubstring); + variableMarkerSequence = true; + startOfSequence = i + 1; + } + } + } + } + + if (startOfSequence != pictureString.length()) { + if (variableMarkerSequence) { + String message = String.format( + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() + ); + throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); + } else { + String literalSubstring = pictureString.substring( + startOfSequence, + pictureString.length() + ); + result.append(literalSubstring); + } + } + return ItemFactory.getInstance().createStringItem(result.toString()); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( + "\"%s\": not castable to type %s", + this.valueTimeItem.serialize(), + "time" + ); + throw new CastException(message, getMetadata()); + } + } + private String parsePresentationModifiers(String presentationModifiers) { String presentationModifier1 = ""; @@ -234,123 +345,4 @@ private String parseVariableMarker(String variableMarker, StringBuilder result) return pattern.toString(); } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - if (this.valueTimeItem.isNull()) { - return this.valueTimeItem; - } - - DateTime timeValue = this.valueTimeItem.getDateTimeValue(); - String pictureString = this.pictureStringItem.getStringValue(); - - // Start sequence - int startOfSequence = 0; - boolean variableMarkerSequence = false; - - StringBuilder result = new StringBuilder(); - - // Iterate over picture - for (int i = 0; i < pictureString.length(); i++) { - char c = pictureString.charAt(i); - if (variableMarkerSequence) { - if (c == ']') { - String variableMarker = pictureString.substring(startOfSequence, i); - String pattern = parseVariableMarker(variableMarker, result); - - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); - Calendar formatCalendar = Calendar.getInstance(); - formatCalendar.set( - timeValue.getYear(), - timeValue.getMonthOfYear() - 1, - timeValue.getDayOfMonth(), - timeValue.getHourOfDay(), - timeValue.getMinuteOfHour(), - timeValue.getSecondOfMinute() - ); - result.append(simpleDateFormat.format(formatCalendar.getTime())); - - variableMarkerSequence = false; - startOfSequence = i + 1; - } - } else { - if (c == ']') { - if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } - } else if (c == '[') { - if (i == pictureString.length() - 1) { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } - - if (pictureString.charAt(i + 1) == '[') { - String literalSubstring = pictureString.substring(startOfSequence, i + 1); - result.append(literalSubstring); - startOfSequence = i + 2; - i++; - } else { - String literalSubstring = pictureString.substring(startOfSequence, i); - result.append(literalSubstring); - variableMarkerSequence = true; - startOfSequence = i + 1; - } - } - } - } - - if (startOfSequence != pictureString.length()) { - if (variableMarkerSequence) { - String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() - ); - throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); - } else { - String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() - ); - result.append(literalSubstring); - } - } - return ItemFactory.getInstance().createStringItem(result.toString()); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": not castable to type %s", - this.valueTimeItem.serialize(), - "time" - ); - throw new CastException(message, getMetadata()); - } - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " format-time function", - getMetadata() - ); - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.valueTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.valueTimeItem != null && this.pictureStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java index c2c990a9d3..4a58055d7a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java @@ -9,12 +9,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class AdjustDateTimeToTimezone extends LocalFunctionCallIterator { +public class AdjustDateTimeToTimezone extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item timeItem = null; @@ -29,71 +30,59 @@ public AdjustDateTimeToTimezone( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - if (this.timezone == null && this.children.size() == 1) { - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.children.size() == 2) { + this.timezone = this.children.get(1) + .materializeFirstItemOrNull(context); + } + if (this.timeItem == null) { + return null; + } + if (this.timezone == null && this.children.size() == 1) { + return ItemFactory.getInstance() .createDateTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); - } - if (this.timezone == null) { - if (this.timeItem.hasTimeZone()) { - return ItemFactory.getInstance() + } + if (this.timezone == null) { + if (this.timeItem.hasTimeZone()) { + return ItemFactory.getInstance() .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), - false + this.timeItem.getDateTimeValue() + .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), + false ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createDateTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); - } else { - if (this.checkTimeZoneArgument()) { - throw new InvalidTimezoneException("Invalid timezone", getMetadata()); - } - if (this.timeItem.hasTimeZone()) { - return ItemFactory.getInstance() + } else { + if (this.checkTimeZoneArgument()) { + throw new InvalidTimezoneException("Invalid timezone", getMetadata()); + } + if (this.timeItem.hasTimeZone()) { + return ItemFactory.getInstance() .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " adjust-dateTime-to-timezone function", - getMetadata() - ); - } - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.timeItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (this.children.size() == 2) { - this.timezone = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); } - this.hasNext = this.timeItem != null; } private boolean checkTimeZoneArgument() { diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java index ab6005dcfe..4b82561fb9 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java @@ -9,12 +9,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class AdjustDateToTimezone extends LocalFunctionCallIterator { +public class AdjustDateToTimezone extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -29,71 +30,59 @@ public AdjustDateToTimezone( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - if (this.timezone == null && this.children.size() == 1) { - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.children.size() == 2) { + this.timezone = this.children.get(1) + .materializeFirstItemOrNull(context); + } + if (this.dateItem == null) { + return null; + } + if (this.timezone == null && this.children.size() == 1) { + return ItemFactory.getInstance() .createDateItem(this.dateItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); - } - if (this.timezone == null) { - if (this.dateItem.hasTimeZone()) { - return ItemFactory.getInstance() + } + if (this.timezone == null) { + if (this.dateItem.hasTimeZone()) { + return ItemFactory.getInstance() .createDateItem( - this.dateItem.getDateTimeValue() - .withZoneRetainFields(this.dateItem.getDateTimeValue().getZone()), - false + this.dateItem.getDateTimeValue() + .withZoneRetainFields(this.dateItem.getDateTimeValue().getZone()), + false ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createDateItem(this.dateItem.getDateTimeValue(), this.dateItem.hasTimeZone()); - } else { - if (this.checkTimeZoneArgument()) { - throw new InvalidTimezoneException("Invalid timezone", getMetadata()); - } - if (this.dateItem.hasTimeZone()) { - return ItemFactory.getInstance() + } else { + if (this.checkTimeZoneArgument()) { + throw new InvalidTimezoneException("Invalid timezone", getMetadata()); + } + if (this.dateItem.hasTimeZone()) { + return ItemFactory.getInstance() .createDateItem( - this.dateItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.dateItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createDateItem( - this.dateItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.dateItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " adjust-date-to-timezone function", - getMetadata() - ); - } - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (this.children.size() == 2) { - this.timezone = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); } - this.hasNext = this.dateItem != null; } private boolean checkTimeZoneArgument() { diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java index 37b00ef28a..fb4a0b20a7 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java @@ -9,12 +9,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class AdjustTimeToTimezone extends LocalFunctionCallIterator { +public class AdjustTimeToTimezone extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item timeItem = null; @@ -29,71 +30,59 @@ public AdjustTimeToTimezone( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - if (this.timezone == null && this.children.size() == 1) { - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.children.size() == 2) { + this.timezone = this.children.get(1) + .materializeFirstItemOrNull(context); + } + if (this.timeItem == null) { + return null; + } + if (this.timezone == null && this.children.size() == 1) { + return ItemFactory.getInstance() .createTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); - } - if (this.timezone == null) { - if (this.timeItem.hasTimeZone()) { - return ItemFactory.getInstance() + } + if (this.timezone == null) { + if (this.timeItem.hasTimeZone()) { + return ItemFactory.getInstance() .createTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), - false + this.timeItem.getDateTimeValue() + .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), + false ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); - } else { - if (this.checkTimeZoneArgument()) { - throw new InvalidTimezoneException("Invalid timezone", getMetadata()); - } - if (this.timeItem.hasTimeZone()) { - return ItemFactory.getInstance() + } else { + if (this.checkTimeZoneArgument()) { + throw new InvalidTimezoneException("Invalid timezone", getMetadata()); + } + if (this.timeItem.hasTimeZone()) { + return ItemFactory.getInstance() .createTimeItem( - this.timeItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - return ItemFactory.getInstance() + } + return ItemFactory.getInstance() .createTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); - } - - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " adjust-time-to-timezone function", - getMetadata() - ); - } - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.timeItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (this.children.size() == 2) { - this.timezone = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); } - this.hasNext = this.timeItem != null; } private boolean checkTimeZoneArgument() { diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java index 823f351447..41ce4303c1 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java @@ -6,12 +6,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class DayFromDateFunctionIterator extends LocalFunctionCallIterator { +public class DayFromDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -25,22 +26,12 @@ public DayFromDateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getDayOfMonth()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " day-from-date function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getDayOfMonth()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java index b4c51d135e..02f12a024c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java @@ -6,12 +6,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class DayFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class DayFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +26,13 @@ public DayFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getDayOfMonth()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " day-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getDayOfMonth()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java index 956c0be941..257533de38 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java @@ -7,12 +7,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class TimezoneFromDateFunctionIterator extends LocalFunctionCallIterator { +public class TimezoneFromDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -26,25 +27,14 @@ public TimezoneFromDateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateItem == null || !this.dateItem.hasTimeZone()) { + return null; + } + return ItemFactory.getInstance() .createDayTimeDurationItem( - new Period(this.dateItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + new Period(this.dateItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " timezone-from-date function", - getMetadata() - ); - } - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateItem != null && this.dateItem.hasTimeZone(); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java index 55d00eb8a3..ce6147c9ac 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java @@ -7,12 +7,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class TimezoneFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class TimezoneFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -26,26 +27,15 @@ public TimezoneFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateTimeItem == null || !this.dateTimeItem.hasTimeZone()) { + return null; + } + return ItemFactory.getInstance() .createDayTimeDurationItem( - new Period(this.dateTimeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + new Period(this.dateTimeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " timezone-from-dateTime function", - getMetadata() - ); - } } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null && this.dateTimeItem.hasTimeZone(); - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java index 40a5f3d611..3f14eec9b3 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java @@ -7,12 +7,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class TimezoneFromTimeFunctionIterator extends LocalFunctionCallIterator { +public class TimezoneFromTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item timeItem = null; @@ -26,25 +27,15 @@ public TimezoneFromTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); + if(this.timeItem == null || !this.timeItem.hasTimeZone()) { + return null; + } + return ItemFactory.getInstance() .createDayTimeDurationItem( - new Period(this.timeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + new Period(this.timeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " timezone-from-time function", - getMetadata() - ); - } } - @Override - public void open(DynamicContext context) { - super.open(context); - this.timeItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.timeItem != null && this.timeItem.hasTimeZone(); - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java index 0c0c9160f2..f6b7099faa 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java @@ -9,12 +9,13 @@ import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; -public class DayTimeDurationFunctionIterator extends LocalFunctionCallIterator { +public class DayTimeDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationStringItem = null; @@ -28,37 +29,27 @@ public DayTimeDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - Period period = DurationItem.getDurationFromString( + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationStringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationStringItem == null) { + return null; + } + try { + Period period = DurationItem.getDurationFromString( this.durationStringItem.getStringValue(), BuiltinTypesCatalogue.dayTimeDurationItem - ); - return ItemFactory.getInstance().createDayTimeDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( + ); + return ItemFactory.getInstance().createDayTimeDurationItem(period); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( "\"%s\": value of type %s is not castable to type %s", this.durationStringItem.serialize(), "string", "dayTimeDuration" - ); - throw new CastException(message, getMetadata()); - } - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " dayTimeDuration function", - getMetadata() ); + throw new CastException(message, getMetadata()); } } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java index 58924c0237..67199b0220 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java @@ -6,12 +6,13 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class DaysFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class DaysFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -25,23 +26,13 @@ public DaysFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getDays()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " days-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getDays()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; - } } From 8a37b40b0e29e82a0aae48ef6f5a0c855ad4307c Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 14 Jun 2021 10:34:10 +0200 Subject: [PATCH 022/142] Spotless. AtMostOne. Time Functions, Parse, Null, Codepoint, Length --- .../functions/NullFunctionIterator.java | 8 ++- .../arrays/ArraySizeFunctionIterator.java | 32 +++------- .../datetime/CurrentDateFunctionIterator.java | 2 - .../CurrentDateTimeFunctionIterator.java | 2 - .../datetime/CurrentTimeFunctionIterator.java | 2 - .../datetime/FormatDateFunctionIterator.java | 34 +++++------ .../FormatDateTimeFunctionIterator.java | 40 ++++++------- .../datetime/FormatTimeFunctionIterator.java | 40 ++++++------- .../components/AdjustDateTimeToTimezone.java | 58 +++++++++---------- .../components/AdjustDateToTimezone.java | 58 +++++++++---------- .../components/AdjustTimeToTimezone.java | 58 +++++++++---------- .../DayFromDateFunctionIterator.java | 2 - .../DayFromDateTimeFunctionIterator.java | 4 +- .../HoursFromDateTimeFunctionIterator.java | 27 +++------ .../HoursFromTimeFunctionIterator.java | 26 +++------ .../MinutesFromDateTimeFunctionIterator.java | 27 +++------ .../MinutesFromTimeFunctionIterator.java | 27 +++------ .../MonthFromDateFunctionIterator.java | 25 +++----- .../MonthFromDateTimeFunctionIterator.java | 27 +++------ .../SecondsFromDateTimeFunctionIterator.java | 39 +++++-------- .../SecondsFromTimeFunctionIterator.java | 37 +++++------- .../TimezoneFromDateFunctionIterator.java | 8 +-- .../TimezoneFromDateTimeFunctionIterator.java | 8 +-- .../TimezoneFromTimeFunctionIterator.java | 10 ++-- .../YearFromDateFunctionIterator.java | 25 +++----- .../DayTimeDurationFunctionIterator.java | 16 +++-- .../YearMonthDurationFunctionIterator.java | 53 +++++++---------- .../DaysFromDurationFunctionIterator.java | 4 +- .../HoursFromDurationFunctionIterator.java | 28 +++------ .../MinutesFromDurationFunctionIterator.java | 27 +++------ .../MonthsFromDurationFunctionIterator.java | 27 +++------ .../SecondsFromDurationFunctionIterator.java | 39 +++++-------- .../YearsFromDurationFunctionIterator.java | 27 +++------ .../io/ParseJsonFunctionIterator.java | 43 ++++++-------- .../CodepointEqualFunctionIterator.java | 31 +++------- .../strings/EndsWithFunctionIterator.java | 45 ++++++-------- .../strings/StartsWithFunctionIterator.java | 45 ++++++-------- .../strings/StringLengthFunctionIterator.java | 30 ++++------ 38 files changed, 393 insertions(+), 648 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/NullFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/NullFunctionIterator.java index 519930ab19..064ce7beeb 100644 --- a/src/main/java/org/rumbledb/runtime/functions/NullFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/NullFunctionIterator.java @@ -21,15 +21,16 @@ package org.rumbledb.runtime.functions; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class NullFunctionIterator extends LocalFunctionCallIterator { +public class NullFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,7 +44,8 @@ protected NullFunctionIterator( } @Override - public Item next() { + public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createNullItem(); } + } 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 39f0643a24..25790c8c41 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArraySizeFunctionIterator.java @@ -23,19 +23,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ArraySizeFunctionIterator extends LocalFunctionCallIterator { +public class ArraySizeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator arrayIterator; public ArraySizeFunctionIterator( List arguments, @@ -46,26 +44,12 @@ public ArraySizeFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - - this.arrayIterator = this.children.get(0); - this.arrayIterator.open(context); - this.hasNext = this.arrayIterator.hasNext(); - this.arrayIterator.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - - Item array = this.arrayIterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - return ItemFactory.getInstance().createIntItem(array.getSize()); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item array = this.children.get(0).materializeFirstItemOrNull(context); + if (array == null) { + return null; } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + "SIZE function", - getMetadata() - ); + return ItemFactory.getInstance().createIntItem(array.getSize()); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java index 3a97d2019b..41448e2769 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java index 902d2cd933..ae1f153389 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentDateTimeFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java index b45a605eff..2ad9294f19 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/CurrentTimeFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java index 2839571d30..37e8b83107 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateFunctionIterator.java @@ -7,13 +7,11 @@ import org.rumbledb.exceptions.ComponentSpecifierNotAvailableException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IncorrectSyntaxFormatDateTimeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -37,9 +35,9 @@ public FormatDateFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.valueDateItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.valueDateItem == null || this.pictureStringItem == null) { return null; } @@ -67,9 +65,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); Calendar formatCalendar = Calendar.getInstance(); formatCalendar.set( - dateValue.getYear(), - dateValue.getMonthOfYear() - 1, - dateValue.getDayOfMonth() + dateValue.getYear(), + dateValue.getMonthOfYear() - 1, + dateValue.getDayOfMonth() ); result.append(simpleDateFormat.format(formatCalendar.getTime())); @@ -80,8 +78,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (c == ']') { if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { @@ -93,8 +91,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } else if (c == '[') { if (i == pictureString.length() - 1) { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } @@ -117,14 +115,14 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (startOfSequence != pictureString.length()) { if (variableMarkerSequence) { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() + startOfSequence, + pictureString.length() ); result.append(literalSubstring); } @@ -132,9 +130,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createStringItem(result.toString()); } catch (UnsupportedOperationException | IllegalArgumentException e) { String message = String.format( - "\"%s\": not castable to type %s", - this.valueDateItem.serialize(), - "date" + "\"%s\": not castable to type %s", + this.valueDateItem.serialize(), + "date" ); throw new CastException(message, getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java index 93912bb288..d66bd9d8c8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatDateTimeFunctionIterator.java @@ -7,13 +7,11 @@ import org.rumbledb.exceptions.ComponentSpecifierNotAvailableException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IncorrectSyntaxFormatDateTimeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -37,9 +35,9 @@ public FormatDateTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.valueDateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.valueDateTimeItem == null || this.pictureStringItem == null) { return null; } @@ -68,12 +66,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); Calendar formatCalendar = Calendar.getInstance(); formatCalendar.set( - dateTimeValue.getYear(), - dateTimeValue.getMonthOfYear() - 1, - dateTimeValue.getDayOfMonth(), - dateTimeValue.getHourOfDay(), - dateTimeValue.getMinuteOfHour(), - dateTimeValue.getSecondOfMinute() + dateTimeValue.getYear(), + dateTimeValue.getMonthOfYear() - 1, + dateTimeValue.getDayOfMonth(), + dateTimeValue.getHourOfDay(), + dateTimeValue.getMinuteOfHour(), + dateTimeValue.getSecondOfMinute() ); result.append(simpleDateFormat.format(formatCalendar.getTime())); @@ -84,8 +82,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (c == ']') { if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { @@ -97,8 +95,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } else if (c == '[') { if (i == pictureString.length() - 1) { String message = String.format( - "\"%s\": incorrect syntax lala", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax lala", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } @@ -121,14 +119,14 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (startOfSequence != pictureString.length()) { if (variableMarkerSequence) { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() + startOfSequence, + pictureString.length() ); result.append(literalSubstring); } @@ -136,9 +134,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createStringItem(result.toString()); } catch (UnsupportedOperationException | IllegalArgumentException e) { String message = String.format( - "\"%s\": not castable to type %s", - this.valueDateTimeItem.serialize(), - "dateTime" + "\"%s\": not castable to type %s", + this.valueDateTimeItem.serialize(), + "dateTime" ); throw new CastException(message, getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java index 5091e92f32..9b68e53af7 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/FormatTimeFunctionIterator.java @@ -7,13 +7,11 @@ import org.rumbledb.exceptions.ComponentSpecifierNotAvailableException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IncorrectSyntaxFormatDateTimeException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnsupportedFeatureException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -37,9 +35,9 @@ public FormatTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.valueTimeItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); this.pictureStringItem = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.valueTimeItem == null || this.pictureStringItem == null) { return null; } @@ -68,12 +66,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern.toString()); Calendar formatCalendar = Calendar.getInstance(); formatCalendar.set( - timeValue.getYear(), - timeValue.getMonthOfYear() - 1, - timeValue.getDayOfMonth(), - timeValue.getHourOfDay(), - timeValue.getMinuteOfHour(), - timeValue.getSecondOfMinute() + timeValue.getYear(), + timeValue.getMonthOfYear() - 1, + timeValue.getDayOfMonth(), + timeValue.getHourOfDay(), + timeValue.getMinuteOfHour(), + timeValue.getSecondOfMinute() ); result.append(simpleDateFormat.format(formatCalendar.getTime())); @@ -84,8 +82,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (c == ']') { if (i == pictureString.length() - 1 || pictureString.charAt(i + 1) != ']') { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { @@ -97,8 +95,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } else if (c == '[') { if (i == pictureString.length() - 1) { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } @@ -121,14 +119,14 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (startOfSequence != pictureString.length()) { if (variableMarkerSequence) { String message = String.format( - "\"%s\": incorrect syntax", - this.pictureStringItem.serialize() + "\"%s\": incorrect syntax", + this.pictureStringItem.serialize() ); throw new IncorrectSyntaxFormatDateTimeException(message, getMetadata()); } else { String literalSubstring = pictureString.substring( - startOfSequence, - pictureString.length() + startOfSequence, + pictureString.length() ); result.append(literalSubstring); } @@ -136,9 +134,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createStringItem(result.toString()); } catch (UnsupportedOperationException | IllegalArgumentException e) { String message = String.format( - "\"%s\": not castable to type %s", - this.valueTimeItem.serialize(), - "time" + "\"%s\": not castable to type %s", + this.valueTimeItem.serialize(), + "time" ); throw new CastException(message, getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java index 4a58055d7a..e5abe9197a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateTimeToTimezone.java @@ -6,12 +6,10 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidTimezoneException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -34,54 +32,54 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); if (this.children.size() == 2) { this.timezone = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); } if (this.timeItem == null) { return null; } if (this.timezone == null && this.children.size() == 1) { return ItemFactory.getInstance() - .createDateTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); + .createDateTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); } if (this.timezone == null) { if (this.timeItem.hasTimeZone()) { return ItemFactory.getInstance() - .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), - false - ); + .createDateTimeItem( + this.timeItem.getDateTimeValue() + .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), + false + ); } return ItemFactory.getInstance() - .createDateTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); + .createDateTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); } else { if (this.checkTimeZoneArgument()) { throw new InvalidTimezoneException("Invalid timezone", getMetadata()); } if (this.timeItem.hasTimeZone()) { return ItemFactory.getInstance() - .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true - ); - } - return ItemFactory.getInstance() .createDateTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); + } + return ItemFactory.getInstance() + .createDateTimeItem( + this.timeItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java index 4b82561fb9..8f87fabec3 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustDateToTimezone.java @@ -6,12 +6,10 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidTimezoneException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -34,54 +32,54 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); if (this.children.size() == 2) { this.timezone = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); } if (this.dateItem == null) { return null; } if (this.timezone == null && this.children.size() == 1) { return ItemFactory.getInstance() - .createDateItem(this.dateItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); + .createDateItem(this.dateItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); } if (this.timezone == null) { if (this.dateItem.hasTimeZone()) { return ItemFactory.getInstance() - .createDateItem( - this.dateItem.getDateTimeValue() - .withZoneRetainFields(this.dateItem.getDateTimeValue().getZone()), - false - ); + .createDateItem( + this.dateItem.getDateTimeValue() + .withZoneRetainFields(this.dateItem.getDateTimeValue().getZone()), + false + ); } return ItemFactory.getInstance() - .createDateItem(this.dateItem.getDateTimeValue(), this.dateItem.hasTimeZone()); + .createDateItem(this.dateItem.getDateTimeValue(), this.dateItem.hasTimeZone()); } else { if (this.checkTimeZoneArgument()) { throw new InvalidTimezoneException("Invalid timezone", getMetadata()); } if (this.dateItem.hasTimeZone()) { return ItemFactory.getInstance() - .createDateItem( - this.dateItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true - ); - } - return ItemFactory.getInstance() .createDateItem( - this.dateItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.dateItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); + } + return ItemFactory.getInstance() + .createDateItem( + this.dateItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java index fb4a0b20a7..c9af1b24ea 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/AdjustTimeToTimezone.java @@ -6,12 +6,10 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidTimezoneException; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -34,54 +32,54 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); if (this.children.size() == 2) { this.timezone = this.children.get(1) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); } if (this.timeItem == null) { return null; } if (this.timezone == null && this.children.size() == 1) { return ItemFactory.getInstance() - .createTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); + .createTimeItem(this.timeItem.getDateTimeValue().withZone(DateTimeZone.UTC), true); } if (this.timezone == null) { if (this.timeItem.hasTimeZone()) { return ItemFactory.getInstance() - .createTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), - false - ); + .createTimeItem( + this.timeItem.getDateTimeValue() + .withZoneRetainFields(this.timeItem.getDateTimeValue().getZone()), + false + ); } return ItemFactory.getInstance() - .createTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); + .createTimeItem(this.timeItem.getDateTimeValue(), this.timeItem.hasTimeZone()); } else { if (this.checkTimeZoneArgument()) { throw new InvalidTimezoneException("Invalid timezone", getMetadata()); } if (this.timeItem.hasTimeZone()) { return ItemFactory.getInstance() - .createTimeItem( - this.timeItem.getDateTimeValue() - .withZone( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true - ); - } - return ItemFactory.getInstance() .createTimeItem( - this.timeItem.getDateTimeValue() - .withZoneRetainFields( - DateTimeZone.forOffsetHoursMinutes( - this.timezone.getDurationValue().getHours(), - this.timezone.getDurationValue().getMinutes() - ) - ), - true + this.timeItem.getDateTimeValue() + .withZone( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true ); + } + return ItemFactory.getInstance() + .createTimeItem( + this.timeItem.getDateTimeValue() + .withZoneRetainFields( + DateTimeZone.forOffsetHoursMinutes( + this.timezone.getDurationValue().getHours(), + this.timezone.getDurationValue().getMinutes() + ) + ), + true + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java index 41ce4303c1..7b00705fcc 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateFunctionIterator.java @@ -3,12 +3,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java index 02f12a024c..e1c7dca542 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/DayFromDateTimeFunctionIterator.java @@ -3,12 +3,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -28,7 +26,7 @@ public DayFromDateTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.dateTimeItem == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromDateTimeFunctionIterator.java index 322ea41433..dcef0581ce 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromDateTimeFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class HoursFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class HoursFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +24,13 @@ public HoursFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getHourOfDay()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " hours-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getHourOfDay()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromTimeFunctionIterator.java index 281ddf57d3..6c2ab11686 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/HoursFromTimeFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class HoursFromTimeFunctionIterator extends LocalFunctionCallIterator { +public class HoursFromTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -25,22 +24,11 @@ public HoursFromTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getHourOfDay()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " hours-from-time function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateItem == null) { + return null; } - } - - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateItem != null; + return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getHourOfDay()); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromDateTimeFunctionIterator.java index 1e4a23bef2..fe23568a4a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromDateTimeFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MinutesFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class MinutesFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +24,13 @@ public MinutesFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMinuteOfHour()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " minutes-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMinuteOfHour()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromTimeFunctionIterator.java index 682be068a2..ff3e3016a2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MinutesFromTimeFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MinutesFromTimeFunctionIterator extends LocalFunctionCallIterator { +public class MinutesFromTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +24,13 @@ public MinutesFromTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMinuteOfHour()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " minutes-from-time function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMinuteOfHour()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateFunctionIterator.java index 53636007a0..91c573575b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MonthFromDateFunctionIterator extends LocalFunctionCallIterator { +public class MonthFromDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -25,22 +24,12 @@ public MonthFromDateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getMonthOfYear()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " month-from-date function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getMonthOfYear()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateTimeFunctionIterator.java index 0549046988..6766fa3f1a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/MonthFromDateTimeFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MonthFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class MonthFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -25,23 +24,13 @@ public MonthFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMonthOfYear()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " month-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateTimeItem.getDateTimeValue().getMonthOfYear()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromDateTimeFunctionIterator.java index 9e559fa953..40c7baea00 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromDateTimeFunctionIterator.java @@ -3,16 +3,15 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.math.BigDecimal; import java.util.List; -public class SecondsFromDateTimeFunctionIterator extends LocalFunctionCallIterator { +public class SecondsFromDateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateTimeItem = null; @@ -26,29 +25,19 @@ public SecondsFromDateTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDecimalItem( - BigDecimal.valueOf( - this.dateTimeItem.getDateTimeValue().getSecondOfMinute() - + this.dateTimeItem.getDateTimeValue().getMillisOfSecond() * 1.0 / 1000 - ) - ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " seconds-from-dateTime function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateTimeItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.dateTimeItem == null) { + return null; } + return ItemFactory.getInstance() + .createDecimalItem( + BigDecimal.valueOf( + this.dateTimeItem.getDateTimeValue().getSecondOfMinute() + + this.dateTimeItem.getDateTimeValue().getMillisOfSecond() * 1.0 / 1000 + ) + ); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateTimeItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateTimeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromTimeFunctionIterator.java index 455d0d5878..33e6e95e03 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/SecondsFromTimeFunctionIterator.java @@ -3,16 +3,15 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.math.BigDecimal; import java.util.List; -public class SecondsFromTimeFunctionIterator extends LocalFunctionCallIterator { +public class SecondsFromTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item timeItem = null; @@ -26,28 +25,18 @@ public SecondsFromTimeFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDecimalItem( - BigDecimal.valueOf( - this.timeItem.getDateTimeValue().getSecondOfMinute() - + this.timeItem.getDateTimeValue().getMillisOfSecond() * 1.0 / 1000 - ) - ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " seconds-from-time function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.timeItem == null) { + return null; } + return ItemFactory.getInstance() + .createDecimalItem( + BigDecimal.valueOf( + this.timeItem.getDateTimeValue().getSecondOfMinute() + + this.timeItem.getDateTimeValue().getMillisOfSecond() * 1.0 / 1000 + ) + ); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.timeItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.timeItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java index 257533de38..7499bd6d54 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -33,8 +31,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return null; } return ItemFactory.getInstance() - .createDayTimeDurationItem( - new Period(this.dateItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) - ); + .createDayTimeDurationItem( + new Period(this.dateItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java index ce6147c9ac..d157dddb3b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromDateTimeFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -33,9 +31,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return null; } return ItemFactory.getInstance() - .createDayTimeDurationItem( - new Period(this.dateTimeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) - ); + .createDayTimeDurationItem( + new Period(this.dateTimeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java index 3f14eec9b3..9b08f5e1dc 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/TimezoneFromTimeFunctionIterator.java @@ -4,12 +4,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -29,13 +27,13 @@ public TimezoneFromTimeFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.timeItem = this.children.get(0).materializeFirstItemOrNull(context); - if(this.timeItem == null || !this.timeItem.hasTimeZone()) { + if (this.timeItem == null || !this.timeItem.hasTimeZone()) { return null; } return ItemFactory.getInstance() - .createDayTimeDurationItem( - new Period(this.timeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) - ); + .createDayTimeDurationItem( + new Period(this.timeItem.getDateTimeValue().getZone().toTimeZone().getRawOffset()) + ); } } diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateFunctionIterator.java index 4f3437814b..4b52489032 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/components/YearFromDateFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class YearFromDateFunctionIterator extends LocalFunctionCallIterator { +public class YearFromDateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item dateItem = null; @@ -25,22 +24,12 @@ public YearFromDateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getYear()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " year-from-date function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0).materializeFirstItemOrNull(context); + if (this.dateItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.dateItem.getDateTimeValue().getYear()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.dateItem = this.children.get(0).materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.dateItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java index f6b7099faa..739f004278 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java @@ -5,13 +5,11 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.CastException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; @@ -31,22 +29,22 @@ public DayTimeDurationFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.durationStringItem == null) { return null; } try { Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.dayTimeDurationItem + this.durationStringItem.getStringValue(), + BuiltinTypesCatalogue.dayTimeDurationItem ); return ItemFactory.getInstance().createDayTimeDurationItem(period); } catch (UnsupportedOperationException | IllegalArgumentException e) { String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "dayTimeDuration" + "\"%s\": value of type %s is not castable to type %s", + this.durationStringItem.serialize(), + "string", + "dayTimeDuration" ); throw new CastException(message, getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java index c2d4e6038f..c2d72e7cf9 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java @@ -5,16 +5,15 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.CastException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; -public class YearMonthDurationFunctionIterator extends LocalFunctionCallIterator { +public class YearMonthDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationStringItem = null; @@ -28,37 +27,27 @@ public YearMonthDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.yearMonthDurationItem - ); - return ItemFactory.getInstance().createYearMonthDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "yearMonthDuration" - ); - throw new CastException(message, getMetadata()); - } - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " yearMonthDuration function", - getMetadata() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationStringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationStringItem == null) { + return null; + } + try { + Period period = DurationItem.getDurationFromString( + this.durationStringItem.getStringValue(), + BuiltinTypesCatalogue.yearMonthDurationItem + ); + return ItemFactory.getInstance().createYearMonthDurationItem(period); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( + "\"%s\": value of type %s is not castable to type %s", + this.durationStringItem.serialize(), + "string", + "yearMonthDuration" ); + throw new CastException(message, getMetadata()); } } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java index 67199b0220..2554d8fbb1 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/DaysFromDurationFunctionIterator.java @@ -3,12 +3,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -28,7 +26,7 @@ public DaysFromDurationFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); if (this.durationItem == null) { return null; } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/HoursFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/HoursFromDurationFunctionIterator.java index 1b26437975..a406efeccc 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/HoursFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/HoursFromDurationFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class HoursFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class HoursFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -25,23 +24,14 @@ public HoursFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getHours()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " hours-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } - } + return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getHours()); - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/MinutesFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/MinutesFromDurationFunctionIterator.java index dc554ad29a..b0f092a4ba 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/MinutesFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/MinutesFromDurationFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MinutesFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class MinutesFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -25,23 +24,13 @@ public MinutesFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getMinutes()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " minutes-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getMinutes()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/MonthsFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/MonthsFromDurationFunctionIterator.java index ba41e43a8b..a9cb393610 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/MonthsFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/MonthsFromDurationFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class MonthsFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class MonthsFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -25,23 +24,13 @@ public MonthsFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getMonths()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " months-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getMonths()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/SecondsFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/SecondsFromDurationFunctionIterator.java index 6a797e09db..9fe0e39000 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/SecondsFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/SecondsFromDurationFunctionIterator.java @@ -3,16 +3,15 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.math.BigDecimal; import java.util.List; -public class SecondsFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class SecondsFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -26,29 +25,19 @@ public SecondsFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance() - .createDecimalItem( - BigDecimal.valueOf( - this.durationItem.getDurationValue().getSeconds() - + this.durationItem.getDurationValue().getMillis() * 1.0 / 1000 - ) - ); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " seconds-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } + return ItemFactory.getInstance() + .createDecimalItem( + BigDecimal.valueOf( + this.durationItem.getDurationValue().getSeconds() + + this.durationItem.getDurationValue().getMillis() * 1.0 / 1000 + ) + ); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/YearsFromDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/YearsFromDurationFunctionIterator.java index 518f856527..5c1d6d7723 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/components/YearsFromDurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/YearsFromDurationFunctionIterator.java @@ -3,15 +3,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class YearsFromDurationFunctionIterator extends LocalFunctionCallIterator { +public class YearsFromDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationItem = null; @@ -25,23 +24,13 @@ public YearsFromDurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getYears()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " years-from-duration function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationItem == null) { + return null; } + return ItemFactory.getInstance().createIntItem(this.durationItem.getDurationValue().getYears()); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/io/ParseJsonFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/io/ParseJsonFunctionIterator.java index 493fd71dc2..69206fb9bc 100644 --- a/src/main/java/org/rumbledb/runtime/functions/io/ParseJsonFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/io/ParseJsonFunctionIterator.java @@ -29,13 +29,13 @@ import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.parsing.ItemParser; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.io.StringReader; import java.util.List; -public class ParseJsonFunctionIterator extends LocalFunctionCallIterator { +public class ParseJsonFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -50,39 +50,30 @@ public ParseJsonFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); + public Item materializeFirstItemOrNull(DynamicContext context) { this.string = this.children.get(0).materializeFirstItemOrNull(context); - this.hasNext = this.string != null; + if (this.string == null) { + return null; + } + try { + JsonReader object = new JsonReader(new StringReader(this.string.getStringValue())); + return ItemParser.getItemFromObject(object, getMetadata()); + } catch (IteratorFlowException e) { + RumbleException ex = new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); + ex.initCause(e); + throw ex; + } } @Override public void reset(DynamicContext context) { super.reset(context); this.string = this.children.get(0).materializeFirstItemOrNull(context); - this.hasNext = this.string != null; - } - - @Override - public void close() { - super.close(); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - JsonReader object = new JsonReader(new StringReader(this.string.getStringValue())); - return ItemParser.getItemFromObject(object, getMetadata()); - } catch (IteratorFlowException e) { - RumbleException ex = new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); - ex.initCause(e); - throw ex; - } + if (this.string == null) { + return; } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " json-parse function", getMetadata()); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/CodepointEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/CodepointEqualFunctionIterator.java index 8ca0d37748..2dd47fc648 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/CodepointEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/CodepointEqualFunctionIterator.java @@ -23,15 +23,14 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class CodepointEqualFunctionIterator extends LocalFunctionCallIterator { +public class CodepointEqualFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private String input1; @@ -47,32 +46,20 @@ public CodepointEqualFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); + public Item materializeFirstItemOrNull(DynamicContext context) { this.input1 = null; this.input2 = null; - setNextResult(); + setNextResult(context); + Item result = this.nextResult; + return result; } - @Override - public Item next() { - if (this.hasNext) { - Item result = this.nextResult; - setNextResult(); - return result; - } else - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " codepoint-equal function", - getMetadata() - ); - } - - public void setNextResult() { + public void setNextResult(DynamicContext context) { if (this.input1 == null || this.input2 == null) { Item operandOneItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + .materializeFirstItemOrNull(context); Item operandTwoItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); + .materializeFirstItemOrNull(context); if (operandOneItem == null || operandTwoItem == null) { this.hasNext = false; return; diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java index be6a7c8ac1..049e50f314 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class EndsWithFunctionIterator extends LocalFunctionCallIterator { +public class EndsWithFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,29 +43,22 @@ public EndsWithFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item substringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (substringItem == null || substringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(true); - } - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (stringItem == null || stringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(false); - } - boolean result = stringItem.getStringValue() - .endsWith( - substringItem.getStringValue() - ); - return ItemFactory.getInstance().createBooleanItem(result); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " ends-with function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item substringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (substringItem == null || substringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(true); + } + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (stringItem == null || stringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(false); } + boolean result = stringItem.getStringValue() + .endsWith( + substringItem.getStringValue() + ); + return ItemFactory.getInstance().createBooleanItem(result); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java index 5154d80dff..c79eb47192 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class StartsWithFunctionIterator extends LocalFunctionCallIterator { +public class StartsWithFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,29 +43,22 @@ public StartsWithFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item substringItem = this.children.get(1) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (substringItem == null || substringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(true); - } - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - if (stringItem == null || stringItem.getStringValue().isEmpty()) { - return ItemFactory.getInstance().createBooleanItem(false); - } - boolean result = stringItem.getStringValue() - .startsWith( - substringItem.getStringValue() - ); - return ItemFactory.getInstance().createBooleanItem(result); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " starts-with function", - getMetadata() - ); + public Item materializeFirstItemOrNull(DynamicContext context) { + Item substringItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (substringItem == null || substringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(true); + } + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (stringItem == null || stringItem.getStringValue().isEmpty()) { + return ItemFactory.getInstance().createBooleanItem(false); } + boolean result = stringItem.getStringValue() + .startsWith( + substringItem.getStringValue() + ); + return ItemFactory.getInstance().createBooleanItem(result); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java index 5a697cf40a..36023d8448 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class StringLengthFunctionIterator extends LocalFunctionCallIterator { +public class StringLengthFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,23 +43,15 @@ public StringLengthFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; + public Item materializeFirstItemOrNull(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); - Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - - if (stringItem == null) { - return ItemFactory.getInstance().createIntItem(0); - } - - return ItemFactory.getInstance().createIntItem(stringItem.getStringValue().length()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " string-length function", - getMetadata() - ); + if (stringItem == null) { + return ItemFactory.getInstance().createIntItem(0); } + + return ItemFactory.getInstance().createIntItem(stringItem.getStringValue().length()); } + } From af25858bcba83f32786d99b4af69ce0d5a3f4949 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 14 Jun 2021 10:43:48 +0200 Subject: [PATCH 023/142] AtMostOne. Boolean, Concat --- .../booleans/BooleanFunctionIterator.java | 23 ++++++------ .../strings/ConcatFunctionIterator.java | 35 ++++++++----------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/booleans/BooleanFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/booleans/BooleanFunctionIterator.java index 3296a0c167..f9f68a285b 100644 --- a/src/main/java/org/rumbledb/runtime/functions/booleans/BooleanFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/booleans/BooleanFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.booleans; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class BooleanFunctionIterator extends LocalFunctionCallIterator { +public class BooleanFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,15 +43,12 @@ public BooleanFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - RuntimeIterator iterator = this.children.get(0); - boolean effectiveBooleanValue = iterator.getEffectiveBooleanValue( - this.currentDynamicContextForLocalExecution - ); - return ItemFactory.getInstance().createBooleanItem(effectiveBooleanValue); - } - throw new IteratorFlowException(RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " boolean function", getMetadata()); + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator iterator = this.children.get(0); + boolean effectiveBooleanValue = iterator.getEffectiveBooleanValue( + context + ); + return ItemFactory.getInstance().createBooleanItem(effectiveBooleanValue); } + } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ConcatFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ConcatFunctionIterator.java index f0e7436dea..eee61095e0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/ConcatFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ConcatFunctionIterator.java @@ -21,16 +21,16 @@ package org.rumbledb.runtime.functions.strings; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class ConcatFunctionIterator extends LocalFunctionCallIterator { +public class ConcatFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -43,26 +43,19 @@ public ConcatFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - StringBuilder builder = new StringBuilder(); - for (RuntimeIterator iterator : this.children) { - Item item = iterator.materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - // if not empty sequence - if (item != null) { - String stringValue = item.serialize(); - if (!stringValue.equals("")) { - builder.append(stringValue); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + StringBuilder builder = new StringBuilder(); + for (RuntimeIterator iterator : this.children) { + Item item = iterator.materializeFirstItemOrNull(context); + // if not empty sequence + if (item != null) { + String stringValue = item.serialize(); + if (!stringValue.equals("")) { + builder.append(stringValue); } } - this.hasNext = false; - return ItemFactory.getInstance().createStringItem(builder.toString()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " substring function", - getMetadata() - ); } + return ItemFactory.getInstance().createStringItem(builder.toString()); } + } From 242cbc5f324c047d911fd545a46e1aad60742513 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 15 Jun 2021 10:38:27 +0200 Subject: [PATCH 024/142] AtMostOne. Extra functions not in excel --- .../context/LastFunctionIterator.java | 24 ++----- .../context/PositionFunctionIterator.java | 24 ++----- .../durations/DurationFunctionIterator.java | 53 ++++++-------- .../value/DeepEqualFunctionIterator.java | 71 ++++++++----------- 4 files changed, 64 insertions(+), 108 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/context/LastFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/context/LastFunctionIterator.java index f732f32544..7094815ef0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/context/LastFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/context/LastFunctionIterator.java @@ -26,14 +26,14 @@ import org.rumbledb.exceptions.AbsentPartOfDynamicContextException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; import java.util.Map; import java.util.TreeMap; -public class LastFunctionIterator extends LocalFunctionCallIterator { +public class LastFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -47,22 +47,12 @@ public LastFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.hasNext = true; - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item result = this.currentDynamicContextForLocalExecution.getVariableValues().getLast(); - if (result == null) { - throw new AbsentPartOfDynamicContextException("Context undefined (last) ", getMetadata()); - } - return result; + public Item materializeFirstItemOrNull(DynamicContext context) { + Item result = context.getVariableValues().getLast(); + if (result == null) { + throw new AbsentPartOfDynamicContextException("Context undefined (last) ", getMetadata()); } - return null; + return result; } public Map getVariableDependencies() { diff --git a/src/main/java/org/rumbledb/runtime/functions/context/PositionFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/context/PositionFunctionIterator.java index 9a34f09a04..db9dba61ba 100644 --- a/src/main/java/org/rumbledb/runtime/functions/context/PositionFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/context/PositionFunctionIterator.java @@ -26,14 +26,14 @@ import org.rumbledb.exceptions.AbsentPartOfDynamicContextException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; import java.util.Map; import java.util.TreeMap; -public class PositionFunctionIterator extends LocalFunctionCallIterator { +public class PositionFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -47,22 +47,12 @@ public PositionFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - this.hasNext = true; - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - Item result = this.currentDynamicContextForLocalExecution.getVariableValues().getPosition(); - if (result == null) { - throw new AbsentPartOfDynamicContextException("Context undefined (position) ", getMetadata()); - } - return result; + public Item materializeFirstItemOrNull(DynamicContext context) { + Item result = context.getVariableValues().getPosition(); + if (result == null) { + throw new AbsentPartOfDynamicContextException("Context undefined (position) ", getMetadata()); } - return null; + return result; } public Map getVariableDependencies() { diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java index 4bc7440c72..a652a2d424 100644 --- a/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java @@ -5,16 +5,15 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.CastException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import java.util.List; -public class DurationFunctionIterator extends LocalFunctionCallIterator { +public class DurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private Item durationStringItem = null; @@ -28,37 +27,27 @@ public DurationFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.durationItem - ); - return ItemFactory.getInstance().createDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "duration" - ); - throw new CastException(message, getMetadata()); - } - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " duration function", - getMetadata() + public Item materializeFirstItemOrNull(DynamicContext context) { + this.durationStringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + if (this.durationStringItem == null) { + return null; + } + try { + Period period = DurationItem.getDurationFromString( + this.durationStringItem.getStringValue(), + BuiltinTypesCatalogue.durationItem + ); + return ItemFactory.getInstance().createDurationItem(period); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + String message = String.format( + "\"%s\": value of type %s is not castable to type %s", + this.durationStringItem.serialize(), + "string", + "duration" ); + throw new CastException(message, getMetadata()); } } - @Override - public void open(DynamicContext context) { - super.open(context); - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution); - this.hasNext = this.durationStringItem != null; - } } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 301c011db0..2e444a3614 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -27,17 +27,16 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import scala.Tuple2; import java.util.Iterator; import java.util.List; -public class DeepEqualFunctionIterator extends LocalFunctionCallIterator { +public class DeepEqualFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -52,48 +51,36 @@ public DeepEqualFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - } - - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - - RuntimeIterator sequenceIterator1 = this.children.get(0); - RuntimeIterator sequenceIterator2 = this.children.get(1); - - if (sequenceIterator1.isRDDOrDataFrame() && sequenceIterator2.isRDDOrDataFrame()) { - JavaRDD rdd1 = sequenceIterator1.getRDD(this.currentDynamicContextForLocalExecution); - JavaRDD rdd2 = sequenceIterator2.getRDD(this.currentDynamicContextForLocalExecution); - if (rdd1.partitions().size() == rdd2.partitions().size()) { - FlatMapFunction2, Iterator, Boolean> filter = - new SameElementsAndLengthClosure(); - JavaRDD differences = rdd1.zipPartitions(rdd2, filter); - return ItemFactory.getInstance().createBooleanItem(differences.isEmpty()); - } else { - JavaPairRDD rdd1Zipped = rdd1.zipWithIndex().mapToPair(Tuple2::swap); - JavaPairRDD rdd2Zipped = rdd2.zipWithIndex().mapToPair(Tuple2::swap); - JavaPairRDD, Optional>> rddJoined = rdd1Zipped.fullOuterJoin( - rdd2Zipped - ); - JavaPairRDD, Optional>> rddFiltered = rddJoined.filter( - tuple -> !tuple._2()._1().equals(tuple._2()._2()) - ); - return ItemFactory.getInstance().createBooleanItem(rddFiltered.isEmpty()); - } + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator sequenceIterator1 = this.children.get(0); + RuntimeIterator sequenceIterator2 = this.children.get(1); + + if (sequenceIterator1.isRDDOrDataFrame() && sequenceIterator2.isRDDOrDataFrame()) { + JavaRDD rdd1 = sequenceIterator1.getRDD(context); + JavaRDD rdd2 = sequenceIterator2.getRDD(context); + if (rdd1.partitions().size() == rdd2.partitions().size()) { + FlatMapFunction2, Iterator, Boolean> filter = + new SameElementsAndLengthClosure(); + JavaRDD differences = rdd1.zipPartitions(rdd2, filter); + return ItemFactory.getInstance().createBooleanItem(differences.isEmpty()); + } else { + JavaPairRDD rdd1Zipped = rdd1.zipWithIndex().mapToPair(Tuple2::swap); + JavaPairRDD rdd2Zipped = rdd2.zipWithIndex().mapToPair(Tuple2::swap); + JavaPairRDD, Optional>> rddJoined = rdd1Zipped.fullOuterJoin( + rdd2Zipped + ); + JavaPairRDD, Optional>> rddFiltered = rddJoined.filter( + tuple -> !tuple._2()._1().equals(tuple._2()._2()) + ); + return ItemFactory.getInstance().createBooleanItem(rddFiltered.isEmpty()); } - List items1 = sequenceIterator1.materialize(this.currentDynamicContextForLocalExecution); - List items2 = sequenceIterator2.materialize(this.currentDynamicContextForLocalExecution); - - boolean res = checkDeepEqual(items1, items2); - return ItemFactory.getInstance().createBooleanItem(res); - } else { - throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "deep-equal function", getMetadata()); } - } + List items1 = sequenceIterator1.materialize(context); + List items2 = sequenceIterator2.materialize(context); + boolean res = checkDeepEqual(items1, items2); + return ItemFactory.getInstance().createBooleanItem(res); + } public boolean checkDeepEqual(List items1, List items2) { if (items1.size() != items2.size()) { From 01005f1fa08689edea247e8139b834f027e3f5c7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 18 Jun 2021 17:36:47 +0200 Subject: [PATCH 025/142] Intersection from Hybrid to AtMostOne --- .../context/BuiltinFunctionCatalogue.java | 4 +- .../ObjectIntersectFunctionIterator.java | 99 +++++++------------ 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..70ea352915 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object+", + "object", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** * function that projects objects by filtering their pairs and leaves non-objects intact diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index 7897cc061c..207383de37 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -27,10 +27,9 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; -import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import sparksoniq.spark.SparkSessionManager; @@ -41,91 +40,65 @@ import java.util.LinkedHashMap; import java.util.List; -public class ObjectIntersectFunctionIterator extends HybridRuntimeIterator { +public class ObjectIntersectFunctionIterator extends AtMostOneItemLocalRuntimeIterator { /** * */ private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public ObjectIntersectFunctionIterator( - List arguments, + List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { - super(arguments, executionMode, iteratorMetadata); - this.iterator = arguments.get(0); + super(children, executionMode, iteratorMetadata); } @Override - public Item nextLocal() { - if (this.hasNext) { - List items = this.iterator.materialize(this.currentDynamicContextForLocalExecution); - LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); - boolean firstItem = true; - for (Item item : items) { - // ignore non-object items - if (item.isObject()) { - if (firstItem) { - // add all key-value pairs of the first item - for (String key : item.getKeys()) { + public Item materializeFirstItemOrNull(DynamicContext context) { + List items = this.children.get(0).materialize(context); + LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); + boolean firstItem = true; + for (Item item : items) { + // ignore non-object items + if (item.isObject()) { + if (firstItem) { + // add all key-value pairs of the first item + for (String key : item.getKeys()) { + Item value = item.getItemByKey(key); + ArrayList valueList = new ArrayList<>(); + valueList.add(value); + keyValuePairs.put(key, valueList); + } + firstItem = false; + } else { + // iterate over existing keys in the map of results + Iterator keyIterator = keyValuePairs.keySet().iterator(); + while (keyIterator.hasNext()) { + String key = keyIterator.next(); + // if the new item doesn't contain the same keys + if (!item.getKeys().contains(key)) { + // remove the key from the map + keyIterator.remove(); + } else { + // add the matching key's value to the list Item value = item.getItemByKey(key); - ArrayList valueList = new ArrayList<>(); - valueList.add(value); - keyValuePairs.put(key, valueList); - } - firstItem = false; - } else { - // iterate over existing keys in the map of results - Iterator keyIterator = keyValuePairs.keySet().iterator(); - while (keyIterator.hasNext()) { - String key = keyIterator.next(); - // if the new item doesn't contain the same keys - if (!item.getKeys().contains(key)) { - // remove the key from the map - keyIterator.remove(); - } else { - // add the matching key's value to the list - Item value = item.getItemByKey(key); - keyValuePairs.get(key).add(value); - } + keyValuePairs.get(key).add(value); } } } } - - Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); - - this.hasNext = false; - return result; } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " INTERSECT function", - getMetadata() - ); - } - @Override - protected void openLocal() { - } + Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); - @Override - protected void closeLocal() { + return result; } - @Override - protected void resetLocal() { - } - - @Override - protected boolean hasNextLocal() { - return this.hasNext; - } - - @Override + // @Override protected JavaRDD getRDDAux(DynamicContext context) { // Enclose object values into arrays. - JavaRDD childRDD = this.iterator.getRDD(context); + JavaRDD childRDD = this.children.get(0).getRDD(context); Function mapTransformation = new ObjectIntersectMapClosure(); JavaRDD mapResult = childRDD.map(mapTransformation); From 00014981b2069ae8d7da243b77e5543819d7e1aa Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 18 Jun 2021 17:36:47 +0200 Subject: [PATCH 026/142] Revert "Intersection from Hybrid to AtMostOne" This reverts commit 01005f1fa08689edea247e8139b834f027e3f5c7. --- .../context/BuiltinFunctionCatalogue.java | 4 +- .../ObjectIntersectFunctionIterator.java | 99 ++++++++++++------- 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 70ea352915..ebfa8dfb33 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object", + "object+", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that projects objects by filtering their pairs and leaves non-objects intact diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index 207383de37..7897cc061c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -27,9 +27,10 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; -import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import sparksoniq.spark.SparkSessionManager; @@ -40,65 +41,91 @@ import java.util.LinkedHashMap; import java.util.List; -public class ObjectIntersectFunctionIterator extends AtMostOneItemLocalRuntimeIterator { +public class ObjectIntersectFunctionIterator extends HybridRuntimeIterator { /** * */ private static final long serialVersionUID = 1L; + private RuntimeIterator iterator; public ObjectIntersectFunctionIterator( - List children, + List arguments, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { - super(children, executionMode, iteratorMetadata); + super(arguments, executionMode, iteratorMetadata); + this.iterator = arguments.get(0); } @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - List items = this.children.get(0).materialize(context); - LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); - boolean firstItem = true; - for (Item item : items) { - // ignore non-object items - if (item.isObject()) { - if (firstItem) { - // add all key-value pairs of the first item - for (String key : item.getKeys()) { - Item value = item.getItemByKey(key); - ArrayList valueList = new ArrayList<>(); - valueList.add(value); - keyValuePairs.put(key, valueList); - } - firstItem = false; - } else { - // iterate over existing keys in the map of results - Iterator keyIterator = keyValuePairs.keySet().iterator(); - while (keyIterator.hasNext()) { - String key = keyIterator.next(); - // if the new item doesn't contain the same keys - if (!item.getKeys().contains(key)) { - // remove the key from the map - keyIterator.remove(); - } else { - // add the matching key's value to the list + public Item nextLocal() { + if (this.hasNext) { + List items = this.iterator.materialize(this.currentDynamicContextForLocalExecution); + LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); + boolean firstItem = true; + for (Item item : items) { + // ignore non-object items + if (item.isObject()) { + if (firstItem) { + // add all key-value pairs of the first item + for (String key : item.getKeys()) { Item value = item.getItemByKey(key); - keyValuePairs.get(key).add(value); + ArrayList valueList = new ArrayList<>(); + valueList.add(value); + keyValuePairs.put(key, valueList); + } + firstItem = false; + } else { + // iterate over existing keys in the map of results + Iterator keyIterator = keyValuePairs.keySet().iterator(); + while (keyIterator.hasNext()) { + String key = keyIterator.next(); + // if the new item doesn't contain the same keys + if (!item.getKeys().contains(key)) { + // remove the key from the map + keyIterator.remove(); + } else { + // add the matching key's value to the list + Item value = item.getItemByKey(key); + keyValuePairs.get(key).add(value); + } } } } } + + Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); + + this.hasNext = false; + return result; } + throw new IteratorFlowException( + RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " INTERSECT function", + getMetadata() + ); + } - Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); + @Override + protected void openLocal() { + } - return result; + @Override + protected void closeLocal() { } - // @Override + @Override + protected void resetLocal() { + } + + @Override + protected boolean hasNextLocal() { + return this.hasNext; + } + + @Override protected JavaRDD getRDDAux(DynamicContext context) { // Enclose object values into arrays. - JavaRDD childRDD = this.children.get(0).getRDD(context); + JavaRDD childRDD = this.iterator.getRDD(context); Function mapTransformation = new ObjectIntersectMapClosure(); JavaRDD mapResult = childRDD.map(mapTransformation); From af86868f3eff884bce63146440aa0576c691e381 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 18 Jun 2021 18:47:04 +0200 Subject: [PATCH 027/142] Auto stash before revert of "Intersection from Hybrid to AtMostOne" --- .../object/ObjectIntersectFunctionIterator.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index 7897cc061c..8b00afbaa2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -47,14 +47,13 @@ public class ObjectIntersectFunctionIterator extends HybridRuntimeIterator { */ private static final long serialVersionUID = 1L; private RuntimeIterator iterator; - public ObjectIntersectFunctionIterator( - List arguments, + List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { - super(arguments, executionMode, iteratorMetadata); - this.iterator = arguments.get(0); + super(children, executionMode, iteratorMetadata); + this.iterator = this.children.get(0); } @Override @@ -137,5 +136,7 @@ protected JavaRDD getRDDAux(DynamicContext context) { JavaSparkContext sparkContext = SparkSessionManager.getInstance().getJavaSparkContext(); List listResult = Arrays.asList(reduceResult); return sparkContext.parallelize(listResult); + } + } From ec5f04b183b62e1a774482dcef414ab25fb9ea57 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 18 Jun 2021 19:03:43 +0200 Subject: [PATCH 028/142] spotless --- .../java/org/rumbledb/context/BuiltinFunctionCatalogue.java | 4 ++-- .../functions/object/ObjectIntersectFunctionIterator.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..70ea352915 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object+", + "object", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** * function that projects objects by filtering their pairs and leaves non-objects intact diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index 8b00afbaa2..ef8e9188e4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -47,6 +47,7 @@ public class ObjectIntersectFunctionIterator extends HybridRuntimeIterator { */ private static final long serialVersionUID = 1L; private RuntimeIterator iterator; + public ObjectIntersectFunctionIterator( List children, ExecutionMode executionMode, From c2321df60693a3465899887c95138fe5a640f669 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 18 Jun 2021 19:14:33 +0200 Subject: [PATCH 029/142] intersect catalogue back to initial --- .../java/org/rumbledb/context/BuiltinFunctionCatalogue.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 70ea352915..ebfa8dfb33 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object", + "object+", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that projects objects by filtering their pairs and leaves non-objects intact From a87f780110ccc3b566c87d0c4fc8931bca1ced46 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 19 Jun 2021 21:08:58 +0200 Subject: [PATCH 030/142] deepEqual. add if collation --- .../sequences/value/DeepEqualFunctionIterator.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 2e444a3614..4e69718140 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -26,7 +26,9 @@ import org.apache.spark.api.java.function.FlatMapFunction2; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -55,6 +57,13 @@ public Item materializeFirstItemOrNull(DynamicContext context) { RuntimeIterator sequenceIterator1 = this.children.get(0); RuntimeIterator sequenceIterator2 = this.children.get(1); + if (this.children.size() == 3) { + Item strColl = this.children.get(2).materializeFirstItemOrNull(context); + if (!strColl.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("XQST0038", getMetadata()); + } + } + if (sequenceIterator1.isRDDOrDataFrame() && sequenceIterator2.isRDDOrDataFrame()) { JavaRDD rdd1 = sequenceIterator1.getRDD(context); JavaRDD rdd2 = sequenceIterator2.getRDD(context); From 8a6399b8460396e1594c13fe7aa8e724edf7585d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 20 Jun 2021 13:03:06 +0200 Subject: [PATCH 031/142] RoundHalfToEven to numeric? --- .../context/BuiltinFunctionCatalogue.java | 6 +++--- .../RoundHalfToEvenFunctionIterator.java | 20 +++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..9d53884779 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -884,7 +884,7 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "double?", + "numeric?", "double?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL @@ -895,9 +895,9 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "double?", + "numeric?", "integer", - "double?", + "numeric?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 3d6bd94dbe..67e3f3c23a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -24,6 +24,7 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -37,7 +38,6 @@ public class RoundHalfToEvenFunctionIterator extends AtMostOneItemLocalRuntimeIt private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public RoundHalfToEvenFunctionIterator( List arguments, @@ -65,9 +65,21 @@ public Item materializeFirstItemOrNull(DynamicContext context) { precision = 0; } try { - BigDecimal bd = new BigDecimal(value.castToDoubleValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + if (value.isDouble()) { + BigDecimal bd = new BigDecimal(value.getDoubleValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + } + if (value.isDecimal()) { + BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDecimalItem(bd); + } + if (value.isFloat()) { + BigDecimal bd = new BigDecimal(value.getFloatValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + } + throw new UnexpectedTypeException("Unexpected value in round-half-to-even(): " + value.getDynamicType(), getMetadata()); } catch (IteratorFlowException e) { throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); From 1b47cbedc84bec48b310ef75d0e8b557b730828f Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 20 Jun 2021 13:03:06 +0200 Subject: [PATCH 032/142] RoundHalfToEven to numeric? --- .../context/BuiltinFunctionCatalogue.java | 8 ++++---- .../RoundHalfToEvenFunctionIterator.java | 20 +++++++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..e8e425e2b6 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -884,8 +884,8 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "double?", - "double?", + "numeric?", + "numeric?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -895,9 +895,9 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "double?", + "numeric?", "integer", - "double?", + "numeric?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 3d6bd94dbe..67e3f3c23a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -24,6 +24,7 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -37,7 +38,6 @@ public class RoundHalfToEvenFunctionIterator extends AtMostOneItemLocalRuntimeIt private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public RoundHalfToEvenFunctionIterator( List arguments, @@ -65,9 +65,21 @@ public Item materializeFirstItemOrNull(DynamicContext context) { precision = 0; } try { - BigDecimal bd = new BigDecimal(value.castToDoubleValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + if (value.isDouble()) { + BigDecimal bd = new BigDecimal(value.getDoubleValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + } + if (value.isDecimal()) { + BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDecimalItem(bd); + } + if (value.isFloat()) { + BigDecimal bd = new BigDecimal(value.getFloatValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + } + throw new UnexpectedTypeException("Unexpected value in round-half-to-even(): " + value.getDynamicType(), getMetadata()); } catch (IteratorFlowException e) { throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); From fe51050ea769b427ed4fae167340aa0e53c958f4 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 20 Jun 2021 13:13:28 +0200 Subject: [PATCH 033/142] spotless. --- .../functions/numerics/RoundHalfToEvenFunctionIterator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 67e3f3c23a..8151e9194f 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -79,7 +79,10 @@ public Item materializeFirstItemOrNull(DynamicContext context) { bd = bd.setScale(precision, RoundingMode.HALF_EVEN); return ItemFactory.getInstance().createFloatItem(bd.floatValue()); } - throw new UnexpectedTypeException("Unexpected value in round-half-to-even(): " + value.getDynamicType(), getMetadata()); + throw new UnexpectedTypeException( + "Unexpected value in round-half-to-even(): " + value.getDynamicType(), + getMetadata() + ); } catch (IteratorFlowException e) { throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); From fbf8e11eabc553cd4b223b3a18fcde0bd6f2feb5 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 20 Jun 2021 16:34:53 +0200 Subject: [PATCH 034/142] roundHalfToEven. support Int & Integer in order to pass the 2 last failed tests --- .../numerics/RoundHalfToEvenFunctionIterator.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 8151e9194f..4b89bd0691 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -79,6 +79,16 @@ public Item materializeFirstItemOrNull(DynamicContext context) { bd = bd.setScale(precision, RoundingMode.HALF_EVEN); return ItemFactory.getInstance().createFloatItem(bd.floatValue()); } + if (value.isInt()) { + BigDecimal bd = new BigDecimal(value.getIntValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntItem(bd.intValue()); + } + if (value.isInteger()) { + BigDecimal bd = new BigDecimal(value.getIntegerValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); + } throw new UnexpectedTypeException( "Unexpected value in round-half-to-even(): " + value.getDynamicType(), getMetadata() From 8cf9dee8144dc437567643d51afab8d8ffd8daf0 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 20 Jun 2021 16:34:53 +0200 Subject: [PATCH 035/142] roundHalfToEven. support Int & Integer in order to pass the 2 last failed tests --- .../numerics/RoundHalfToEvenFunctionIterator.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 8151e9194f..cc0d40e0e2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -65,6 +65,16 @@ public Item materializeFirstItemOrNull(DynamicContext context) { precision = 0; } try { + if (value.isInt()) { + BigDecimal bd = new BigDecimal(value.getIntValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntItem(bd.intValue()); + } + if (value.isInteger()) { + BigDecimal bd = new BigDecimal(value.getIntegerValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); + } if (value.isDouble()) { BigDecimal bd = new BigDecimal(value.getDoubleValue()); bd = bd.setScale(precision, RoundingMode.HALF_EVEN); @@ -79,6 +89,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { bd = bd.setScale(precision, RoundingMode.HALF_EVEN); return ItemFactory.getInstance().createFloatItem(bd.floatValue()); } + throw new UnexpectedTypeException( "Unexpected value in round-half-to-even(): " + value.getDynamicType(), getMetadata() From 97267db75b0144f0d3aa418bb15e7f8b2cba0851 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 11:46:33 +0200 Subject: [PATCH 036/142] comment collation part --- .../functions/sequences/value/DeepEqualFunctionIterator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 4e69718140..00f7e27065 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -57,12 +57,14 @@ public Item materializeFirstItemOrNull(DynamicContext context) { RuntimeIterator sequenceIterator1 = this.children.get(0); RuntimeIterator sequenceIterator2 = this.children.get(1); + /* if (this.children.size() == 3) { Item strColl = this.children.get(2).materializeFirstItemOrNull(context); if (!strColl.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { throw new DefaultCollationException("XQST0038", getMetadata()); } } + */ if (sequenceIterator1.isRDDOrDataFrame() && sequenceIterator2.isRDDOrDataFrame()) { JavaRDD rdd1 = sequenceIterator1.getRDD(context); From 3f0ecc8ec22f41a697efeb89fc5760d494a4e8d3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 13:08:20 +0200 Subject: [PATCH 037/142] SupportCollation. DeepEqual, Contains, StartsWith adapt catalogue as well, remaining crashes are from different collation strings --- .../context/BuiltinFunctionCatalogue.java | 55 ++++++++++++++++--- .../value/DeepEqualFunctionIterator.java | 10 +--- .../strings/ContainsFunctionIterator.java | 8 +++ .../strings/StartsWithFunctionIterator.java | 8 +++ 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..4114a58d82 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -793,7 +793,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that returns whether two sequences are deep-equal to each other */ - static final BuiltinFunction deep_equal = createBuiltinFunction( + static final BuiltinFunction deep_equal1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -805,6 +805,19 @@ private static BuiltinFunction createBuiltinFunction( DeepEqualFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction deep_equal2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "deep-equal" + ), + "item*", + "item*", + "string", + "boolean", + DeepEqualFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the absolute value of the arg */ @@ -1404,7 +1417,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that checks whether a string starts with a substring */ - static final BuiltinFunction starts_with = createBuiltinFunction( + static final BuiltinFunction starts_with1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1416,10 +1429,35 @@ private static BuiltinFunction createBuiltinFunction( StartsWithFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction starts_with2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "starts-with" + ), + "string?", + "string?", + "string", + "boolean", + StartsWithFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that checks whether a string contains a substring */ - static final BuiltinFunction contains = createBuiltinFunction( + static final BuiltinFunction contains1 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "contains" + ), + "string?", + "string?", + "boolean", + ContainsFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction contains2 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1427,6 +1465,7 @@ private static BuiltinFunction createBuiltinFunction( ), "string?", "string?", + "string", "boolean", ContainsFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL @@ -2295,8 +2334,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(distinct_values.getIdentifier(), distinct_values); builtinFunctions.put(index_of.getIdentifier(), index_of); - builtinFunctions.put(deep_equal.getIdentifier(), deep_equal); - + builtinFunctions.put(deep_equal1.getIdentifier(), deep_equal1); + builtinFunctions.put(deep_equal2.getIdentifier(), deep_equal2); builtinFunctions.put(abs.getIdentifier(), abs); builtinFunctions.put(ceiling.getIdentifier(), ceiling); builtinFunctions.put(floor.getIdentifier(), floor); @@ -2343,9 +2382,11 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(upper_case.getIdentifier(), upper_case); builtinFunctions.put(translate.getIdentifier(), translate); builtinFunctions.put(codepoint_equal.getIdentifier(), codepoint_equal); - builtinFunctions.put(starts_with.getIdentifier(), starts_with); + builtinFunctions.put(starts_with1.getIdentifier(), starts_with1); + builtinFunctions.put(starts_with2.getIdentifier(), starts_with2); builtinFunctions.put(matches.getIdentifier(), matches); - builtinFunctions.put(contains.getIdentifier(), contains); + builtinFunctions.put(contains1.getIdentifier(), contains1); + builtinFunctions.put(contains2.getIdentifier(), contains2); builtinFunctions.put(normalize_space.getIdentifier(), normalize_space); builtinFunctions.put(normalize_unicode1.getIdentifier(), normalize_unicode1); builtinFunctions.put(normalize_unicode2.getIdentifier(), normalize_unicode2); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 00f7e27065..7c7b18b729 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -28,7 +28,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -56,15 +55,12 @@ public DeepEqualFunctionIterator( public Item materializeFirstItemOrNull(DynamicContext context) { RuntimeIterator sequenceIterator1 = this.children.get(0); RuntimeIterator sequenceIterator2 = this.children.get(1); - - /* if (this.children.size() == 3) { - Item strColl = this.children.get(2).materializeFirstItemOrNull(context); - if (!strColl.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { - throw new DefaultCollationException("XQST0038", getMetadata()); + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); } } - */ if (sequenceIterator1.isRDDOrDataFrame() && sequenceIterator2.isRDDOrDataFrame()) { JavaRDD rdd1 = sequenceIterator1.getRDD(context); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java index 2c46ee4802..08d3f04eef 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ContainsFunctionIterator.java @@ -22,6 +22,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -44,6 +45,13 @@ public ContainsFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 3) { + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } + Item substringItem = this.children.get(1) .materializeFirstItemOrNull(context); if (substringItem == null || substringItem.getStringValue().isEmpty()) { diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java index c79eb47192..8920c40d60 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StartsWithFunctionIterator.java @@ -22,6 +22,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -44,6 +45,13 @@ public StartsWithFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 3) { + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } + Item substringItem = this.children.get(1) .materializeFirstItemOrNull(context); if (substringItem == null || substringItem.getStringValue().isEmpty()) { From a3afd87d3acadbbad55530c2c551fc528117d861 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 14:04:18 +0200 Subject: [PATCH 038/142] Revert "Merge remote-tracking branch 'origin/correct-types-pierre-motard' into support-collation-pierre-motard" This reverts commit a1595b711e174f68fc0b534582f65649017d28b6. --- .../context/BuiltinFunctionCatalogue.java | 8 ++--- .../RoundHalfToEvenFunctionIterator.java | 34 +++---------------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 2ab0b17ced..4114a58d82 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -897,8 +897,8 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "numeric?", - "numeric?", + "double?", + "double?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -908,9 +908,9 @@ private static BuiltinFunction createBuiltinFunction( "math", "round-half-to-even" ), - "numeric?", + "double?", "integer", - "numeric?", + "double?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index cc0d40e0e2..3d6bd94dbe 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -24,7 +24,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; -import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -38,6 +37,7 @@ public class RoundHalfToEvenFunctionIterator extends AtMostOneItemLocalRuntimeIt private static final long serialVersionUID = 1L; + private RuntimeIterator iterator; public RoundHalfToEvenFunctionIterator( List arguments, @@ -65,35 +65,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { precision = 0; } try { - if (value.isInt()) { - BigDecimal bd = new BigDecimal(value.getIntValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createIntItem(bd.intValue()); - } - if (value.isInteger()) { - BigDecimal bd = new BigDecimal(value.getIntegerValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); - } - if (value.isDouble()) { - BigDecimal bd = new BigDecimal(value.getDoubleValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); - } - if (value.isDecimal()) { - BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDecimalItem(bd); - } - if (value.isFloat()) { - BigDecimal bd = new BigDecimal(value.getFloatValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createFloatItem(bd.floatValue()); - } - - throw new UnexpectedTypeException( - "Unexpected value in round-half-to-even(): " + value.getDynamicType(), - getMetadata() - ); + BigDecimal bd = new BigDecimal(value.castToDoubleValue()); + bd = bd.setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); } catch (IteratorFlowException e) { throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); From 3f381b473f7b55623eb7757962d9c7c8ffc5f2d4 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 15:30:26 +0200 Subject: [PATCH 039/142] Collation support. EndsWith, Substring before/after --- .../context/BuiltinFunctionCatalogue.java | 64 ++++++++++++++++--- .../strings/EndsWithFunctionIterator.java | 7 ++ .../SubstringAfterFunctionIterator.java | 8 ++- .../SubstringBeforeFunctionIterator.java | 7 ++ 4 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 4114a58d82..2fbc806407 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1146,7 +1146,7 @@ private static BuiltinFunction createBuiltinFunction( * function that returns the part of the first variable that precedes the first occurrence of the second * variable. */ - static final BuiltinFunction substring_before = createBuiltinFunction( + static final BuiltinFunction substring_before1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1158,11 +1158,36 @@ private static BuiltinFunction createBuiltinFunction( SubstringBeforeFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction substring_before2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "substring-before" + ), + "string?", + "string?", + "string", + "string", + SubstringBeforeFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the part of the first variable that follows the first occurrence of the second * vairable. */ - static final BuiltinFunction substring_after = createBuiltinFunction( + static final BuiltinFunction substring_after1 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "substring-after" + ), + "string?", + "string?", + "string", + SubstringAfterFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction substring_after2 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1171,6 +1196,7 @@ private static BuiltinFunction createBuiltinFunction( "string?", "string?", "string", + "string", SubstringAfterFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -1262,7 +1288,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that replaces parts of a string according to a regex expression */ - static final BuiltinFunction replace = createBuiltinFunction( + static final BuiltinFunction replace1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1275,6 +1301,7 @@ private static BuiltinFunction createBuiltinFunction( ReplaceFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** * function that returns the string length */ @@ -1402,7 +1429,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that checks whether a string ends with a substring */ - static final BuiltinFunction ends_with = createBuiltinFunction( + static final BuiltinFunction ends_with1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1414,6 +1441,19 @@ private static BuiltinFunction createBuiltinFunction( EndsWithFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction ends_with2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "ends-with" + ), + "string?", + "string?", + "string", + "boolean", + EndsWithFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that checks whether a string starts with a substring */ @@ -1473,7 +1513,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that checks whether a string matches a regular expression */ - static final BuiltinFunction matches = createBuiltinFunction( + static final BuiltinFunction matches1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1485,6 +1525,7 @@ private static BuiltinFunction createBuiltinFunction( MatchesFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** * function that normalizes spaces in a string */ @@ -2361,18 +2402,21 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(codepoints_to_string.getIdentifier(), codepoints_to_string); builtinFunctions.put(string_to_codepoints.getIdentifier(), string_to_codepoints); - builtinFunctions.put(replace.getIdentifier(), replace); + builtinFunctions.put(replace1.getIdentifier(), replace1); builtinFunctions.put(substring2.getIdentifier(), substring2); builtinFunctions.put(substring3.getIdentifier(), substring3); - builtinFunctions.put(substring_before.getIdentifier(), substring_before); - builtinFunctions.put(substring_after.getIdentifier(), substring_after); + builtinFunctions.put(substring_before1.getIdentifier(), substring_before1); + builtinFunctions.put(substring_before2.getIdentifier(), substring_before2); + builtinFunctions.put(substring_after1.getIdentifier(), substring_after1); + builtinFunctions.put(substring_after2.getIdentifier(), substring_after2); for (int i = 0; i < 100; i++) { builtinFunctions.put( new FunctionIdentifier(Name.createVariableInDefaultFunctionNamespace("concat"), i), concat ); } - builtinFunctions.put(ends_with.getIdentifier(), ends_with); + builtinFunctions.put(ends_with1.getIdentifier(), ends_with1); + builtinFunctions.put(ends_with2.getIdentifier(), ends_with2); builtinFunctions.put(string_join1.getIdentifier(), string_join1); builtinFunctions.put(string_join2.getIdentifier(), string_join2); builtinFunctions.put(string_length.getIdentifier(), string_length); @@ -2384,7 +2428,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(codepoint_equal.getIdentifier(), codepoint_equal); builtinFunctions.put(starts_with1.getIdentifier(), starts_with1); builtinFunctions.put(starts_with2.getIdentifier(), starts_with2); - builtinFunctions.put(matches.getIdentifier(), matches); + builtinFunctions.put(matches1.getIdentifier(), matches1); builtinFunctions.put(contains1.getIdentifier(), contains1); builtinFunctions.put(contains2.getIdentifier(), contains2); builtinFunctions.put(normalize_space.getIdentifier(), normalize_space); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java index 049e50f314..6cf37d6cfe 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/EndsWithFunctionIterator.java @@ -22,6 +22,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -44,6 +45,12 @@ public EndsWithFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 3) { + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } Item substringItem = this.children.get(1) .materializeFirstItemOrNull(context); if (substringItem == null || substringItem.getStringValue().isEmpty()) { diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java index bbc91f2275..cc524fa5f2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringAfterFunctionIterator.java @@ -2,6 +2,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -28,7 +29,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { .materializeFirstItemOrNull(context); Item substringItem = this.children.get(1) .materializeFirstItemOrNull(context); - + if (this.children.size() == 3) { + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } if (stringItem == null || stringItem.getStringValue().isEmpty()) { return ItemFactory.getInstance().createStringItem(""); } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java index eafc21e68b..1924f86b09 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SubstringBeforeFunctionIterator.java @@ -2,6 +2,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -28,6 +29,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { .materializeFirstItemOrNull(context); Item substringItem = this.children.get(1) .materializeFirstItemOrNull(context); + if (this.children.size() == 3) { + String collation = this.children.get(2).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } if ( substringItem == null || substringItem.getStringValue().isEmpty() From 1cea585951b53576a26f07c620b5d7b9a63ba404 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 15:42:08 +0200 Subject: [PATCH 040/142] Support collation. Distinct values, index of --- .../context/BuiltinFunctionCatalogue.java | 35 ++++++++++++++++--- .../value/DistinctValuesFunctionIterator.java | 9 +++++ .../value/IndexOfFunctionIterator.java | 11 ++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 2fbc806407..f1671d2cf9 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -764,7 +764,7 @@ private static BuiltinFunction createBuiltinFunction( /** * function that returns the values that appear in a sequence, with duplicates eliminated */ - static final BuiltinFunction distinct_values = createBuiltinFunction( + static final BuiltinFunction distinct_values1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -775,10 +775,22 @@ private static BuiltinFunction createBuiltinFunction( DistinctValuesFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); + static final BuiltinFunction distinct_values2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "distinct-values" + ), + "atomic*", + "string", + "atomic*", + DistinctValuesFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + ); /** * function that returns indices of items that are equal to the search parameter */ - static final BuiltinFunction index_of = createBuiltinFunction( + static final BuiltinFunction index_of1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -790,6 +802,19 @@ private static BuiltinFunction createBuiltinFunction( IndexOfFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); + static final BuiltinFunction index_of2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "index-of" + ), + "atomic*", + "atomic", + "string", + "integer*", + IndexOfFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + ); /** * function that returns whether two sequences are deep-equal to each other */ @@ -2373,8 +2398,10 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(one_or_more.getIdentifier(), one_or_more); builtinFunctions.put(exactly_one.getIdentifier(), exactly_one); - builtinFunctions.put(distinct_values.getIdentifier(), distinct_values); - builtinFunctions.put(index_of.getIdentifier(), index_of); + builtinFunctions.put(distinct_values1.getIdentifier(), distinct_values1); + builtinFunctions.put(distinct_values2.getIdentifier(), distinct_values2); + builtinFunctions.put(index_of1.getIdentifier(), index_of1); + builtinFunctions.put(index_of2.getIdentifier(), index_of2); builtinFunctions.put(deep_equal1.getIdentifier(), deep_equal1); builtinFunctions.put(deep_equal2.getIdentifier(), deep_equal2); builtinFunctions.put(abs.getIdentifier(), abs); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DistinctValuesFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DistinctValuesFunctionIterator.java index dc8011905f..12a094b58e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DistinctValuesFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DistinctValuesFunctionIterator.java @@ -23,6 +23,7 @@ import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; @@ -48,6 +49,14 @@ public DistinctValuesFunctionIterator( ) { super(arguments, executionMode, iteratorMetadata); this.sequenceIterator = arguments.get(0); + if (arguments.size() == 2) { + String collation = arguments.get(1) + .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) + .getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } } public Item nextLocal() { diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/IndexOfFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/IndexOfFunctionIterator.java index 3b26d79534..9cf3bcabda 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/IndexOfFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/IndexOfFunctionIterator.java @@ -24,6 +24,7 @@ import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.NonAtomicKeyException; @@ -54,6 +55,16 @@ public IndexOfFunctionIterator( super(arguments, executionMode, iteratorMetadata); this.sequenceIterator = this.children.get(0); this.searchIterator = this.children.get(1); + + if (this.children.size() == 3) { + String collation = this.children.get(2) + .materializeFirstItemOrNull(this.currentDynamicContextForLocalExecution) + .getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } + } @Override From 67c94ba7b2a261d9838c3abe673d2fa621c83fa5 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 21 Jun 2021 16:48:46 +0200 Subject: [PATCH 041/142] AtMostOne from Hybrid. ObjectIntersect --- .../ObjectIntersectFunctionIterator.java | 42 ++++--------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index ef8e9188e4..ced3eacea0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -30,6 +30,7 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -41,7 +42,7 @@ import java.util.LinkedHashMap; import java.util.List; -public class ObjectIntersectFunctionIterator extends HybridRuntimeIterator { +public class ObjectIntersectFunctionIterator extends AtMostOneItemLocalRuntimeIterator { /** * */ @@ -58,9 +59,9 @@ public ObjectIntersectFunctionIterator( } @Override - public Item nextLocal() { - if (this.hasNext) { - List items = this.iterator.materialize(this.currentDynamicContextForLocalExecution); + public Item materializeFirstItemOrNull(DynamicContext context) { + if (!this.iterator.isRDDOrDataFrame()) { + List items = this.iterator.materialize(context); LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); boolean firstItem = true; for (Item item : items) { @@ -96,34 +97,9 @@ public Item nextLocal() { Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); - this.hasNext = false; return result; } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " INTERSECT function", - getMetadata() - ); - } - - @Override - protected void openLocal() { - } - @Override - protected void closeLocal() { - } - - @Override - protected void resetLocal() { - } - - @Override - protected boolean hasNextLocal() { - return this.hasNext; - } - - @Override - protected JavaRDD getRDDAux(DynamicContext context) { // Enclose object values into arrays. JavaRDD childRDD = this.iterator.getRDD(context); Function mapTransformation = new ObjectIntersectMapClosure(); @@ -131,13 +107,11 @@ protected JavaRDD getRDDAux(DynamicContext context) { // Reduce input objects. Function2 transformation = new ObjectIntersectReduceClosure(); - Item reduceResult = mapResult.reduce(transformation); + Item result = mapResult.reduce(transformation); - // transform Item to JavaRDD - JavaSparkContext sparkContext = SparkSessionManager.getInstance().getJavaSparkContext(); - List listResult = Arrays.asList(reduceResult); - return sparkContext.parallelize(listResult); + return result; } + } From 1689eb3896f03b83d2a32ad783a463f8223f4c60 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 22 Jun 2021 12:06:02 +0200 Subject: [PATCH 042/142] Collation min#2 max#2 --- .../context/BuiltinFunctionCatalogue.java | 26 ++++++++++++++++--- .../aggregate/MaxFunctionIterator.java | 7 +++++ .../aggregate/MinFunctionIterator.java | 7 +++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index f1671d2cf9..9b016e93a2 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -549,23 +549,39 @@ private static BuiltinFunction createBuiltinFunction( /** * function that returns the minimum of a sequence */ - static final BuiltinFunction min = createBuiltinFunction( + static final BuiltinFunction min1 = createBuiltinFunction( new Name(Name.FN_NS, "fn", "min"), "item*", "atomic?", MinFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction min2 = createBuiltinFunction( + new Name(Name.FN_NS, "fn", "min"), + "item*", + "string", + "atomic?", + MinFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the maximum of a sequence */ - static final BuiltinFunction max = createBuiltinFunction( + static final BuiltinFunction max1 = createBuiltinFunction( new Name(Name.FN_NS, "fn", "max"), "item*", "atomic?", MaxFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + static final BuiltinFunction max2 = createBuiltinFunction( + new Name(Name.FN_NS, "fn", "max"), + "item*", + "string", + "atomic?", + MaxFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the average of a sequence */ @@ -2378,8 +2394,10 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(count.getIdentifier(), count); builtinFunctions.put(boolean_function.getIdentifier(), boolean_function); - builtinFunctions.put(min.getIdentifier(), min); - builtinFunctions.put(max.getIdentifier(), max); + builtinFunctions.put(min1.getIdentifier(), min1); + builtinFunctions.put(min2.getIdentifier(), min2); + builtinFunctions.put(max1.getIdentifier(), max1); + builtinFunctions.put(max2.getIdentifier(), max2); builtinFunctions.put(sum1.getIdentifier(), sum1); builtinFunctions.put(sum2.getIdentifier(), sum2); builtinFunctions.put(avg.getIdentifier(), avg); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index aab3046b02..0b64e88d07 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -24,6 +24,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; import org.rumbledb.exceptions.RumbleException; @@ -62,6 +63,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { getMetadata() ) ); + if (this.children.size() == 2) { + String collation = this.children.get(1).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } if (!this.iterator.isRDDOrDataFrame()) { diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index ea637426df..aa5b17f66e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -24,6 +24,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.exceptions.DefaultCollationException; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidArgumentTypeException; import org.rumbledb.exceptions.RumbleException; @@ -62,6 +63,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { getMetadata() ) ); + if (this.children.size() == 2) { + String collation = this.children.get(1).materializeFirstItemOrNull(context).getStringValue(); + if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { + throw new DefaultCollationException("Wrong collation parameter", getMetadata()); + } + } if (!this.iterator.isRDDOrDataFrame()) { From 902a9041c7d2d3731406f13a6ac66a7e1437ebfa Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 22 Jun 2021 15:25:38 +0200 Subject: [PATCH 043/142] fix intersect --- .../java/org/rumbledb/context/BuiltinFunctionCatalogue.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..70ea352915 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object+", + "object", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** * function that projects objects by filtering their pairs and leaves non-objects intact From 2e63c10dd9633c1a1d2765adac08b9b728ffb543 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 22 Jun 2021 15:25:38 +0200 Subject: [PATCH 044/142] fix intersect --- .../java/org/rumbledb/context/BuiltinFunctionCatalogue.java | 4 ++-- .../functions/object/ObjectIntersectFunctionIterator.java | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ebfa8dfb33..70ea352915 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2135,9 +2135,9 @@ private static BuiltinFunction createBuiltinFunction( "intersect" ), "item*", - "object+", + "object", ObjectIntersectFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** * function that projects objects by filtering their pairs and leaves non-objects intact diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java index ced3eacea0..4f475ab0db 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectIntersectFunctionIterator.java @@ -21,23 +21,18 @@ package org.rumbledb.runtime.functions.object; import org.apache.spark.api.java.JavaRDD; -import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.function.Function2; import org.apache.spark.api.java.function.Function; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; -import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import sparksoniq.spark.SparkSessionManager; import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; From 33dd84474fc323d7beae636b8e3d91731117103a Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 23 Jun 2021 07:30:47 +0000 Subject: [PATCH 045/142] Revert "Remove DurationFunction" This reverts commit ec61adb3843511c03a29497c5f242a38da887237. --- .../context/BuiltinFunctionCatalogue.java | 50 ----------------- .../DayTimeDurationFunctionIterator.java | 53 ------------------- .../durations/DurationFunctionIterator.java | 53 ------------------- .../YearMonthDurationFunctionIterator.java | 53 ------------------- 4 files changed, 209 deletions(-) delete mode 100644 src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java delete mode 100644 src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java delete mode 100644 src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index e2f916ae8b..1ed0c73cc0 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -38,9 +38,6 @@ import org.rumbledb.runtime.functions.datetime.components.TimezoneFromTimeFunctionIterator; import org.rumbledb.runtime.functions.datetime.components.YearFromDateFunctionIterator; import org.rumbledb.runtime.functions.datetime.components.YearFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.durations.DayTimeDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.DurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.YearMonthDurationFunctionIterator; import org.rumbledb.runtime.functions.durations.components.DaysFromDurationFunctionIterator; import org.rumbledb.runtime.functions.durations.components.HoursFromDurationFunctionIterator; import org.rumbledb.runtime.functions.durations.components.MinutesFromDurationFunctionIterator; @@ -1611,50 +1608,6 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); - /** - * function that returns the duration item from the supplied string - */ - static final BuiltinFunction duration = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "duration" - ), - "string?", - "duration?", - DurationFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL - ); - /** - * function that returns the yearMonthDuration item from the supplied string - */ - static final BuiltinFunction yearMonthDuration = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "yearMonthDuration" - ), - "string?", - "yearMonthDuration?", - YearMonthDurationFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL - ); - /** - * function that returns the dayTimeDuration item from the supplied string - */ - static final BuiltinFunction dayTimeDuration = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "dayTimeDuration" - ), - "string?", - "dayTimeDuration?", - DayTimeDurationFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL - ); - - /** * function that returns the years from a duration */ @@ -2483,9 +2436,6 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(number.getIdentifier(), number); builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); - builtinFunctions.put(duration.getIdentifier(), duration); - builtinFunctions.put(dayTimeDuration.getIdentifier(), dayTimeDuration); - builtinFunctions.put(yearMonthDuration.getIdentifier(), yearMonthDuration); builtinFunctions.put(years_from_duration.getIdentifier(), years_from_duration); builtinFunctions.put(months_from_duration.getIdentifier(), months_from_duration); builtinFunctions.put(days_from_duration.getIdentifier(), days_from_duration); diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java deleted file mode 100644 index 739f004278..0000000000 --- a/src/main/java/org/rumbledb/runtime/functions/durations/DayTimeDurationFunctionIterator.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.rumbledb.runtime.functions.durations; - -import org.joda.time.Period; -import org.rumbledb.api.Item; -import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.DurationItem; -import org.rumbledb.items.ItemFactory; -import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; -import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; -import java.util.List; - -public class DayTimeDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { - - private static final long serialVersionUID = 1L; - private Item durationStringItem = null; - - public DayTimeDurationFunctionIterator( - List parameters, - ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata - ) { - super(parameters, executionMode, iteratorMetadata); - } - - @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(context); - if (this.durationStringItem == null) { - return null; - } - try { - Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.dayTimeDurationItem - ); - return ItemFactory.getInstance().createDayTimeDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "dayTimeDuration" - ); - throw new CastException(message, getMetadata()); - } - } - -} diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java deleted file mode 100644 index a652a2d424..0000000000 --- a/src/main/java/org/rumbledb/runtime/functions/durations/DurationFunctionIterator.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.rumbledb.runtime.functions.durations; - -import org.joda.time.Period; -import org.rumbledb.api.Item; -import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.DurationItem; -import org.rumbledb.items.ItemFactory; -import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; -import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; -import java.util.List; - -public class DurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { - - private static final long serialVersionUID = 1L; - private Item durationStringItem = null; - - public DurationFunctionIterator( - List arguments, - ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata - ) { - super(arguments, executionMode, iteratorMetadata); - } - - @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(context); - if (this.durationStringItem == null) { - return null; - } - try { - Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.durationItem - ); - return ItemFactory.getInstance().createDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "duration" - ); - throw new CastException(message, getMetadata()); - } - } - -} diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java deleted file mode 100644 index c2d72e7cf9..0000000000 --- a/src/main/java/org/rumbledb/runtime/functions/durations/YearMonthDurationFunctionIterator.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.rumbledb.runtime.functions.durations; - -import org.joda.time.Period; -import org.rumbledb.api.Item; -import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.DurationItem; -import org.rumbledb.items.ItemFactory; -import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; -import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; -import java.util.List; - -public class YearMonthDurationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { - - private static final long serialVersionUID = 1L; - private Item durationStringItem = null; - - public YearMonthDurationFunctionIterator( - List parameters, - ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata - ) { - super(parameters, executionMode, iteratorMetadata); - } - - @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - this.durationStringItem = this.children.get(0) - .materializeFirstItemOrNull(context); - if (this.durationStringItem == null) { - return null; - } - try { - Period period = DurationItem.getDurationFromString( - this.durationStringItem.getStringValue(), - BuiltinTypesCatalogue.yearMonthDurationItem - ); - return ItemFactory.getInstance().createYearMonthDurationItem(period); - } catch (UnsupportedOperationException | IllegalArgumentException e) { - String message = String.format( - "\"%s\": value of type %s is not castable to type %s", - this.durationStringItem.serialize(), - "string", - "yearMonthDuration" - ); - throw new CastException(message, getMetadata()); - } - } - -} From 265918ca171422a46c22a45f7e1735f4d76c04f7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 23 Jun 2021 10:07:27 +0000 Subject: [PATCH 046/142] Ceiling supports numeric only single quote test and fn-ceiling-double-5 not passing --- .../context/BuiltinFunctionCatalogue.java | 14 +++---- .../numerics/CeilingFunctionIterator.java | 37 +++++++++++++++---- .../numerics/FloorFunctionIterator.java | 36 +++++++++++++++--- .../numerics/RoundFunctionIterator.java | 14 +++++-- 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 1ed0c73cc0..785333da90 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -317,7 +317,7 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction position = createBuiltinFunction( new Name(Name.FN_NS, "fn", "position"), - "integer?", + "integer", PositionFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -326,7 +326,7 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction last = createBuiltinFunction( new Name(Name.FN_NS, "fn", "last"), - "integer?", + "integer", LastFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -879,8 +879,8 @@ private static BuiltinFunction createBuiltinFunction( "math", "ceiling" ), - "double?", - "double?", + "numeric?", + "numeric?", CeilingFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -893,8 +893,8 @@ private static BuiltinFunction createBuiltinFunction( "math", "floor" ), - "double?", - "double?", + "numeric?", + "numeric?", FloorFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -962,7 +962,7 @@ private static BuiltinFunction createBuiltinFunction( "math", "pi" ), - "double?", + "double", PiFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java index 7811c5ea12..58ec68618f 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java @@ -23,18 +23,20 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; public class CeilingFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator iterator; public CeilingFunctionIterator( List arguments, @@ -50,12 +52,33 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - return ItemFactory.getInstance() - .createDoubleItem( - Math.ceil( - value.castToDoubleValue() - ) - ); + if (value.isInt()) { + return ItemFactory.getInstance().createIntItem(value.getIntValue()); + } + if (value.isInteger()) { + return ItemFactory.getInstance().createIntegerItem(value.getIntegerValue()); + } + if (value.isDecimal()) { + BigDecimal bd = value.getDecimalValue().setScale(0, RoundingMode.CEILING); + return ItemFactory.getInstance().createDecimalItem(bd); + } + if (value.isFloat()) { + BigDecimal bd = new BigDecimal(value.getFloatValue()); + bd = bd.setScale(0, RoundingMode.CEILING); + return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + } + if (value.isDouble()) { + return ItemFactory.getInstance() + .createDoubleItem( + Math.ceil( + value.castToDoubleValue() + ) + ); + } + throw new UnexpectedTypeException( + "Unexpected value in ceiling(): " + value.getDynamicType(), + getMetadata() + ); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index 4ea1f013ab..44fcddacbb 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -23,6 +23,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -30,6 +31,8 @@ import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.types.BuiltinTypesCatalogue; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; public class FloorFunctionIterator extends AtMostOneItemLocalRuntimeIterator { @@ -51,12 +54,33 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - return ItemFactory.getInstance() - .createDoubleItem( - Math.floor( - value.castToDoubleValue() - ) - ); + if (value.isInt()) { + return ItemFactory.getInstance().createIntItem(value.getIntValue()); + } + if (value.isInteger()) { + return ItemFactory.getInstance().createIntegerItem(value.getIntegerValue()); + } + if (value.isDecimal()) { + BigDecimal bd = value.getDecimalValue().setScale(0, RoundingMode.FLOOR); + return ItemFactory.getInstance().createDecimalItem(bd); + } + if (value.isFloat()) { + BigDecimal bd = new BigDecimal(value.getFloatValue()); + bd = bd.setScale(0, RoundingMode.FLOOR); + return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + } + if (value.isDouble()) { + return ItemFactory.getInstance() + .createDoubleItem( + Math.floor( + value.castToDoubleValue() + ) + ); + } + throw new UnexpectedTypeException( + "Unexpected value in floor(): " + value.getDynamicType(), + getMetadata() + ); } @Override 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 861aaec7dd..78c60deb98 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java @@ -74,18 +74,24 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { precision = 0; } try { + if (value.isInt()) { + BigDecimal bd = new BigDecimal(value.getIntValue()).setScale(precision, RoundingMode.HALF_UP); + return ItemFactory.getInstance().createIntItem(bd.intValue()); + } + if (value.isInteger()) { + BigDecimal bd = new BigDecimal(value.getIntegerValue()).setScale(precision, RoundingMode.HALF_UP); + return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); + } if (value.isDecimal()) { BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_UP); return ItemFactory.getInstance().createDecimalItem(bd); } if (value.isDouble()) { - BigDecimal bd = new BigDecimal(value.getDoubleValue()); - bd = bd.setScale(precision, RoundingMode.HALF_UP); + BigDecimal bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_UP); return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); } if (value.isFloat()) { - BigDecimal bd = new BigDecimal(value.getFloatValue()); - bd = bd.setScale(precision, RoundingMode.HALF_UP); + BigDecimal bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_UP); return ItemFactory.getInstance().createFloatItem(bd.floatValue()); } throw new UnexpectedTypeException("Unexpected value in round(): " + value.getDynamicType(), getMetadata()); From 94063db76baeb456b6dbb805f506f1383f7354a9 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 24 Jun 2021 11:46:45 +0000 Subject: [PATCH 047/142] Add support for 0 parameter, in context --- .../context/BuiltinFunctionCatalogue.java | 45 ++++++++++++++++--- .../numerics/NumberFunctionIterator.java | 5 +++ .../NormalizeSpaceFunctionIterator.java | 6 +++ .../strings/StringLengthFunctionIterator.java | 5 +++ 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 785333da90..9f08b349b4 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1343,7 +1343,17 @@ private static BuiltinFunction createBuiltinFunction( /** * function that returns the string length */ - static final BuiltinFunction string_length = createBuiltinFunction( + static final BuiltinFunction string_length0 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "string-length" + ), + "integer", + StringLengthFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction string_length1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1567,7 +1577,17 @@ private static BuiltinFunction createBuiltinFunction( /** * function that normalizes spaces in a string */ - static final BuiltinFunction normalize_space = createBuiltinFunction( + static final BuiltinFunction normalize_space0 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "normalize-space" + ), + "string", + NormalizeSpaceFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction normalize_space1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -1596,7 +1616,17 @@ private static BuiltinFunction createBuiltinFunction( /** * function that that returns the double representation of the input string or number */ - static final BuiltinFunction number = createBuiltinFunction( + static final BuiltinFunction number0 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "number" + ), + "double", + NumberFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction number1 = createBuiltinFunction( new Name( Name.FN_NS, "fn", @@ -2417,7 +2447,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(ends_with2.getIdentifier(), ends_with2); builtinFunctions.put(string_join1.getIdentifier(), string_join1); builtinFunctions.put(string_join2.getIdentifier(), string_join2); - builtinFunctions.put(string_length.getIdentifier(), string_length); + builtinFunctions.put(string_length0.getIdentifier(), string_length0); + builtinFunctions.put(string_length1.getIdentifier(), string_length1); builtinFunctions.put(tokenize1.getIdentifier(), tokenize1); builtinFunctions.put(tokenize2.getIdentifier(), tokenize2); builtinFunctions.put(lower_case.getIdentifier(), lower_case); @@ -2429,11 +2460,13 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(matches1.getIdentifier(), matches1); builtinFunctions.put(contains1.getIdentifier(), contains1); builtinFunctions.put(contains2.getIdentifier(), contains2); - builtinFunctions.put(normalize_space.getIdentifier(), normalize_space); + builtinFunctions.put(normalize_space0.getIdentifier(), normalize_space0); + builtinFunctions.put(normalize_space1.getIdentifier(), normalize_space1); builtinFunctions.put(normalize_unicode1.getIdentifier(), normalize_unicode1); builtinFunctions.put(normalize_unicode2.getIdentifier(), normalize_unicode2); builtinFunctions.put(serialize.getIdentifier(), serialize); - builtinFunctions.put(number.getIdentifier(), number); + builtinFunctions.put(number0.getIdentifier(), number0); + builtinFunctions.put(number1.getIdentifier(), number1); builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); builtinFunctions.put(years_from_duration.getIdentifier(), years_from_duration); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java index d51b0637ec..3a17f005b2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/NumberFunctionIterator.java @@ -22,6 +22,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -45,6 +46,10 @@ public NumberFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 0) { + List items = context.getVariableValues().getLocalVariableValue(Name.CONTEXT_ITEM, getMetadata()); + return CastIterator.castItemToType(items.get(0), BuiltinTypesCatalogue.doubleItem, getMetadata()); + } Item anyItem = this.children.get(0).materializeFirstItemOrNull(context); if (anyItem == null) { diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java index 69819b1ecf..4426dff4c6 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/NormalizeSpaceFunctionIterator.java @@ -23,6 +23,7 @@ import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -45,6 +46,11 @@ public NormalizeSpaceFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 0) { + List items = context.getVariableValues().getLocalVariableValue(Name.CONTEXT_ITEM, getMetadata()); + return ItemFactory.getInstance() + .createStringItem(StringUtils.normalizeSpace(items.get(0).getStringValue())); + } Item stringItem = this.children.get(0) .materializeFirstItemOrNull(context); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java index 36023d8448..21f2a158a5 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringLengthFunctionIterator.java @@ -22,6 +22,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; @@ -44,6 +45,10 @@ public StringLengthFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 0) { + List items = context.getVariableValues().getLocalVariableValue(Name.CONTEXT_ITEM, getMetadata()); + return ItemFactory.getInstance().createIntItem(items.get(0).getStringValue().length()); + } Item stringItem = this.children.get(0) .materializeFirstItemOrNull(context); From 2e24d6c911bca1e6df2cb0e8dbaf9d97049a1c59 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 25 Jun 2021 09:15:45 +0000 Subject: [PATCH 048/142] Correct prefix from math: to fn: --- .../context/BuiltinFunctionCatalogue.java | 28 +++++++++---------- .../runtime/FunctionNumerics/FunctionAbs.jq | 2 +- .../FunctionNumerics/FunctionCeiling.jq | 2 +- .../runtime/FunctionNumerics/FunctionFloor.jq | 2 +- .../FunctionNumerics/FunctionRound1.jq | 2 +- .../FunctionRoundHalfToEven1.jq | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 9f08b349b4..d2b825030f 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -861,8 +861,8 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction abs = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "abs" ), "numeric?", @@ -875,8 +875,8 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction ceiling = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "ceiling" ), "numeric?", @@ -889,8 +889,8 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction floor = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "floor" ), "numeric?", @@ -904,8 +904,8 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction round1 = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "round" ), "numeric?", @@ -915,8 +915,8 @@ private static BuiltinFunction createBuiltinFunction( ); static final BuiltinFunction round2 = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "round" ), "numeric?", @@ -931,8 +931,8 @@ private static BuiltinFunction createBuiltinFunction( */ static final BuiltinFunction round_half_to_even1 = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "round-half-to-even" ), "double?", @@ -942,8 +942,8 @@ private static BuiltinFunction createBuiltinFunction( ); static final BuiltinFunction round_half_to_even2 = createBuiltinFunction( new Name( - Name.MATH_NS, - "math", + Name.FN_NS, + "fn", "round-half-to-even" ), "double?", diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionAbs.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionAbs.jq index 4a11f28d5e..3b63a58930 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionAbs.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionAbs.jq @@ -1,4 +1,4 @@ (:JIQS: ShouldRun; Output="(10.5, 10.5)" :) -math:abs(10.5), +fn:abs(10.5), abs(-10.5), abs(()) diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionCeiling.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionCeiling.jq index b2d144888c..ed6a857e33 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionCeiling.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionCeiling.jq @@ -1,4 +1,4 @@ (:JIQS: ShouldRun; Output="(11, -10)" :) -ceiling(10.5), +fn:ceiling(10.5), ceiling(-10.5), ceiling(()) diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionFloor.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionFloor.jq index 7148bb3827..03917dfc36 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionFloor.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionFloor.jq @@ -1,4 +1,4 @@ (:JIQS: ShouldRun; Output="(10, -11)" :) -floor(10.5), +fn:floor(10.5), floor(-10.5), floor(()) diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq index 48d736cae4..c9ee9082b7 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq @@ -1,5 +1,5 @@ (:JIQS: ShouldRun; Output="(3, 2, -3, 1.13, 8500, 3.14, NaN, INF, -INF, 0, -0)" :) -round(2.5), +fn:round(2.5), round(2.4999), round(-2.5), round(1.125, 2), diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRoundHalfToEven1.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRoundHalfToEven1.jq index 9419507dd1..b76ed4d0d0 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRoundHalfToEven1.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRoundHalfToEven1.jq @@ -1,5 +1,5 @@ (:JIQS: ShouldRun; Output="(0, 2, 2, 3567.81, 0, 35600)" :) -round-half-to-even(0.5), +fn:round-half-to-even(0.5), round-half-to-even(1.5), round-half-to-even(2.5), round-half-to-even(3.567812e+3, 2), From a7c1b341c6c69d0cbb69fab07230e79f1417b777 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 28 Jun 2021 13:02:17 +0000 Subject: [PATCH 049/142] Master into master pierre motard --- docs/RumbleML.md | 38 +- src/main/java/org/rumbledb/api/Item.java | 18 + .../compiler/ExecutionModeVisitor.java | 411 +++++++ .../rumbledb/compiler/InferTypeVisitor.java | 1061 +++++++++-------- .../compiler/StaticContextVisitor.java | 230 ++-- .../rumbledb/compiler/TranslationVisitor.java | 18 +- .../org/rumbledb/compiler/VisitorHelpers.java | 30 +- .../compiler/XQueryTranslationVisitor.java | 38 +- .../config/RumbleRuntimeConfiguration.java | 85 +- .../context/BuiltinFunctionCatalogue.java | 45 +- .../org/rumbledb/context/InScopeVariable.java | 4 + src/main/java/org/rumbledb/context/Name.java | 24 + .../org/rumbledb/context/NamedFunctions.java | 9 +- .../org/rumbledb/context/StaticContext.java | 59 +- .../exceptions/ExceptionMetadata.java | 5 +- .../InvalidRumbleMLParamException.java | 7 + .../rumbledb/exceptions/RumbleException.java | 4 + .../UnknownFunctionCallException.java | 14 + .../org/rumbledb/expressions/Expression.java | 35 +- .../java/org/rumbledb/expressions/Node.java | 16 + .../arithmetic/AdditiveExpression.java | 2 +- .../arithmetic/MultiplicativeExpression.java | 2 +- .../arithmetic/UnaryExpression.java | 2 +- .../comparison/ComparisonExpression.java | 2 +- .../expressions/flowr/FlworExpression.java | 6 - .../rumbledb/expressions/flowr/ForClause.java | 1 + .../flowr/GroupByVariableDeclaration.java | 2 +- .../rumbledb/expressions/flowr/LetClause.java | 11 +- .../expressions/flowr/ReturnClause.java | 19 - .../flowr/SimpleMapExpression.java | 2 +- .../module/VariableDeclaration.java | 8 +- .../DynamicFunctionCallExpression.java | 31 +- .../primary/BooleanLiteralExpression.java | 2 +- .../primary/DecimalLiteralExpression.java | 2 +- .../primary/DoubleLiteralExpression.java | 2 +- .../primary/FunctionCallExpression.java | 17 +- .../primary/InlineFunctionExpression.java | 20 +- .../primary/IntegerLiteralExpression.java | 2 +- .../NamedFunctionReferenceExpression.java | 2 +- .../primary/StringLiteralExpression.java | 2 +- .../primary/VariableReferenceExpression.java | 17 +- .../expressions/typing/CastExpression.java | 15 +- .../typing/CastableExpression.java | 9 +- .../typing/InstanceOfExpression.java | 9 +- .../typing/IsStaticallyExpression.java | 8 +- .../expressions/typing/TreatExpression.java | 9 +- .../typing/ValidateTypeExpression.java | 15 +- .../java/org/rumbledb/items/FunctionItem.java | 33 + .../flwor/clauses/LetClauseSparkIterator.java | 2 +- .../DynamicFunctionCallIterator.java | 87 +- .../functions/FunctionItemCallIterator.java | 4 +- .../org/rumbledb/types/ArrayItemType.java | 19 +- .../org/rumbledb/types/AtomicItemType.java | 9 +- .../rumbledb/types/BuiltinTypesCatalogue.java | 301 ++++- .../rumbledb/types/DerivedAtomicItemType.java | 4 +- .../org/rumbledb/types/FunctionItemType.java | 15 +- .../java/org/rumbledb/types/ItemItemType.java | 13 +- .../java/org/rumbledb/types/ItemType.java | 30 +- .../org/rumbledb/types/ItemTypeFactory.java | 13 +- .../org/rumbledb/types/ItemTypeReference.java | 24 + .../java/org/rumbledb/types/JsonItemType.java | 17 +- .../org/rumbledb/types/ObjectItemType.java | 17 +- .../java/org/rumbledb/types/SequenceType.java | 130 +- .../org/rumbledb/types/UnionItemType.java | 12 +- .../java/sparksoniq/spark/DataFrameUtils.java | 94 +- .../sparksoniq/spark/SparkSessionManager.java | 12 +- .../spark/ml/AnnotateFunctionIterator.java | 14 +- .../ml/ApplyEstimatorRuntimeIterator.java | 115 +- .../ml/ApplyTransformerRuntimeIterator.java | 90 +- .../ml/GetEstimatorFunctionIterator.java | 150 ++- .../ml/GetTransformerFunctionIterator.java | 160 +-- .../sparksoniq/spark/ml/RumbleMLCatalog.java | 7 +- .../sparksoniq/spark/ml/RumbleMLUtils.java | 17 +- .../java/iq/base/AnnotationsTestsBase.java | 3 +- .../runtime-native-flwor/udt/type4.jq | 7 + .../runtime-native-flwor/udt/typeError11.jq | 2 +- .../runtime-native-flwor/udt/typeError12.jq | 2 +- .../MLAnnotateDF-SchemaError1.jq | 2 +- .../MLAnnotateDF-SchemaError3.jq | 2 +- .../MLAnnotateDF-SchemaError4.jq | 2 +- .../AnnotateFunction/MLAnnotateDF2.jq | 2 +- .../MLAnnotateForChaining1.jq | 4 +- .../MLAnnotateForChaining2.jq | 4 +- .../MLAnnotateForChaining4.jq | 10 +- .../MLAnnotateForEstimator1.jq | 8 +- .../MLAnnotateLocal-SchemaError3.jq | 2 +- .../MLAnnotateRDD-SchemaError3.jq | 2 +- .../MLEstimator-AFTSurvivalRegression.jq | 6 +- .../MLEstimator-BisectingKMeans.jq | 6 +- ...MLEstimator-BucketedRandomProjectionLSH.jq | 6 +- .../MLEstimator-ChiSqSelector.jq | 6 +- .../MLEstimator-DecisionTreeClassifier.jq | 6 +- .../MLEstimator-DecisionTreeRegressor.jq | 6 +- .../MLEstimator-GBTClassifier.jq | 6 +- .../MLEstimator-GBTRegressor.jq | 6 +- .../MLEstimator-GaussianMixture.jq | 6 +- ...MLEstimator-GeneralizedLinearRegression.jq | 6 +- .../EstimatorTests/MLEstimator-IDF.jq | 6 +- .../MLEstimator-IsotonicRegression.jq | 6 +- .../EstimatorTests/MLEstimator-KMeans1.jq | 6 +- .../EstimatorTests/MLEstimator-LDA.jq | 6 +- .../MLEstimator-LinearRegression.jq | 6 +- .../EstimatorTests/MLEstimator-LinearSVC.jq | 6 +- .../MLEstimator-LogisticRegression1.jq | 6 +- .../MLEstimator-MaxAbsScaler.jq | 6 +- .../EstimatorTests/MLEstimator-MinHashLSH.jq | 6 +- .../MLEstimator-MinMaxScaler.jq | 6 +- ...timator-MultilayerPerceptronClassifier2.jq | 6 +- .../EstimatorTests/MLEstimator-NaiveBayes.jq | 6 +- .../EstimatorTests/MLEstimator-PCA.jq | 6 +- .../MLEstimator-RandomForestClassifier.jq | 6 +- .../MLEstimator-RandomForestRegressor.jq | 6 +- .../MLEstimator-StandardScaler.jq | 6 +- .../MLEstimator-VectorIndexer.jq | 6 +- .../MLFeatureVectorization-Error1.jq | 6 +- .../MLFeatureVectorization1.jq | 4 +- .../runtime-spark/RumbleML/MLPipeline1.jq | 29 + .../runtime-spark/RumbleML/MLPipeline2.jq | 29 + .../runtime-spark/RumbleML/MLPipeline3.jq | 36 + .../runtime-spark/RumbleML/MLPipeline4.jq | 29 + .../runtime-spark/RumbleML/MLPipeline5.jq | 23 + .../runtime-spark/RumbleML/MLPipeline6.jq | 24 + ...ansformer-DiscreteCosineTransform(DCT)1.jq | 4 +- .../MLTransformer-Normalizer1.jq | 4 +- .../MLTransformer-PolynomialExpansion1.jq | 4 +- .../MLTransformer-Tokenizer2.jq | 20 + .../MLTransformer-VectorSizeHint1.jq | 4 +- .../MLTransformer-VectorSlicer1.jq | 4 +- .../static-typing/postfix/dynamicfunc1.jq | 2 +- .../static-typing/postfix/dynamicfunc3.jq | 2 +- 130 files changed, 3029 insertions(+), 1168 deletions(-) create mode 100644 src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java create mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/type4.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Tokenizer2.jq diff --git a/docs/RumbleML.md b/docs/RumbleML.md index 7a44291ebb..f6abb9b09e 100644 --- a/docs/RumbleML.md +++ b/docs/RumbleML.md @@ -3,7 +3,7 @@ RumbleML is a Machine Learning library built on top of the Rumble engine that ma The machine learning capabilities are exposed through JSONiq function items. The concepts of "estimator" and "transformer", which are core to Machine Learning, are naturally function items and fit seamlessly in the JSONiq data model. -Training sets, test sets, and validation sets, which containing features and labels, are exposed through JSONiq sequences of object items: the keys of these objects are the features and labels. +Training sets, test sets, and validation sets, which contain features and labels, are exposed through JSONiq sequences of object items: the keys of these objects are the features and labels. The names of the estimators and of the transformers, as well as the functionality they encapsulate, are directly inherited from the [SparkML](https://spark.apache.org/docs/latest/ml-guide.html) library which RumbleML is based on: we chose not to reinvent the wheel. @@ -19,7 +19,7 @@ It is an abstraction that either performs a feature transformation or generates ## Estimators -An **estimator** is a function item that maps a sequence of objects to a transformer (yes, you got it right: that's a function item. This is why they are also called higher-order functions!). +An **estimator** is a function item that maps a sequence of objects to a transformer (yes, you got it right: that's a function item returned by a function item. This is why they are also called higher-order functions!). Estimators abstract the concept of a Machine Learning algorithm or any algorithm that fits or trains on data. For example, a learning algorithm such as _KMeans_ is implemented as an Estimator. Calling this estimator on data essentially trains a KMeansModel, which is a Model and hence a Transformer. @@ -29,19 +29,30 @@ Transformers and estimators are function items in the Rumble Data Model. Their f ## Type Annotations -RumbleML works on highly structured data, because it requires full type information for all the fields in the training set or test set. While it is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly, Rumble does not support a full object type system yet. Thus, the annotate() function has been introduced as a temporary remedy which facilitates the manual annotation of data against a schema for structured data. This annotation operation is required to be applied on any dataset that must be used as input to RumbleML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. +RumbleML works on highly structured data, because it requires full type information for all the fields in the training set or test set. It is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly. + +Rumble supports a user-defined type system with which you can validate and annotate datasets against a JSound schema. + +This annotation is required to be applied on any dataset that must be used as input to RumbleML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. ## Examples - Tokenizer Example: ``` + +declare type local:id-and-sentence as { + "id": "integer", + "sentence": "string" +}; + + let $local-data := ( {"id": 1, "sentence": "Hi I heard about Spark"}, {"id": 2, "sentence": "I wish Java could use case classes"}, {"id": 3, "sentence": "Logistic regression models are neat"} ) -let $df-data := annotate($local-data, {"id": "integer", "sentence": "string"}) +let $df-data := validate type local:id-and-sentence* { $local-data } let $transformer := get-transformer("Tokenizer") for $i in $transformer( @@ -58,6 +69,18 @@ return $i - KMeans Example: ``` +declare type local:col-1-2-3 as { + "id": "integer", + "col1": "decimal", + "col2": "decimal", + "col3": "decimal" +}; + +let $vector-assembler := get-transformer("VectorAssembler")( + ?, + { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" } +) + let $local-data := ( {"id": 0, "col1": 0.0, "col2": 0.0, "col3": 0.0}, {"id": 1, "col1": 0.1, "col2": 0.1, "col3": 0.1}, @@ -66,17 +89,18 @@ let $local-data := ( {"id": 4, "col1": 9.1, "col2": 9.1, "col3": 9.1}, {"id": 5, "col1": 9.2, "col2": 9.2, "col3": 9.2} ) -let $df-data := annotate($local-data, {"id": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $df-data := validate type local:col-1-2-3* {$local-data } +let $df-data := $vector-assembler($df-data) let $est := get-estimator("KMeans") let $tra := $est( $df-data, - {"featuresCol": ["col1", "col2", "col3"]} + {"featuresCol": "features"} ) for $i in $tra( $df-data, - {"featuresCol": ["col1", "col2", "col3"]} + {"featuresCol": "features"} ) return $i diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 01d5f3f270..2169d3b562 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -7,6 +7,8 @@ import java.util.Map; import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.ml.Estimator; +import org.apache.spark.ml.Transformer; import org.joda.time.DateTime; import org.joda.time.Period; import org.rumbledb.context.DynamicContext; @@ -599,4 +601,20 @@ default int castToIntValue() { default NativeClauseContext generateNativeQuery(NativeClauseContext context) { return NativeClauseContext.NoNativeQuery; } + + default boolean isEstimator() { + return false; + } + + default Estimator getEstimator() { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + + default boolean isTransformer() { + return false; + } + + default Transformer getTransformer() { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } } diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java new file mode 100644 index 0000000000..e85c34979c --- /dev/null +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -0,0 +1,411 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.compiler; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.rumbledb.context.BuiltinFunctionCatalogue; +import org.rumbledb.context.FunctionIdentifier; +import org.rumbledb.context.InScopeVariable; +import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; +import org.rumbledb.expressions.control.TypeSwitchExpression; +import org.rumbledb.expressions.control.TypeswitchCase; +import org.rumbledb.expressions.flowr.Clause; +import org.rumbledb.expressions.flowr.CountClause; +import org.rumbledb.expressions.flowr.FlworExpression; +import org.rumbledb.expressions.flowr.GroupByVariableDeclaration; +import org.rumbledb.expressions.flowr.ForClause; +import org.rumbledb.expressions.flowr.GroupByClause; +import org.rumbledb.expressions.flowr.LetClause; +import org.rumbledb.expressions.flowr.ReturnClause; +import org.rumbledb.expressions.module.FunctionDeclaration; +import org.rumbledb.expressions.module.LibraryModule; +import org.rumbledb.expressions.module.MainModule; +import org.rumbledb.expressions.module.Prolog; +import org.rumbledb.expressions.module.VariableDeclaration; +import org.rumbledb.expressions.primary.FunctionCallExpression; +import org.rumbledb.expressions.primary.InlineFunctionExpression; +import org.rumbledb.expressions.primary.VariableReferenceExpression; +import org.rumbledb.types.SequenceType; +import org.rumbledb.types.SequenceType.Arity; + +/** + * Static context visitor implements a multi-pass algorithm that enables function hoisting + */ +public class ExecutionModeVisitor extends AbstractNodeVisitor { + + private VisitorConfig visitorConfig; + + ExecutionModeVisitor() { + this.visitorConfig = VisitorConfig.staticContextVisitorInitialPassConfig; + } + + void setVisitorConfig(VisitorConfig visitorConfig) { + this.visitorConfig = visitorConfig; + } + + @Override + protected StaticContext defaultAction(Node node, StaticContext argument) { + visitDescendants(node, argument); + node.initHighestExecutionMode(this.visitorConfig); + return argument; + } + + @Override + public StaticContext visitMainModule(MainModule mainModule, StaticContext argument) { + visitDescendants(mainModule, mainModule.getStaticContext()); + mainModule.initHighestExecutionMode(this.visitorConfig); + return argument; + } + + @Override + public StaticContext visitLibraryModule(LibraryModule libraryModule, StaticContext argument) { + if (libraryModule.getProlog() != null) { + libraryModule.getProlog().initHighestExecutionMode(this.visitorConfig); + this.visit(libraryModule.getProlog(), libraryModule.getStaticContext()); + } + libraryModule.initHighestExecutionMode(this.visitorConfig); + return argument; + } + + // region primary + @Override + public StaticContext visitVariableReference(VariableReferenceExpression expression, StaticContext argument) { + if (expression.alwaysReturnsAtMostOneItem()) { + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + return argument; + } + Name variableName = expression.getVariableName(); + ExecutionMode mode = expression.getStaticContext().getVariableStorageMode(variableName); + if (this.visitorConfig.setUnsetToLocal() && mode.equals(ExecutionMode.UNSET)) { + if ( + expression.getStaticSequenceType().getArity().equals(Arity.OneOrMore) + || + expression.getStaticSequenceType().getArity().equals(Arity.ZeroOrMore) + ) { + if (expression.getStaticSequenceType().getItemType().isObjectItemType()) { + System.err.println( + "[WARNING] Forcing execution mode of variable " + + expression.getVariableName() + + " to DataFrame based on static object* type." + ); + expression.setHighestExecutionMode(ExecutionMode.DATAFRAME); + return argument; + } + } + System.err.println( + "[WARNING] Forcing execution mode of variable " + expression.getVariableName() + " to local." + ); + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + return argument; + } + expression.setHighestExecutionMode(mode); + return argument; + } + + private void populateFunctionDeclarationStaticContext( + StaticContext functionDeclarationContext, + List modes, + InlineFunctionExpression expression + ) { + int i = 0; + for (Name name : expression.getParams().keySet()) { + ExecutionMode mode = modes.get(i); + SequenceType type = expression.getParams().get(name); + if (type.isEmptySequence()) { + mode = ExecutionMode.LOCAL; + } else if (type.getArity().equals(Arity.OneOrZero) || type.getArity().equals(Arity.One)) { + mode = ExecutionMode.LOCAL; + } + functionDeclarationContext.setVariableStorageMode( + name, + mode + ); + ++i; + } + } + + @Override + public StaticContext visitFunctionDeclaration(FunctionDeclaration declaration, StaticContext argument) { + InlineFunctionExpression expression = (InlineFunctionExpression) declaration.getExpression(); + // define a static context for the function body, add params to the context and visit the body expression + List modes = expression.getStaticContext() + .getUserDefinedFunctionsExecutionModes() + .getParameterExecutionMode( + expression.getFunctionIdentifier(), + expression.getMetadata() + ); + populateFunctionDeclarationStaticContext(expression.getStaticContext(), modes, expression); + // visit the body first to make its execution mode available while adding the function to the catalog + this.visit(expression.getBody(), expression.getStaticContext()); + expression.initHighestExecutionMode(this.visitorConfig); + declaration.initHighestExecutionMode(this.visitorConfig); + expression.registerUserDefinedFunctionExecutionMode( + this.visitorConfig + ); + return argument; + } + + @Override + public StaticContext visitInlineFunctionExpr(InlineFunctionExpression expression, StaticContext argument) { + // define a static context for the function body, add params to the context and visit the body expression + expression.getParams() + .forEach( + (paramName, sequenceType) -> expression.getBody() + .getStaticContext() + .setVariableStorageMode( + paramName, + ExecutionMode.LOCAL + ) + ); + // visit the body first to make its execution mode available while adding the function to the catalog + this.visit(expression.getBody(), expression.getBody().getStaticContext()); + expression.initHighestExecutionMode(this.visitorConfig); + expression.registerUserDefinedFunctionExecutionMode( + this.visitorConfig + ); + return argument; + } + + @Override + public StaticContext visitFunctionCall(FunctionCallExpression expression, StaticContext argument) { + visitDescendants(expression, expression.getStaticContext()); + FunctionIdentifier identifier = expression.getFunctionIdentifier(); + if (!BuiltinFunctionCatalogue.exists(identifier)) { + List modes = new ArrayList<>(); + for (Expression parameter : expression.getArguments()) { + if (parameter == null) { + // This is for a partial application, for ? arguments. + // We do not modify the current mode for this parameter. + modes.add(ExecutionMode.UNSET); + } else { + modes.add(parameter.getHighestExecutionMode(this.visitorConfig)); + } + } + expression.getStaticContext() + .getUserDefinedFunctionsExecutionModes() + .setParameterExecutionMode( + identifier, + modes, + expression.getMetadata() + ); + } + expression.initFunctionCallHighestExecutionMode(this.visitorConfig); + return argument; + } + // endregion + + @Override + public StaticContext visitReturnClause(ReturnClause expression, StaticContext argument) { + System.err.println(expression.getStaticContext()); + visitDescendants(expression, expression.getStaticContext()); + if (expression.getPreviousClause().getHighestExecutionMode(this.visitorConfig).isDataFrame()) { + expression.setHighestExecutionMode(ExecutionMode.RDD); + return argument; + } + if (expression.getReturnExpr().getHighestExecutionMode(this.visitorConfig).isRDD()) { + expression.setHighestExecutionMode(ExecutionMode.RDD); + return argument; + } + if (expression.getReturnExpr().getHighestExecutionMode(this.visitorConfig).isDataFrame()) { + expression.setHighestExecutionMode(ExecutionMode.DATAFRAME); + return argument; + } + if (expression.getReturnExpr().getHighestExecutionMode(this.visitorConfig).isUnset()) { + expression.setHighestExecutionMode(ExecutionMode.UNSET); + return argument; + } + if (expression.getPreviousClause().getHighestExecutionMode(this.visitorConfig).isUnset()) { + expression.setHighestExecutionMode(ExecutionMode.UNSET); + return argument; + } + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + return argument; + } + + // region FLWOR + @Override + public StaticContext visitFlowrExpression(FlworExpression expression, StaticContext argument) { + Clause clause = expression.getReturnClause().getFirstClause(); + while (clause != null) { + if (clause.getNextClause() != null) { + this.visit(clause, clause.getNextClause().getStaticContext()); + } else { + this.visit(clause, null); + } + clause = clause.getNextClause(); + } + if (expression.alwaysReturnsAtMostOneItem()) { + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + } else { + expression.setHighestExecutionMode( + expression.getReturnClause().getHighestExecutionMode(this.visitorConfig) + ); + } + return argument; + } + + // region FLWOR vars + @Override + public StaticContext visitForClause(ForClause clause, StaticContext argument) { + this.visit(clause.getExpression(), clause.getExpression().getStaticContext()); + clause.initHighestExecutionMode(this.visitorConfig); + + argument.setVariableStorageMode( + clause.getVariableName(), + clause.getVariableHighestStorageMode(this.visitorConfig) + ); + + if (clause.getPositionalVariableName() != null) { + argument.setVariableStorageMode( + clause.getPositionalVariableName(), + ExecutionMode.LOCAL + ); + } + return argument; + } + + @Override + public StaticContext visitLetClause(LetClause clause, StaticContext argument) { + this.visit(clause.getExpression(), clause.getExpression().getStaticContext()); + clause.initHighestExecutionMode(this.visitorConfig); + + argument.setVariableStorageMode( + clause.getVariableName(), + clause.getVariableHighestStorageMode(this.visitorConfig) + ); + + return argument; + } + + @Override + public StaticContext visitGroupByClause(GroupByClause clause, StaticContext argument) { + for (GroupByVariableDeclaration variable : clause.getGroupVariables()) { + if (variable.getExpression() != null) { + // if a variable declaration takes place + this.visit(variable.getExpression(), null); + argument.setVariableStorageMode( + variable.getVariableName(), + ExecutionMode.LOCAL + ); + } + } + clause.initHighestExecutionMode(this.visitorConfig); + StaticContext clauseContext = clause.getStaticContext(); + for (Entry entry : argument.getInScopeVariables().entrySet()) { + boolean isKeyVariable = false; + for (GroupByVariableDeclaration variable : clause.getGroupVariables()) { + if (variable.getExpression() != null) { + if (entry.getKey().equals(variable.getVariableName())) { + isKeyVariable = true; + } + } + } + if (isKeyVariable) { + continue; + } + argument.setVariableStorageMode( + entry.getKey(), + clauseContext.getVariableStorageMode(entry.getKey()) + ); + } + return argument; + } + + @Override + public StaticContext visitCountClause(CountClause expression, StaticContext argument) { + expression.initHighestExecutionMode(this.visitorConfig); + argument.setVariableStorageMode( + expression.getCountVariable().getVariableName(), + ExecutionMode.LOCAL + ); + this.visit(expression.getCountVariable(), expression.getCountVariable().getStaticContext()); + return argument; + } + + // endregion + + // region control + @Override + public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, StaticContext argument) { + this.visit(expression.getTestCondition(), null); + for (TypeswitchCase c : expression.getCases()) { + Name variableName = c.getVariableName(); + if (variableName != null) { + c.getReturnExpression() + .getStaticContext() + .setVariableStorageMode( + variableName, + ExecutionMode.LOCAL + ); + } + this.visit(c.getReturnExpression(), c.getReturnExpression().getStaticContext()); + } + + Name defaultCaseVariableName = expression.getDefaultCase().getVariableName(); + if (defaultCaseVariableName == null) { + this.visit(expression.getDefaultCase().getReturnExpression(), null); + } else { + // add variable to child context to visit default return expression + expression.getDefaultCase() + .getReturnExpression() + .getStaticContext() + .setVariableStorageMode( + defaultCaseVariableName, + ExecutionMode.LOCAL + ); + this.visit(expression.getDefaultCase().getReturnExpression(), null); + } + expression.initHighestExecutionMode(this.visitorConfig); + // return the given context unchanged as defined variables go out of scope + return argument; + } + // endregion + + @Override + public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclaration, StaticContext argument) { + if (variableDeclaration.getExpression() != null) { + this.visit(variableDeclaration.getExpression(), null); + } + variableDeclaration.initHighestExecutionMode(this.visitorConfig); + // first pass. + argument.setVariableStorageMode( + variableDeclaration.getVariableName(), + variableDeclaration.getVariableHighestStorageMode(this.visitorConfig) + ); + return argument; + } + + @Override + public StaticContext visitProlog(Prolog prolog, StaticContext argument) { + visitDescendants(prolog, argument); + prolog.initHighestExecutionMode(this.visitorConfig); + return argument; + } + +} diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index 08c165e191..9fb3b23218 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import org.apache.spark.sql.AnalysisException; import org.apache.spark.sql.types.StructType; @@ -23,6 +22,7 @@ import org.rumbledb.exceptions.IsStaticallyUnexpectedTypeException; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.UnexpectedStaticTypeException; +import org.rumbledb.exceptions.UnknownFunctionCallException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.CommaExpression; import org.rumbledb.expressions.Expression; @@ -54,6 +54,9 @@ import org.rumbledb.expressions.miscellaneous.RangeExpression; import org.rumbledb.expressions.miscellaneous.StringConcatExpression; import org.rumbledb.expressions.module.FunctionDeclaration; +import org.rumbledb.expressions.module.LibraryModule; +import org.rumbledb.expressions.module.MainModule; +import org.rumbledb.expressions.module.Prolog; import org.rumbledb.expressions.module.VariableDeclaration; import org.rumbledb.expressions.postfix.ArrayLookupExpression; import org.rumbledb.expressions.postfix.ArrayUnboxingExpression; @@ -78,6 +81,7 @@ import org.rumbledb.expressions.typing.InstanceOfExpression; import org.rumbledb.expressions.typing.IsStaticallyExpression; import org.rumbledb.expressions.typing.TreatExpression; +import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.runtime.functions.input.FileSystemUtil; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FieldDescriptor; @@ -105,6 +109,34 @@ public class InferTypeVisitor extends AbstractNodeVisitor { this.rumbleRuntimeConfiguration = rumbleRuntimeConfiguration; } + private void throwStaticTypeException(String message, ErrorCode code) { + if (this.rumbleRuntimeConfiguration.doStaticAnalysis()) { + throw new UnexpectedStaticTypeException( + message, + code + ); + } + } + + private void throwStaticTypeException(String message, ExceptionMetadata metadata) { + if (this.rumbleRuntimeConfiguration.doStaticAnalysis()) { + throw new UnexpectedStaticTypeException( + message, + metadata + ); + } + } + + private void throwStaticTypeException(String message, ErrorCode code, ExceptionMetadata metadata) { + if (this.rumbleRuntimeConfiguration.doStaticAnalysis()) { + throw new UnexpectedStaticTypeException( + message, + code, + metadata + ); + } + } + /** * Perform basic checks on a list of SequenceType, available checks are for null (OurBad exception) and inferred the * empty sequence (XPST0005) @@ -131,11 +163,11 @@ private void basicChecks( if (inferredEmptyCheck) { for (SequenceType type : types) { if (type.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type for " - + nodeName - + " is empty sequence (with active static typing feature, only allowed for CommaExpression)", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression + throwStaticTypeException( + "Inferred type for " + + nodeName + + " is empty sequence (with active static typing feature, only allowed for CommaExpression)", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression ); } } @@ -164,12 +196,12 @@ private void basicChecks( } } if (inferredEmptyCheck) { - if (type.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type for " - + nodeName - + " is empty sequence (with active static typing feature, only allowed for CommaExpression)", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression + if (type != null && type.isEmptySequence()) { + throwStaticTypeException( + "Inferred type for " + + nodeName + + " is empty sequence (with active static typing feature, only allowed for CommaExpression)", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression ); } } @@ -182,13 +214,13 @@ public StaticContext visitCommaExpression(CommaExpression expression, StaticCont SequenceType inferredType = SequenceType.EMPTY_SEQUENCE; for (Expression childExpression : expression.getExpressions()) { - SequenceType childExpressionInferredType = childExpression.getInferredSequenceType(); + SequenceType childExpressionInferredType = childExpression.getStaticSequenceType(); // if a child expression has no inferred type throw an error if (childExpressionInferredType == null) { - throw new UnexpectedStaticTypeException( - "A child expression of a CommaExpression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "A child expression of a CommaExpression has no inferred type", + expression.getMetadata() ); } @@ -212,8 +244,7 @@ public StaticContext visitCommaExpression(CommaExpression expression, StaticCont } } - System.out.println("visited comma expression with inferred type: " + inferredType); - expression.setInferredSequenceType(inferredType); + expression.setStaticSequenceType(inferredType); return argument; } @@ -221,43 +252,37 @@ public StaticContext visitCommaExpression(CommaExpression expression, StaticCont @Override public StaticContext visitString(StringLiteralExpression expression, StaticContext argument) { - System.out.println("visiting String literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.stringItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.stringItem)); return argument; } @Override public StaticContext visitInteger(IntegerLiteralExpression expression, StaticContext argument) { - System.out.println("visiting Int literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.integerItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.integerItem)); return argument; } @Override public StaticContext visitDouble(DoubleLiteralExpression expression, StaticContext argument) { - System.out.println("visiting Double literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.doubleItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.doubleItem)); return argument; } @Override public StaticContext visitDecimal(DecimalLiteralExpression expression, StaticContext argument) { - System.out.println("visiting Decimal literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.decimalItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.decimalItem)); return argument; } @Override public StaticContext visitNull(NullLiteralExpression expression, StaticContext argument) { - System.out.println("visiting Null literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.nullItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.nullItem)); return argument; } @Override public StaticContext visitBoolean(BooleanLiteralExpression expression, StaticContext argument) { - System.out.println("visiting Boolean literal"); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); return argument; } @@ -266,66 +291,68 @@ public StaticContext visitVariableReference(VariableReferenceExpression expressi SequenceType variableType = expression.getActualType(); if (variableType == null) { // if is null, no 'as [SequenceType]' part was present in the declaration, therefore we infer it - System.out.println("variable reference type was null so we infer it"); variableType = expression.getStaticContext().getVariableSequenceType(expression.getVariableName()); // we also set variableReference type - expression.setType(variableType); + if (variableType == null) { + System.err.println( + "pWARNING] Variable reference type was null so we infer it. Please let us know as we would like to look into it." + ); + variableType = SequenceType.ITEM_STAR; + } + expression.setActualType(variableType); } basicChecks(variableType, expression.getClass().getSimpleName(), false, true, expression.getMetadata()); - System.out.println("visiting variable reference with type: " + variableType); - expression.setInferredSequenceType(variableType); + expression.setStaticSequenceType(variableType); return argument; } @Override public StaticContext visitArrayConstructor(ArrayConstructorExpression expression, StaticContext argument) { - System.out.println("visiting Array constructor literal"); visitDescendants(expression, argument); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.arrayItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.arrayItem)); return argument; } @Override public StaticContext visitObjectConstructor(ObjectConstructorExpression expression, StaticContext argument) { - System.out.println("visiting Object constructor literal"); visitDescendants(expression, argument); if (expression.isMergedConstructor()) { // if it is a merged constructor the child must be a subtype of object* inferred type - SequenceType childSequenceType = ((Expression) expression.getChildren().get(0)).getInferredSequenceType(); + SequenceType childSequenceType = ((Expression) expression.getChildren().get(0)).getStaticSequenceType(); if (childSequenceType == null) { - throw new UnexpectedStaticTypeException( - "The child expression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "The child expression has no inferred type", + expression.getMetadata() ); } if (!childSequenceType.isSubtypeOf(SequenceType.createSequenceType("object*"))) { - throw new UnexpectedStaticTypeException( - "The child expression must have object* sequence type, instead found: " + childSequenceType, - expression.getMetadata() + throwStaticTypeException( + "The child expression must have object* sequence type, instead found: " + childSequenceType, + expression.getMetadata() ); } } else { for (Expression keyExpression : expression.getKeys()) { - SequenceType keySequenceType = keyExpression.getInferredSequenceType(); + SequenceType keySequenceType = keyExpression.getStaticSequenceType(); if (keySequenceType == null) { - throw new UnexpectedStaticTypeException( - "One of the key in the object constructor has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "One of the key in the object constructor has no inferred type", + expression.getMetadata() ); } if ( !keySequenceType.isSubtypeOf(SequenceType.createSequenceType("string")) && !keySequenceType.isSubtypeOf(SequenceType.createSequenceType("anyURI")) ) { - throw new UnexpectedStaticTypeException( - "The inferred static sequence types for the keys of an Object must be a subtype of string or anyURI, instead found a: " - + keySequenceType, - expression.getMetadata() + throwStaticTypeException( + "The inferred static sequence types for the keys of an Object must be a subtype of string or anyURI, instead found a: " + + keySequenceType, + expression.getMetadata() ); } } } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.objectItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.objectItem)); return argument; } @@ -335,8 +362,7 @@ public StaticContext visitContextExpr(ContextItemExpression expression, StaticCo if (contextType == null) { contextType = new SequenceType(BuiltinTypesCatalogue.item); } - expression.setInferredSequenceType(contextType); - System.out.println("Visited context expression, set type: " + contextType); + expression.setStaticSequenceType(contextType); return argument; } @@ -345,28 +371,23 @@ public StaticContext visitInlineFunctionExpr(InlineFunctionExpression expression visitDescendants(expression, argument); SequenceType returnType = expression.getActualReturnType(); if (returnType == null) { - returnType = expression.getBody().getInferredSequenceType(); + returnType = expression.getBody().getStaticSequenceType(); } List params = new ArrayList<>(expression.getParams().values()); FunctionSignature signature = new FunctionSignature(params, returnType); - expression.setInferredSequenceType(new SequenceType(ItemTypeFactory.createFunctionItemType(signature))); - System.out.println("Visited inline function expression"); + expression.setStaticSequenceType(new SequenceType(ItemTypeFactory.createFunctionItemType(signature))); return argument; } private FunctionSignature getSignature(FunctionIdentifier identifier, StaticContext staticContext) { BuiltinFunction function = null; FunctionSignature signature = null; - try { - function = BuiltinFunctionCatalogue.getBuiltinFunction(identifier); - } catch (OurBadException exception) { - signature = staticContext.getFunctionSignature(identifier); - } - + function = BuiltinFunctionCatalogue.getBuiltinFunction(identifier); if (function != null) { signature = function.getSignature(); + } else { + signature = staticContext.getFunctionSignature(identifier); } - return signature; } @@ -374,10 +395,16 @@ private FunctionSignature getSignature(FunctionIdentifier identifier, StaticCont public StaticContext visitNamedFunctionRef(NamedFunctionReferenceExpression expression, StaticContext argument) { visitDescendants(expression, argument); - FunctionSignature signature = getSignature(expression.getIdentifier(), expression.getStaticContext()); - - expression.setInferredSequenceType(new SequenceType(ItemTypeFactory.createFunctionItemType(signature))); - System.out.println("Visited named function expression"); + try { + FunctionSignature signature = getSignature(expression.getIdentifier(), expression.getStaticContext()); + expression.setStaticSequenceType(new SequenceType(ItemTypeFactory.createFunctionItemType(signature))); + } catch (UnknownFunctionCallException e) { + throw new UnknownFunctionCallException( + expression.getIdentifier().getName(), + expression.getIdentifier().getArity(), + expression.getMetadata() + ); + } return argument; } @@ -409,9 +436,8 @@ private boolean tryAnnotateSpecificFunctions(FunctionCallExpression expression, .parquet(uri.toString()) .schema(); ItemType schemaItemType = ItemTypeFactory.createItemType(s); - System.out.println(schemaItemType.toString()); // TODO : check if arity is correct - expression.setInferredSequenceType(new SequenceType(schemaItemType, SequenceType.Arity.ZeroOrMore)); + expression.setStaticSequenceType(new SequenceType(schemaItemType, SequenceType.Arity.ZeroOrMore)); return true; } catch (Exception e) { if (e instanceof AnalysisException) { @@ -424,7 +450,7 @@ private boolean tryAnnotateSpecificFunctions(FunctionCallExpression expression, // handle 'round' function if (functionName.equals(Name.createVariableInDefaultFunctionNamespace("round"))) { // set output type to the same of the first argument (special handling of numeric) - expression.setInferredSequenceType(args.get(0).getInferredSequenceType()); + expression.setStaticSequenceType(args.get(0).getStaticSequenceType()); return true; } @@ -434,9 +460,12 @@ private boolean tryAnnotateSpecificFunctions(FunctionCallExpression expression, @Override public StaticContext visitFunctionCall(FunctionCallExpression expression, StaticContext argument) { visitDescendants(expression, argument); - - FunctionSignature signature = getSignature(expression.getFunctionIdentifier(), expression.getStaticContext()); - + FunctionSignature signature = null; + try { + signature = getSignature(expression.getFunctionIdentifier(), expression.getStaticContext()); + } catch (UnknownFunctionCallException e) { + throw new UnknownFunctionCallException(expression.getFunctionIdentifier(), expression.getMetadata()); + } List parameterExpressions = expression.getArguments(); List parameterTypes = signature.getParameterTypes(); List partialParams = new ArrayList<>(); @@ -445,13 +474,16 @@ public StaticContext visitFunctionCall(FunctionCallExpression expression, Static // check arguments are of correct type for (int i = 0; i < paramsLength; ++i) { if (parameterExpressions.get(i) != null) { - SequenceType actualType = parameterExpressions.get(i).getInferredSequenceType(); + SequenceType actualType = parameterExpressions.get(i).getStaticSequenceType(); + if (actualType == null) { + throw new OurBadException("No static type inferred for expression " + parameterExpressions.get(i)); + } SequenceType expectedType = parameterTypes.get(i); // check actual parameters is either a subtype of or can be promoted to expected type if (!actualType.isSubtypeOfOrCanBePromotedTo(expectedType)) { - throw new UnexpectedStaticTypeException( - "Argument " + i + " requires " + expectedType + " but " + actualType + " was found", - expression.getMetadata() + throwStaticTypeException( + "Argument " + i + " requires " + expectedType + " but " + actualType + " was found", + expression.getMetadata() ); } } else { @@ -461,7 +493,7 @@ public StaticContext visitFunctionCall(FunctionCallExpression expression, Static if (expression.isPartialApplication()) { FunctionSignature partialSignature = new FunctionSignature(partialParams, signature.getReturnType()); - expression.setInferredSequenceType( + expression.setStaticSequenceType( new SequenceType(ItemTypeFactory.createFunctionItemType(partialSignature)) ); } else { @@ -470,13 +502,12 @@ public StaticContext visitFunctionCall(FunctionCallExpression expression, Static // we did not annotate a specific function, therefore we use default return type SequenceType returnType = signature.getReturnType(); if (returnType == null) { - returnType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + returnType = SequenceType.ITEM_STAR; } - expression.setInferredSequenceType(returnType); + expression.setStaticSequenceType(returnType); } } - System.out.println("Visited static function call, set type to " + expression.getInferredSequenceType()); return argument; } @@ -486,110 +517,110 @@ public StaticContext visitFunctionCall(FunctionCallExpression expression, Static @Override public StaticContext visitCastableExpression(CastableExpression expression, StaticContext argument) { - System.out.println("visiting Castable expression"); visitDescendants(expression, argument); ItemType itemType = expression.getSequenceType().getItemType(); if (itemType.equals(BuiltinTypesCatalogue.atomicItem)) { - throw new UnexpectedStaticTypeException( - "atomic item type is not allowed in castable expression", - ErrorCode.CastableErrorCode, - expression.getMetadata() + throwStaticTypeException( + "atomic item type is not allowed in castable expression", + ErrorCode.CastableErrorCode, + expression.getMetadata() ); } - SequenceType expressionType = expression.getMainExpression().getInferredSequenceType(); + SequenceType expressionType = expression.getMainExpression().getStaticSequenceType(); basicChecks(expressionType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); if ( !expressionType.isEmptySequence() && !expressionType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.atomicItem) ) { - throw new UnexpectedStaticTypeException( - "non-atomic item types are not allowed in castable expression, found " - + expressionType.getItemType(), - expressionType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.JSONItem) - ? ErrorCode.NonAtomicElementErrorCode - : ErrorCode.AtomizationError, - expression.getMetadata() + throwStaticTypeException( + "non-atomic item types are not allowed in castable expression, found " + + expressionType.getItemType(), + expressionType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.JSONItem) + ? ErrorCode.NonAtomicElementErrorCode + : ErrorCode.AtomizationError, + expression.getMetadata() ); } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); return argument; } @Override public StaticContext visitCastExpression(CastExpression expression, StaticContext argument) { - System.out.println("visiting Cast expression"); visitDescendants(expression, argument); // check at static time for casting errors (note cast only allows for normal or ? arity) - SequenceType expressionSequenceType = expression.getMainExpression().getInferredSequenceType(); + SequenceType expressionSequenceType = expression.getMainExpression().getStaticSequenceType(); SequenceType castedSequenceType = expression.getSequenceType(); if (castedSequenceType.getItemType().equals(BuiltinTypesCatalogue.atomicItem)) { - throw new UnexpectedStaticTypeException( - "atomic item type is not allowed in cast expression", - ErrorCode.CastableErrorCode, - expression.getMetadata() + throwStaticTypeException( + "atomic item type is not allowed in cast expression", + ErrorCode.CastableErrorCode, + expression.getMetadata() ); } // Empty sequence case if (expressionSequenceType.isEmptySequence()) { if (castedSequenceType.getArity() != SequenceType.Arity.OneOrZero) { - throw new UnexpectedStaticTypeException( - "Empty sequence cannot be cast to type with quantifier different from '?'", - expression.getMetadata() + throwStaticTypeException( + "Empty sequence cannot be cast to type with quantifier different from '?'", + expression.getMetadata() ); } else { // no additional check is needed - expression.setInferredSequenceType(castedSequenceType); + expression.setStaticSequenceType(castedSequenceType); return argument; } } if (!expressionSequenceType.isAritySubtypeOf(castedSequenceType.getArity())) { - throw new UnexpectedStaticTypeException( - "with static type feature it is not possible to cast a " - + - expressionSequenceType - + " as " - + castedSequenceType, - expression.getMetadata() + throwStaticTypeException( + "with static type feature it is not possible to cast a " + + + expressionSequenceType + + " as " + + castedSequenceType, + expression.getMetadata() ); } // ItemType static castability check if (!expressionSequenceType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.atomicItem)) { - throw new UnexpectedStaticTypeException( - "It is never possible to cast a non-atomic sequence type: " - + - expressionSequenceType, - expressionSequenceType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.JSONItem) - ? ErrorCode.NonAtomicElementErrorCode - : ErrorCode.AtomizationError, - expression.getMetadata() + throwStaticTypeException( + "It is never possible to cast a non-atomic sequence type: " + + + expressionSequenceType, + expressionSequenceType.getItemType().isSubtypeOf(BuiltinTypesCatalogue.JSONItem) + ? ErrorCode.NonAtomicElementErrorCode + : ErrorCode.AtomizationError, + expression.getMetadata() ); } - if (!expressionSequenceType.getItemType().isStaticallyCastableAs(castedSequenceType.getItemType())) { - throw new UnexpectedStaticTypeException( - "It is never possible to cast a " - + - expressionSequenceType - + " as " - + castedSequenceType, - expression.getMetadata() + if ( + !expressionSequenceType.getItemType().isAtomicItemType() + || !expressionSequenceType.getItemType().isStaticallyCastableAs(castedSequenceType.getItemType()) + ) { + throwStaticTypeException( + "It is never possible to cast a " + + + expressionSequenceType + + " as " + + castedSequenceType, + expression.getMetadata() ); } - expression.setInferredSequenceType(castedSequenceType); + expression.setStaticSequenceType(castedSequenceType); return argument; } @Override public StaticContext visitIsStaticallyExpr(IsStaticallyExpression expression, StaticContext argument) { - System.out.println("visiting StaticallyIs expression"); visitDescendants(expression, argument); - SequenceType inferred = expression.getMainExpression().getInferredSequenceType(); + SequenceType inferred = expression.getMainExpression().getStaticSequenceType(); SequenceType expected = expression.getSequenceType(); if (!inferred.equals(expected)) { throw new IsStaticallyUnexpectedTypeException( @@ -598,35 +629,33 @@ public StaticContext visitIsStaticallyExpr(IsStaticallyExpression expression, St ); } - expression.setInferredSequenceType(expected); + expression.setStaticSequenceType(expected); return argument; } @Override public StaticContext visitInstanceOfExpression(InstanceOfExpression expression, StaticContext argument) { - System.out.println("visiting InstanceOf expression"); visitDescendants(expression, argument); - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); return argument; } @Override public StaticContext visitTreatExpression(TreatExpression expression, StaticContext argument) { - System.out.println("visiting Treat expression"); visitDescendants(expression, argument); // check at static time for treat errors - SequenceType expressionSequenceType = expression.getMainExpression().getInferredSequenceType(); + SequenceType expressionSequenceType = expression.getMainExpression().getStaticSequenceType(); SequenceType treatedSequenceType = expression.getSequenceType(); if (expressionSequenceType == null || treatedSequenceType == null) { - throw new UnexpectedStaticTypeException( - "The child expression of a Treat expression has no inferred type or it is being treated as null sequence type", - expression.getMetadata() + throwStaticTypeException( + "The child expression of a Treat expression has no inferred type or it is being treated as null sequence type", + expression.getMetadata() ); } - expression.setInferredSequenceType(treatedSequenceType); + expression.setStaticSequenceType(treatedSequenceType); return argument; } @@ -638,8 +667,8 @@ public StaticContext visitTreatExpression(TreatExpression expression, StaticCont public StaticContext visitAdditiveExpr(AdditiveExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType leftInferredType = expression.getLeftExpression().getInferredSequenceType(); - SequenceType rightInferredType = expression.getRightExpression().getInferredSequenceType(); + SequenceType leftInferredType = expression.getLeftExpression().getStaticSequenceType(); + SequenceType rightInferredType = expression.getRightExpression().getStaticSequenceType(); basicChecks( Arrays.asList(leftInferredType, rightInferredType), @@ -654,10 +683,11 @@ public StaticContext visitAdditiveExpr(AdditiveExpression expression, StaticCont // arity check if (inferredArity == null) { - throw new UnexpectedStaticTypeException( - "'+' and '*' arities are not allowed for additive expressions", - expression.getMetadata() + throwStaticTypeException( + "'+' and '*' arities are not allowed for additive expressions", + expression.getMetadata() ); + inferredArity = SequenceType.Arity.OneOrZero; } ItemType leftItemType = leftInferredType.getItemType(); @@ -712,24 +742,24 @@ public StaticContext visitAdditiveExpr(AdditiveExpression expression, StaticCont if (inferredType == null) { if (inferredArity == SequenceType.Arity.OneOrZero) { // Only possible resulting type is empty sequence so throw error XPST0005 - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } else { - throw new UnexpectedStaticTypeException( - "The following types operation is not possible: " - + leftInferredType - + (expression.isMinus() ? " - " : " + ") - + rightInferredType, - expression.getMetadata() + throwStaticTypeException( + "The following types operation is not possible: " + + leftInferredType + + (expression.isMinus() ? " - " : " + ") + + rightInferredType, + expression.getMetadata() ); } + inferredType = BuiltinTypesCatalogue.atomicItem; } - expression.setInferredSequenceType(new SequenceType(inferredType, inferredArity)); - System.out.println("visiting Additive expression, set type: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(inferredType, inferredArity)); return argument; } @@ -769,8 +799,8 @@ private SequenceType.Arity resolveArities(SequenceType.Arity left, SequenceType. public StaticContext visitMultiplicativeExpr(MultiplicativeExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType leftInferredType = expression.getLeftExpression().getInferredSequenceType(); - SequenceType rightInferredType = expression.getRightExpression().getInferredSequenceType(); + SequenceType leftInferredType = expression.getLeftExpression().getStaticSequenceType(); + SequenceType rightInferredType = expression.getRightExpression().getStaticSequenceType(); basicChecks( Arrays.asList(leftInferredType, rightInferredType), @@ -784,10 +814,11 @@ public StaticContext visitMultiplicativeExpr(MultiplicativeExpression expression SequenceType.Arity inferredArity = resolveArities(leftInferredType.getArity(), rightInferredType.getArity()); if (inferredArity == null) { - throw new UnexpectedStaticTypeException( - "'+' and '*' arities are not allowed for multiplicative expressions", - expression.getMetadata() + throwStaticTypeException( + "'+' and '*' arities are not allowed for multiplicative expressions", + expression.getMetadata() ); + inferredArity = SequenceType.Arity.OneOrZero; } ItemType leftItemType = leftInferredType.getItemType(); @@ -835,48 +866,48 @@ public StaticContext visitMultiplicativeExpr(MultiplicativeExpression expression if (inferredType == null) { if (inferredArity == SequenceType.Arity.OneOrZero) { // Only possible resulting type is empty sequence so throw error XPST0005 - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } else { - throw new UnexpectedStaticTypeException( - "The following types expression is not valid: " - + leftItemType - + " " - + expression.getMultiplicativeOperator() - + " " - + rightItemType, - expression.getMetadata() + throwStaticTypeException( + "The following types expression is not valid: " + + leftItemType + + " " + + expression.getMultiplicativeOperator() + + " " + + rightItemType, + expression.getMetadata() ); } + inferredType = BuiltinTypesCatalogue.atomicItem; } - expression.setInferredSequenceType(new SequenceType(inferredType, inferredArity)); - System.out.println("visiting Multiplicative expression, set type: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(inferredType, inferredArity)); return argument; } @Override public StaticContext visitUnaryExpr(UnaryExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType childInferredType = expression.getMainExpression().getInferredSequenceType(); + SequenceType childInferredType = expression.getMainExpression().getStaticSequenceType(); // if the child expression has null inferred type throw error if (childInferredType == null) { - throw new UnexpectedStaticTypeException( - "The child expression of a UnaryExpression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "The child expression of a UnaryExpression has no inferred type", + expression.getMetadata() ); } // if the child is the empty sequence just infer the empty sequence if (childInferredType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } @@ -884,9 +915,9 @@ public StaticContext visitUnaryExpr(UnaryExpression expression, StaticContext ar childInferredType.getArity() == SequenceType.Arity.OneOrMore || childInferredType.getArity() == SequenceType.Arity.ZeroOrMore ) { - throw new UnexpectedStaticTypeException( - "'+' and '*' arities are not allowed for unary expressions", - expression.getMetadata() + throwStaticTypeException( + "'+' and '*' arities are not allowed for unary expressions", + expression.getMetadata() ); } @@ -895,21 +926,20 @@ public StaticContext visitUnaryExpr(UnaryExpression expression, StaticContext ar ItemType childItemType = childInferredType.getItemType(); if (!childItemType.isNumeric()) { if (childInferredType.getArity() == SequenceType.Arity.OneOrZero) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } else { - throw new UnexpectedStaticTypeException( - "It is not possible to have an Unary expression with the following type: " + childInferredType, - expression.getMetadata() + throwStaticTypeException( + "It is not possible to have an Unary expression with the following type: " + childInferredType, + expression.getMetadata() ); } } - expression.setInferredSequenceType(new SequenceType(childItemType, childInferredType.getArity())); - System.out.println("visiting Unary expression, set type: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(childItemType, childInferredType.getArity())); return argument; } @@ -921,39 +951,39 @@ private StaticContext visitAndOrExpr(Expression expression, StaticContext argume visitDescendants(expression, argument); List childrenExpressions = expression.getChildren(); - SequenceType leftInferredType = ((Expression) childrenExpressions.get(0)).getInferredSequenceType(); - SequenceType rightInferredType = ((Expression) childrenExpressions.get(1)).getInferredSequenceType(); + SequenceType leftInferredType = ((Expression) childrenExpressions.get(0)).getStaticSequenceType(); + SequenceType rightInferredType = ((Expression) childrenExpressions.get(1)).getStaticSequenceType(); if (leftInferredType == null || rightInferredType == null) { - throw new UnexpectedStaticTypeException( - "A child expression of a " + expressionName + "Expression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "A child expression of a " + expressionName + "Expression has no inferred type", + expression.getMetadata() ); } if (!leftInferredType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "left expression of a " - + expressionName - + "Expression has " - + leftInferredType - + " inferred type, which has no effective boolean value", - expression.getMetadata() + throwStaticTypeException( + "left expression of a " + + expressionName + + "Expression has " + + leftInferredType + + " inferred type, which has no effective boolean value", + expression.getMetadata() ); } if (!rightInferredType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "right expression of a " - + expressionName - + "Expression has " - + rightInferredType - + " inferred type, which has no effective boolean value", - expression.getMetadata() + throwStaticTypeException( + "right expression of a " + + expressionName + + "Expression has " + + rightInferredType + + " inferred type, which has no effective boolean value", + expression.getMetadata() ); } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); return argument; } @@ -971,23 +1001,23 @@ public StaticContext visitOrExpr(OrExpression expression, StaticContext argument public StaticContext visitNotExpr(NotExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType childInferredType = expression.getMainExpression().getInferredSequenceType(); + SequenceType childInferredType = expression.getMainExpression().getStaticSequenceType(); if (childInferredType == null) { - throw new UnexpectedStaticTypeException( - "The child expression of NotExpression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "The child expression of NotExpression has no inferred type", + expression.getMetadata() ); } if (!childInferredType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "The child expression of NotExpression has " - + childInferredType - + " inferred type, which has no effective boolean value", - expression.getMetadata() + throwStaticTypeException( + "The child expression of NotExpression has " + + childInferredType + + " inferred type, which has no effective boolean value", + expression.getMetadata() ); } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem)); return argument; } @@ -1000,14 +1030,14 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static visitDescendants(expression, argument); List childrenExpressions = expression.getChildren(); - SequenceType leftInferredType = ((Expression) childrenExpressions.get(0)).getInferredSequenceType(); - SequenceType rightInferredType = ((Expression) childrenExpressions.get(1)).getInferredSequenceType(); + SequenceType leftInferredType = ((Expression) childrenExpressions.get(0)).getStaticSequenceType(); + SequenceType rightInferredType = ((Expression) childrenExpressions.get(1)).getStaticSequenceType(); SequenceType.Arity returnArity = SequenceType.Arity.One; if (leftInferredType == null || rightInferredType == null) { - throw new UnexpectedStaticTypeException( - "A child expression of a ComparisonExpression has no inferred type", - expression.getMetadata() + throwStaticTypeException( + "A child expression of a ComparisonExpression has no inferred type", + expression.getMetadata() ); } @@ -1017,18 +1047,19 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static // XPST0005 error if (operator.isValueComparison()) { if (leftInferredType.isEmptySequence() || rightInferredType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } returnArity = resolveArities(leftInferredType.getArity(), rightInferredType.getArity()); if (returnArity == null) { - throw new UnexpectedStaticTypeException( - "'+' and '*' arities are not allowed for this comparison operator: " + operator, - expression.getMetadata() + throwStaticTypeException( + "'+' and '*' arities are not allowed for this comparison operator: " + operator, + expression.getMetadata() ); + returnArity = SequenceType.Arity.OneOrZero; } } @@ -1046,10 +1077,10 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static leftItemType.isSubtypeOf(BuiltinTypesCatalogue.JSONItem) || rightItemType.isSubtypeOf(BuiltinTypesCatalogue.JSONItem) ) { - throw new UnexpectedStaticTypeException( - "It is not possible to compare with non-atomic types", - ErrorCode.NonAtomicElementErrorCode, - expression.getMetadata() + throwStaticTypeException( + "It is not possible to compare with non-atomic types", + ErrorCode.NonAtomicElementErrorCode, + expression.getMetadata() ); } if ( @@ -1058,9 +1089,9 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static || leftItemType.equals(BuiltinTypesCatalogue.atomicItem) || rightItemType.equals(BuiltinTypesCatalogue.atomicItem) ) { - throw new UnexpectedStaticTypeException( - "It is not possible to compare with non-atomic types", - expression.getMetadata() + throwStaticTypeException( + "It is not possible to compare with non-atomic types", + expression.getMetadata() ); } @@ -1080,9 +1111,9 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static !(leftItemType.equals(BuiltinTypesCatalogue.nullItem) || rightItemType.equals(BuiltinTypesCatalogue.nullItem)) ) { - throw new UnexpectedStaticTypeException( - "It is not possible to compare these types: " + leftItemType + " and " + rightItemType, - expression.getMetadata() + throwStaticTypeException( + "It is not possible to compare these types: " + leftItemType + " and " + rightItemType, + expression.getMetadata() ); } @@ -1105,19 +1136,19 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static || leftItemType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) && !rightItemType.equals(leftItemType))) ) { - throw new UnexpectedStaticTypeException( - "It is not possible to compare these types: " - + leftItemType - + " " - + operator - + " " - + rightItemType, - expression.getMetadata() + throwStaticTypeException( + "It is not possible to compare these types: " + + leftItemType + + " " + + operator + + " " + + rightItemType, + expression.getMetadata() ); } } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem, returnArity)); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.booleanItem, returnArity)); return argument; } @@ -1129,9 +1160,9 @@ public StaticContext visitComparisonExpr(ComparisonExpression expression, Static public StaticContext visitConditionalExpression(ConditionalExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType ifType = expression.getCondition().getInferredSequenceType(); - SequenceType thenType = expression.getBranch().getInferredSequenceType(); - SequenceType elseType = expression.getElseBranch().getInferredSequenceType(); + SequenceType ifType = expression.getCondition().getStaticSequenceType(); + SequenceType thenType = expression.getBranch().getStaticSequenceType(); + SequenceType elseType = expression.getElseBranch().getStaticSequenceType(); if (ifType == null || thenType == null || elseType == null) { throw new OurBadException( @@ -1141,11 +1172,11 @@ public StaticContext visitConditionalExpression(ConditionalExpression expression } if (!ifType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "The condition in the 'if' must have effective boolean value, found inferred type: " - + ifType - + " (which has not effective boolean value)", - expression.getMetadata() + throwStaticTypeException( + "The condition in the 'if' must have effective boolean value, found inferred type: " + + ifType + + " (which has not effective boolean value)", + expression.getMetadata() ); } @@ -1155,15 +1186,14 @@ public StaticContext visitConditionalExpression(ConditionalExpression expression : thenType.leastCommonSupertypeWith(elseType); if (resultingType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } - expression.setInferredSequenceType(resultingType); - System.out.println("visiting Conditional expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(resultingType); return argument; } @@ -1176,32 +1206,32 @@ public void checkSwitchType(SequenceType type, ExceptionMetadata metadata) { return; // no further check is required } if (type.getArity() == SequenceType.Arity.OneOrMore || type.getArity() == SequenceType.Arity.ZeroOrMore) { - throw new UnexpectedStaticTypeException( - "+ and * arities are not allowed for the expressions of switch test condition and cases", - metadata + throwStaticTypeException( + "+ and * arities are not allowed for the expressions of switch test condition and cases", + metadata ); } ItemType itemType = type.getItemType(); if (itemType.isFunctionItemType()) { - throw new UnexpectedStaticTypeException( - "function item not allowed for the expressions of switch test condition and cases", - ErrorCode.UnexpectedFunctionItem, - metadata + throwStaticTypeException( + "function item not allowed for the expressions of switch test condition and cases", + ErrorCode.UnexpectedFunctionItem, + metadata ); } if (itemType.isSubtypeOf(BuiltinTypesCatalogue.JSONItem)) { - throw new UnexpectedStaticTypeException( - "switch test condition and cases expressions' item type must match atomic, instead inferred: " - + itemType, - ErrorCode.NonAtomicElementErrorCode, - metadata + throwStaticTypeException( + "switch test condition and cases expressions' item type must match atomic, instead inferred: " + + itemType, + ErrorCode.NonAtomicElementErrorCode, + metadata ); } if (!itemType.isSubtypeOf(BuiltinTypesCatalogue.atomicItem)) { - throw new UnexpectedStaticTypeException( - "switch test condition and cases expressions' item type must match atomic, instead inferred: " - + itemType, - metadata + throwStaticTypeException( + "switch test condition and cases expressions' item type must match atomic, instead inferred: " + + itemType, + metadata ); } } @@ -1209,10 +1239,10 @@ public void checkSwitchType(SequenceType type, ExceptionMetadata metadata) { @Override public StaticContext visitSwitchExpression(SwitchExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType testType = expression.getTestCondition().getInferredSequenceType(); + SequenceType testType = expression.getTestCondition().getStaticSequenceType(); checkSwitchType(testType, expression.getMetadata()); - SequenceType returnType = expression.getDefaultExpression().getInferredSequenceType(); + SequenceType returnType = expression.getDefaultExpression().getStaticSequenceType(); if (returnType == null) { throw new OurBadException( "A child expression of a SwitchExpression has no inferred type", @@ -1224,13 +1254,13 @@ public StaticContext visitSwitchExpression(SwitchExpression expression, StaticCo boolean addToReturnType = false; for (Expression caseExpression : switchCase.getConditionExpressions()) { // test the case expression - checkSwitchType(caseExpression.getInferredSequenceType(), expression.getMetadata()); + checkSwitchType(caseExpression.getStaticSequenceType(), expression.getMetadata()); // if has overlap with the test condition will add the return type to the possible ones - if (caseExpression.getInferredSequenceType().hasOverlapWith(testType)) { + if (caseExpression.getStaticSequenceType().hasOverlapWith(testType)) { addToReturnType = true; } } - SequenceType caseReturnType = switchCase.getReturnExpression().getInferredSequenceType(); + SequenceType caseReturnType = switchCase.getReturnExpression().getStaticSequenceType(); if (caseReturnType == null) { throw new OurBadException( "A child expression of a SwitchExpression has no inferred type", @@ -1242,8 +1272,7 @@ public StaticContext visitSwitchExpression(SwitchExpression expression, StaticCo } } - expression.setInferredSequenceType(returnType); - System.out.println("visiting Switch expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(returnType); return argument; } @@ -1253,7 +1282,7 @@ public StaticContext visitTryCatchExpression(TryCatchExpression expression, Stat SequenceType inferredType = null; for (Node childNode : expression.getChildren()) { - SequenceType childType = ((Expression) childNode).getInferredSequenceType(); + SequenceType childType = ((Expression) childNode).getStaticSequenceType(); if (childType == null) { throw new OurBadException( "A child expression of a TryCatchExpression has no inferred type", @@ -1269,14 +1298,13 @@ public StaticContext visitTryCatchExpression(TryCatchExpression expression, Stat } if (inferredType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } - expression.setInferredSequenceType(inferredType); - System.out.println("visiting TryCatch expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(inferredType); return argument; } @@ -1285,7 +1313,7 @@ public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, visit(expression.getTestCondition(), argument); SequenceType inferredType = null; - SequenceType conditionType = expression.getTestCondition().getInferredSequenceType(); + SequenceType conditionType = expression.getTestCondition().getStaticSequenceType(); basicChecks(conditionType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); for (TypeswitchCase typeswitchCase : expression.getCases()) { @@ -1301,7 +1329,7 @@ public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, } visit(returnExpression, argument); - SequenceType caseType = returnExpression.getInferredSequenceType(); + SequenceType caseType = returnExpression.getStaticSequenceType(); basicChecks(caseType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); inferredType = inferredType == null ? caseType : inferredType.leastCommonSupertypeWith(caseType); } @@ -1313,13 +1341,12 @@ public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, returnExpression.getStaticContext().replaceVariableSequenceType(variableName, conditionType); } visit(returnExpression, argument); - SequenceType defaultType = returnExpression.getInferredSequenceType(); + SequenceType defaultType = returnExpression.getStaticSequenceType(); basicChecks(defaultType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); inferredType = inferredType.leastCommonSupertypeWith(defaultType); basicChecks(inferredType, expression.getClass().getSimpleName(), false, true, expression.getMetadata()); - expression.setInferredSequenceType(inferredType); - System.out.println("visiting TypeSwitch expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(inferredType); return argument; } @@ -1332,39 +1359,45 @@ public StaticContext visitRangeExpr(RangeExpression expression, StaticContext ar visitDescendants(expression, argument); List children = expression.getChildren(); - SequenceType leftType = ((Expression) children.get(0)).getInferredSequenceType(); - SequenceType rightType = ((Expression) children.get(1)).getInferredSequenceType(); + SequenceType leftType = ((Expression) children.get(0)).getStaticSequenceType(); + SequenceType rightType = ((Expression) children.get(1)).getStaticSequenceType(); - if (leftType == null || rightType == null) { + if (leftType == null) { throw new OurBadException( "A child expression of a RangeExpression has no inferred type", - expression.getMetadata() + ((Expression) children.get(0)).getMetadata() + ); + } + + if (rightType == null) { + throw new OurBadException( + "A child expression of a RangeExpression has no inferred type", + ((Expression) children.get(1)).getMetadata() ); } if (leftType.isEmptySequence() || rightType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } SequenceType intOpt = new SequenceType(BuiltinTypesCatalogue.integerItem, SequenceType.Arity.OneOrZero); if (!leftType.isSubtypeOf(intOpt) || !rightType.isSubtypeOf(intOpt)) { - throw new UnexpectedStaticTypeException( - "operands of the range expression must match type integer? instead found: " - + leftType - + " and " - + rightType, - expression.getMetadata() + throwStaticTypeException( + "operands of the range expression must match type integer? instead found: " + + leftType + + " and " + + rightType, + expression.getMetadata() ); } - expression.setInferredSequenceType( + expression.setStaticSequenceType( new SequenceType(BuiltinTypesCatalogue.integerItem, SequenceType.Arity.ZeroOrMore) ); - System.out.println("visiting Range expression, type set to: " + expression.getInferredSequenceType()); return argument; } @@ -1373,8 +1406,8 @@ public StaticContext visitStringConcatExpr(StringConcatExpression expression, St visitDescendants(expression, argument); List children = expression.getChildren(); - SequenceType leftType = ((Expression) children.get(0)).getInferredSequenceType(); - SequenceType rightType = ((Expression) children.get(1)).getInferredSequenceType(); + SequenceType leftType = ((Expression) children.get(0)).getStaticSequenceType(); + SequenceType rightType = ((Expression) children.get(1)).getStaticSequenceType(); if (leftType == null || rightType == null) { throw new OurBadException( @@ -1385,17 +1418,16 @@ public StaticContext visitStringConcatExpr(StringConcatExpression expression, St SequenceType intOpt = new SequenceType(BuiltinTypesCatalogue.atomicItem, SequenceType.Arity.OneOrZero); if (!leftType.isSubtypeOf(intOpt) || !rightType.isSubtypeOf(intOpt)) { - throw new UnexpectedStaticTypeException( - "operands of the concat expression must match type atomic? instead found: " - + leftType - + " and " - + rightType, - expression.getMetadata() + throwStaticTypeException( + "operands of the concat expression must match type atomic? instead found: " + + leftType + + " and " + + rightType, + expression.getMetadata() ); } - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.stringItem)); - System.out.println("visiting Concat expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.stringItem)); return argument; } @@ -1407,8 +1439,8 @@ public StaticContext visitStringConcatExpr(StringConcatExpression expression, St public StaticContext visitArrayLookupExpression(ArrayLookupExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType mainType = expression.getMainExpression().getInferredSequenceType(); - SequenceType lookupType = expression.getLookupExpression().getInferredSequenceType(); + SequenceType mainType = expression.getMainExpression().getStaticSequenceType(); + SequenceType lookupType = expression.getLookupExpression().getStaticSequenceType(); if (mainType == null || lookupType == null) { throw new OurBadException( @@ -1418,25 +1450,24 @@ public StaticContext visitArrayLookupExpression(ArrayLookupExpression expression } if (!lookupType.isSubtypeOf(SequenceType.createSequenceType("integer"))) { - throw new UnexpectedStaticTypeException( - "the lookup expression type must match integer, instead " + lookupType + " was inferred", - expression.getMetadata() + throwStaticTypeException( + "the lookup expression type must match integer, instead " + lookupType + " was inferred", + expression.getMetadata() ); } if (!mainType.hasOverlapWith(SequenceType.createSequenceType("array*")) || mainType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } SequenceType.Arity inferredArity = mainType.isAritySubtypeOf(SequenceType.Arity.OneOrZero) ? SequenceType.Arity.OneOrZero : SequenceType.Arity.ZeroOrMore; - expression.setInferredSequenceType(new SequenceType(BuiltinTypesCatalogue.item, inferredArity)); - System.out.println("visiting ArrayLookup expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(BuiltinTypesCatalogue.item, inferredArity)); return argument; } @@ -1444,8 +1475,8 @@ public StaticContext visitArrayLookupExpression(ArrayLookupExpression expression public StaticContext visitObjectLookupExpression(ObjectLookupExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType mainType = expression.getMainExpression().getInferredSequenceType(); - SequenceType lookupType = expression.getLookupExpression().getInferredSequenceType(); + SequenceType mainType = expression.getMainExpression().getStaticSequenceType(); + SequenceType lookupType = expression.getLookupExpression().getStaticSequenceType(); if (mainType == null || lookupType == null) { throw new OurBadException( @@ -1456,19 +1487,19 @@ public StaticContext visitObjectLookupExpression(ObjectLookupExpression expressi // must be castable to string if (!lookupType.isSubtypeOf(SequenceType.createSequenceType("atomic"))) { - throw new UnexpectedStaticTypeException( - "the lookup expression type must be castable to string (i.e. must match atomic), instead " - + lookupType - + " was inferred", - expression.getMetadata() + throwStaticTypeException( + "the lookup expression type must be castable to string (i.e. must match atomic), instead " + + lookupType + + " was inferred", + expression.getMetadata() ); } if (!mainType.hasOverlapWith(SequenceType.createSequenceType("object*")) || mainType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } @@ -1495,16 +1526,15 @@ public StaticContext visitObjectLookupExpression(ObjectLookupExpression expressi } } else if (isObjectClosed) { // if object is closed and key is not found then for sure we will return the empty sequence - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } } - expression.setInferredSequenceType(new SequenceType(inferredType, inferredArity)); - System.out.println("visiting ObjectLookup expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(inferredType, inferredArity)); return argument; } @@ -1512,7 +1542,7 @@ public StaticContext visitObjectLookupExpression(ObjectLookupExpression expressi public StaticContext visitArrayUnboxingExpression(ArrayUnboxingExpression expression, StaticContext argument) { visitDescendants(expression, argument); - SequenceType mainType = expression.getMainExpression().getInferredSequenceType(); + SequenceType mainType = expression.getMainExpression().getStaticSequenceType(); if (mainType == null) { throw new OurBadException( @@ -1522,47 +1552,44 @@ public StaticContext visitArrayUnboxingExpression(ArrayUnboxingExpression expres } if (!mainType.hasOverlapWith(SequenceType.createSequenceType("array*")) || mainType.isEmptySequence()) { - throw new UnexpectedStaticTypeException( - "Inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } - expression.setInferredSequenceType(SequenceType.createSequenceType("item*")); - System.out.println( - "visiting ArrayUnboxingExpression expression, type set to: " + expression.getInferredSequenceType() - ); + expression.setStaticSequenceType(SequenceType.createSequenceType("item*")); return argument; } @Override public StaticContext visitFilterExpression(FilterExpression expression, StaticContext argument) { visit(expression.getMainExpression(), argument); - SequenceType mainType = expression.getMainExpression().getInferredSequenceType(); + SequenceType mainType = expression.getMainExpression().getStaticSequenceType(); basicChecks(mainType, expression.getClass().getSimpleName(), true, true, expression.getMetadata()); Expression predicateExpression = expression.getPredicateExpression(); // set context item static type predicateExpression.getStaticContext().setContextItemStaticType(new SequenceType(mainType.getItemType())); visit(predicateExpression, argument); - SequenceType predicateType = predicateExpression.getInferredSequenceType(); + SequenceType predicateType = predicateExpression.getStaticSequenceType(); // unset context item static type predicateExpression.getStaticContext().setContextItemStaticType(null); basicChecks(predicateType, expression.getClass().getSimpleName(), true, true, expression.getMetadata()); // always false so the return type is for sure () if (predicateType.isSubtypeOf(SequenceType.createSequenceType("null?"))) { - throw new UnexpectedStaticTypeException( - "Inferred type for FilterExpression is empty sequence (with active static typing feature, only allowed for CommaExpression)", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "Inferred type for FilterExpression is empty sequence (with active static typing feature, only allowed for CommaExpression)", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } if (!predicateType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "Inferred type " + predicateType + " in FilterExpression has no effective boolean value", - expression.getMetadata() + throwStaticTypeException( + "Inferred type " + predicateType + " in FilterExpression has no effective boolean value", + expression.getMetadata() ); } @@ -1572,8 +1599,7 @@ public StaticContext visitFilterExpression(FilterExpression expression, StaticCo || predicateType.getItemType().equals(BuiltinTypesCatalogue.integerItem)) ? SequenceType.Arity.OneOrZero : SequenceType.Arity.ZeroOrMore; - expression.setInferredSequenceType(new SequenceType(mainType.getItemType(), inferredArity)); - System.out.println("visiting Filter expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(mainType.getItemType(), inferredArity)); return argument; } @@ -1596,42 +1622,69 @@ public StaticContext visitDynamicFunctionCallExpression( DynamicFunctionCallExpression expression, StaticContext argument ) { - // since we do not specify function's signature in the itemType we can only check that it is a function visitDescendants(expression, argument); - SequenceType mainType = expression.getMainExpression().getInferredSequenceType(); + SequenceType mainType = expression.getMainExpression().getStaticSequenceType(); basicChecks(mainType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); + if (mainType.isEmptySequence()) { + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; + } - FunctionSignature signature = null; - boolean isAnyFunction = false; - if (!mainType.isEmptySequence()) { - ItemType type = mainType.getItemType(); - if (type.isFunctionItemType()) { - if (type.equals(BuiltinTypesCatalogue.anyFunctionItem)) { - isAnyFunction = true; + ItemType type = mainType.getItemType(); + if (!type.isFunctionItemType()) { + expression.setStaticSequenceType(SequenceType.ITEM_STAR); + + throwStaticTypeException( + "the type of a dynamic function call main expression must be function, instead inferred " + mainType, + expression.getMetadata() + ); + return argument; + } + + if (type.equals(BuiltinTypesCatalogue.anyFunctionItem)) { + expression.setStaticSequenceType(SequenceType.ITEM_STAR); + return argument; + } + + FunctionSignature signature = type.getSignature(); + List actualParameterTypes = new ArrayList<>(); + List formalParameterTypes = signature.getParameterTypes(); + List partialFormalParameterTypes = new ArrayList<>(); + boolean isPartialApplication = false; + int i = 0; + for (Expression e : expression.getArguments()) { + if (e == null) { + isPartialApplication = true; + if (signature != null) { + partialFormalParameterTypes.add(formalParameterTypes.get(i)); } else { - signature = type.getSignature(); + partialFormalParameterTypes.add(SequenceType.ITEM_STAR); } } + if (e != null) { + actualParameterTypes.add(e.getStaticSequenceType()); + } + ++i; } - - List argsType = expression.getArguments() - .stream() - .map(Expression::getInferredSequenceType) - .collect(Collectors.toList()); - if (isAnyFunction || (signature != null && checkArguments(signature.getParameterTypes(), argsType))) { - // TODO: need to add support for partial application - expression.setInferredSequenceType(signature.getReturnType()); - System.out.println( - "visiting DynamicFunctionCall expression, type set to: " + expression.getInferredSequenceType() + if (isPartialApplication) { + FunctionSignature newSignature = new FunctionSignature( + partialFormalParameterTypes, + signature.getReturnType() ); + expression.setStaticSequenceType(new SequenceType(ItemTypeFactory.createFunctionItemType(newSignature))); return argument; } - - throw new UnexpectedStaticTypeException( - "the type of a dynamic function call main expression must be function, instead inferred " + mainType, + if (!checkArguments(formalParameterTypes, actualParameterTypes)) { + throwStaticTypeException( + "the type of a dynamic function call main expression must be function, instead inferred " + + mainType, expression.getMetadata() - ); + ); + } + + expression.setStaticSequenceType(signature.getReturnType()); + return argument; } @Override @@ -1641,7 +1694,7 @@ public StaticContext visitSimpleMapExpr(SimpleMapExpression expression, StaticCo Expression rightExpression = (Expression) nodes.get(1); visit(leftExpression, argument); - SequenceType leftType = leftExpression.getInferredSequenceType(); + SequenceType leftType = leftExpression.getStaticSequenceType(); basicChecks(leftType, expression.getClass().getSimpleName(), true, true, expression.getMetadata()); // set context item static type @@ -1649,12 +1702,11 @@ public StaticContext visitSimpleMapExpr(SimpleMapExpression expression, StaticCo visit(rightExpression, argument); rightExpression.getStaticContext().setContextItemStaticType(null); - SequenceType rightType = rightExpression.getInferredSequenceType(); + SequenceType rightType = rightExpression.getStaticSequenceType(); basicChecks(rightType, expression.getClass().getSimpleName(), true, true, expression.getMetadata()); SequenceType.Arity resultingArity = leftType.getArity().multiplyWith(rightType.getArity()); - expression.setInferredSequenceType(new SequenceType(rightType.getItemType(), resultingArity)); - System.out.println("visiting SimpleMap expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(new SequenceType(rightType.getItemType(), resultingArity)); return argument; } @@ -1669,10 +1721,10 @@ public StaticContext visitFlowrExpression(FlworExpression expression, StaticCont SequenceType forType; while (clause != null) { - this.visit(clause, argument); + this.visit(clause, clause.getStaticContext()); // if there are for clauses we need to consider their arities for the returning expression if (clause.getClauseType() == FLWOR_CLAUSES.FOR) { - forType = ((ForClause) clause).getExpression().getInferredSequenceType(); + forType = ((ForClause) clause).getExpression().getStaticSequenceType(); // if forType is the empty sequence that means that allowing empty is set otherwise we would have thrown // an error // therefore this for loop will generate one tuple binding the empty sequence, so as for the arities @@ -1691,30 +1743,32 @@ public StaticContext visitFlowrExpression(FlworExpression expression, StaticCont clause = clause.getNextClause(); } - SequenceType returnType = expression.getReturnClause().getReturnExpr().getInferredSequenceType(); + SequenceType returnType = expression.getReturnClause().getReturnExpr().getStaticSequenceType(); basicChecks(returnType, expression.getClass().getSimpleName(), true, true, expression.getMetadata()); returnType = new SequenceType(returnType.getItemType(), returnType.getArity().multiplyWith(forArities)); - expression.setInferredSequenceType(returnType); - System.out.println("visiting Flowr expression, type set to: " + expression.getInferredSequenceType()); + expression.setStaticSequenceType(returnType); return argument; } @Override public StaticContext visitForClause(ForClause expression, StaticContext argument) { - visit(expression.getExpression(), argument); - + visitDescendants(expression, argument); SequenceType declaredType = expression.getActualSequenceType(); - SequenceType inferredType = (declaredType == null - ? expression.getExpression() - : ((TreatExpression) expression.getExpression()).getMainExpression()).getInferredSequenceType(); + SequenceType inferredType = SequenceType.ITEM_STAR; + if (declaredType == null) { + inferredType = expression.getExpression().getStaticSequenceType(); + } else { + inferredType = declaredType; + } + basicChecks(inferredType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); if (inferredType.isEmptySequence()) { if (!expression.isAllowEmpty()) { // for sure we will not have any tuple to process and return the empty sequence - throw new UnexpectedStaticTypeException( - "In for clause Inferred type is empty sequence, empty is not allowed, so the result returned is for sure () and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "In for clause Inferred type is empty sequence, empty is not allowed, so the result returned is for sure () and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } } else { @@ -1731,7 +1785,7 @@ public StaticContext visitForClause(ForClause expression, StaticContext argument } } - checkVariableType( + checkAndUpdateVariableStaticType( declaredType, inferredType, expression.getNextClause().getStaticContext(), @@ -1740,7 +1794,6 @@ public StaticContext visitForClause(ForClause expression, StaticContext argument expression.getMetadata() ); - System.out.println("visiting For clause, inferred var " + expression.getVariableName() + " : " + inferredType); return argument; } @@ -1750,8 +1803,8 @@ public StaticContext visitLetClause(LetClause expression, StaticContext argument SequenceType declaredType = expression.getActualSequenceType(); SequenceType inferredType = (declaredType == null ? expression.getExpression() - : ((TreatExpression) expression.getExpression()).getMainExpression()).getInferredSequenceType(); - checkVariableType( + : ((TreatExpression) expression.getExpression()).getMainExpression()).getStaticSequenceType(); + checkAndUpdateVariableStaticType( declaredType, inferredType, expression.getNextClause().getStaticContext(), @@ -1760,26 +1813,25 @@ public StaticContext visitLetClause(LetClause expression, StaticContext argument expression.getMetadata() ); - System.out.println("visiting Let clause, var " + expression.getVariableName() + " : " + inferredType); return argument; } @Override public StaticContext visitWhereClause(WhereClause expression, StaticContext argument) { visit(expression.getWhereExpression(), argument); - SequenceType whereType = expression.getWhereExpression().getInferredSequenceType(); + SequenceType whereType = expression.getWhereExpression().getStaticSequenceType(); basicChecks(whereType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); if (!whereType.hasEffectiveBooleanValue()) { - throw new UnexpectedStaticTypeException( - "where clause inferred type (" + whereType + ") has no effective boolean value", - expression.getMetadata() + throwStaticTypeException( + "where clause inferred type (" + whereType + ") has no effective boolean value", + expression.getMetadata() ); } if (whereType.isEmptySequence() || whereType.isSubtypeOf(SequenceType.createSequenceType("null?"))) { - throw new UnexpectedStaticTypeException( - "where clause always return false, so return expression inferred type is empty sequence and this is not a CommaExpression", - ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, - expression.getMetadata() + throwStaticTypeException( + "where clause always return false, so return expression inferred type is empty sequence and this is not a CommaExpression", + ErrorCode.StaticallyInferredEmptySequenceNotFromCommaExpression, + expression.getMetadata() ); } return argument; @@ -1795,17 +1847,17 @@ public StaticContext visitGroupByClause(GroupByClause expression, StaticContext Expression groupByVarExpr = groupByVar.getExpression(); SequenceType expectedType; if (groupByVarExpr != null) { - visit(groupByVarExpr, argument); + visit(groupByVarExpr, groupByVarExpr.getStaticContext()); SequenceType declaredType = groupByVar.getActualSequenceType(); SequenceType inferredType; if (declaredType == null) { - inferredType = groupByVarExpr.getInferredSequenceType(); + inferredType = groupByVarExpr.getStaticSequenceType(); expectedType = inferredType; } else { - inferredType = ((TreatExpression) groupByVarExpr).getMainExpression().getInferredSequenceType(); + inferredType = ((TreatExpression) groupByVarExpr).getMainExpression().getStaticSequenceType(); expectedType = declaredType; } - checkVariableType( + checkAndUpdateVariableStaticType( declaredType, inferredType, nextClause.getStaticContext(), @@ -1818,22 +1870,22 @@ public StaticContext visitGroupByClause(GroupByClause expression, StaticContext } // check that expectedType is a subtype of atomic? if (expectedType.isSubtypeOf(SequenceType.createSequenceType("json-item*"))) { - throw new UnexpectedStaticTypeException( - "group by variable " - + groupByVar.getVariableName() - + " must match atomic? instead found " - + expectedType, - ErrorCode.NonAtomicElementErrorCode, - expression.getMetadata() + throwStaticTypeException( + "group by variable " + + groupByVar.getVariableName() + + " must match atomic? instead found " + + expectedType, + ErrorCode.NonAtomicElementErrorCode, + expression.getMetadata() ); } if (!expectedType.isSubtypeOf(SequenceType.createSequenceType("atomic?"))) { - throw new UnexpectedStaticTypeException( - "group by variable " - + groupByVar.getVariableName() - + " must match atomic? instead found " - + expectedType, - expression.getMetadata() + throwStaticTypeException( + "group by variable " + + groupByVar.getVariableName() + + " must match atomic? instead found " + + expectedType, + expression.getMetadata() ); } groupingVars.add(groupByVar.getVariableName()); @@ -1851,14 +1903,14 @@ public StaticContext visitGroupByClause(GroupByClause expression, StaticContext public StaticContext visitOrderByClause(OrderByClause expression, StaticContext argument) { visitDescendants(expression, argument); for (OrderByClauseSortingKey orderClause : expression.getSortingKeys()) { - SequenceType orderType = orderClause.getExpression().getInferredSequenceType(); + SequenceType orderType = orderClause.getExpression().getStaticSequenceType(); basicChecks(orderType, expression.getClass().getSimpleName(), true, false, expression.getMetadata()); if (orderType.isSubtypeOf(SequenceType.createSequenceType("json-item*"))) { - throw new UnexpectedStaticTypeException( - "order by sorting expression's type must match atomic? and be comparable using 'gt' operator (so duration, hexBinary, base64Binary and atomic item type are not allowed), instead inferred: " - + orderType, - ErrorCode.NonAtomicElementErrorCode, - expression.getMetadata() + throwStaticTypeException( + "order by sorting expression's type must match atomic? and be comparable using 'gt' operator (so duration, hexBinary, base64Binary and atomic item type are not allowed), instead inferred: " + + orderType, + ErrorCode.NonAtomicElementErrorCode, + expression.getMetadata() ); } if ( @@ -1872,10 +1924,10 @@ public StaticContext visitOrderByClause(OrderByClause expression, StaticContext || orderType.getItemType().equals(BuiltinTypesCatalogue.base64BinaryItem) ) { - throw new UnexpectedStaticTypeException( - "order by sorting expression's type must match atomic? and be comparable using 'gt' operator (so duration, hexBinary, base64Binary and atomic item type are not allowed), instead inferred: " - + orderType, - expression.getMetadata() + throwStaticTypeException( + "order by sorting expression's type must match atomic? and be comparable using 'gt' operator (so duration, hexBinary, base64Binary and atomic item type are not allowed), instead inferred: " + + orderType, + expression.getMetadata() ); } } @@ -1890,7 +1942,7 @@ public StaticContext visitOrderByClause(OrderByClause expression, StaticContext // if [declaredType] is not null, check if the inferred type matches or can be promoted to the declared type // (otherwise throw type error) // if [declaredType] is null, replace the type of [variableName] in the [context] with the inferred type - public void checkVariableType( + public void checkAndUpdateVariableStaticType( SequenceType declaredType, SequenceType inferredType, StaticContext context, @@ -1906,16 +1958,16 @@ public void checkVariableType( context.replaceVariableSequenceType(variableName, inferredType); } else { if (!inferredType.isSubtypeOf(declaredType)) { - throw new UnexpectedStaticTypeException( - "In a " - + nodeName - + ", the variable $" - + variableName - + " inferred type " - + inferredType - + " does not match or can be promoted to the declared type " - + declaredType, - metadata + throwStaticTypeException( + "In a " + + nodeName + + ", the variable $" + + variableName + + " inferred type " + + inferredType + + " does not match or can be promoted to the declared type " + + declaredType, + metadata ); } } @@ -1925,10 +1977,15 @@ public void checkVariableType( public StaticContext visitVariableDeclaration(VariableDeclaration expression, StaticContext argument) { visitDescendants(expression, argument); SequenceType declaredType = expression.getActualSequenceType(); - SequenceType inferredType = (declaredType == null - ? expression.getExpression() - : ((TreatExpression) expression.getExpression()).getMainExpression()).getInferredSequenceType(); - checkVariableType( + SequenceType inferredType = SequenceType.ITEM_STAR; + if (declaredType == null) { + if (expression.getExpression() != null) { + inferredType = expression.getExpression().getStaticSequenceType(); + } + } else { + inferredType = declaredType; + } + checkAndUpdateVariableStaticType( declaredType, inferredType, argument, @@ -1943,29 +2000,49 @@ public StaticContext visitVariableDeclaration(VariableDeclaration expression, St @Override public StaticContext visitFunctionDeclaration(FunctionDeclaration expression, StaticContext argument) { visitDescendants(expression, argument); - InlineFunctionExpression inlineExpression = (InlineFunctionExpression) expression.getExpression(); - SequenceType inferredType = inlineExpression.getBody().getInferredSequenceType(); + SequenceType inferredType = inlineExpression.getBody().getStaticSequenceType(); SequenceType expectedType = inlineExpression.getActualReturnType(); if (expectedType == null) { expectedType = inferredType; } else if (!inferredType.isSubtypeOfOrCanBePromotedTo(expectedType)) { - throw new UnexpectedStaticTypeException( - "The declared function return inferred type " - + inferredType - + " does not match or can be promoted to the expected return type " - + expectedType, - expression.getMetadata() + throwStaticTypeException( + "The declared function return inferred type " + + inferredType + + " does not match or can be promoted to the expected return type " + + expectedType, + expression.getMetadata() ); } - // add function signature to the statically known one - argument.addFunctionSignature( - inlineExpression.getFunctionIdentifier(), - new FunctionSignature(new ArrayList(inlineExpression.getParams().values()), expectedType) - ); + return argument; + } + @Override + public StaticContext visitMainModule(MainModule mainModule, StaticContext argument) { + StaticContext generatedContext = visitDescendants(mainModule, mainModule.getStaticContext()); + return generatedContext; + } + + @Override + public StaticContext visitLibraryModule(LibraryModule libraryModule, StaticContext argument) { + visitDescendants(libraryModule, libraryModule.getStaticContext()); + return argument; + } + + @Override + public StaticContext visitProlog(Prolog prolog, StaticContext argument) { + for (Node child : prolog.getChildren()) { + visit(child, argument); + } + return argument; + } + + @Override + public StaticContext visitValidateTypeExpression(ValidateTypeExpression expression, StaticContext argument) { + visitDescendants(expression, expression.getStaticContext()); + expression.setStaticSequenceType(expression.getSequenceType()); return argument; } diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index 3d95657546..be20f6851a 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -22,18 +22,14 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.Map.Entry; -import org.rumbledb.context.BuiltinFunctionCatalogue; -import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.UndeclaredVariableException; -import org.rumbledb.exceptions.VariableAlreadyExistsException; import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; import org.rumbledb.expressions.control.TypeSwitchExpression; @@ -48,36 +44,36 @@ import org.rumbledb.expressions.module.FunctionDeclaration; import org.rumbledb.expressions.module.LibraryModule; import org.rumbledb.expressions.module.MainModule; +import org.rumbledb.expressions.module.Prolog; +import org.rumbledb.expressions.module.TypeDeclaration; import org.rumbledb.expressions.module.VariableDeclaration; -import org.rumbledb.expressions.primary.FunctionCallExpression; import org.rumbledb.expressions.primary.InlineFunctionExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; +import org.rumbledb.expressions.typing.CastExpression; +import org.rumbledb.expressions.typing.CastableExpression; +import org.rumbledb.expressions.typing.InstanceOfExpression; +import org.rumbledb.expressions.typing.TreatExpression; +import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.FunctionSignature; +import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; -import org.rumbledb.types.SequenceType.Arity; /** * Static context visitor implements a multi-pass algorithm that enables function hoisting */ public class StaticContextVisitor extends AbstractNodeVisitor { - private VisitorConfig visitorConfig; private Map importedModuleContexts; StaticContextVisitor() { - this.visitorConfig = VisitorConfig.staticContextVisitorInitialPassConfig; this.importedModuleContexts = new HashMap<>(); } - void setVisitorConfig(VisitorConfig visitorConfig) { - this.visitorConfig = visitorConfig; - } - @Override protected StaticContext defaultAction(Node node, StaticContext argument) { StaticContext generatedContext = visitDescendants(node, argument); // initialize execution mode by visiting children and expressions first, then calling initialize methods - node.initHighestExecutionMode(this.visitorConfig); return generatedContext; } @@ -99,7 +95,6 @@ public StaticContext visit(Node node, StaticContext argument) { public StaticContext visitMainModule(MainModule mainModule, StaticContext argument) { this.importedModuleContexts.clear(); StaticContext generatedContext = visitDescendants(mainModule, argument); - mainModule.initHighestExecutionMode(this.visitorConfig); return generatedContext; } @@ -109,14 +104,16 @@ public StaticContext visitLibraryModule(LibraryModule libraryModule, StaticConte StaticContext moduleContext = libraryModule.getStaticContext(); this.visit(libraryModule.getProlog(), moduleContext); this.importedModuleContexts.put(libraryModule.getNamespace(), moduleContext); - } else { - libraryModule.getProlog().initHighestExecutionMode(this.visitorConfig); } - libraryModule.initHighestExecutionMode(this.visitorConfig); argument.importModuleContext( this.importedModuleContexts.get(libraryModule.getNamespace()), libraryModule.getNamespace() ); + argument.getInScopeSchemaTypes() + .importModuleTypes( + this.importedModuleContexts.get(libraryModule.getNamespace()).getInScopeSchemaTypes(), + libraryModule.getNamespace() + ); return argument; } @@ -131,59 +128,45 @@ public StaticContext visitVariableReference(VariableReferenceExpression expressi ); } else { // note: sequence type can be null - expression.setType(argument.getVariableSequenceType(variableName)); - ExecutionMode mode = argument.getVariableStorageMode(variableName); - if (this.visitorConfig.setUnsetToLocal() && mode.equals(ExecutionMode.UNSET)) { - mode = ExecutionMode.LOCAL; - } - expression.setHighestExecutionMode(mode); - // TODO: check staticContext available + expression.setActualType(argument.getVariableSequenceType(variableName)); return argument; } } private void populateFunctionDeclarationStaticContext( StaticContext functionDeclarationContext, - List modes, InlineFunctionExpression expression ) { - int i = 0; for (Name name : expression.getParams().keySet()) { - ExecutionMode mode = modes.get(i); - SequenceType type = expression.getParams().get(name); - if (type.isEmptySequence()) { - mode = ExecutionMode.LOCAL; - } else if (type.getArity().equals(Arity.OneOrZero) || type.getArity().equals(Arity.One)) { - mode = ExecutionMode.LOCAL; - } functionDeclarationContext.addVariable( name, expression.getParams().get(name), - expression.getMetadata(), - mode + expression.getMetadata() ); - ++i; } } @Override public StaticContext visitFunctionDeclaration(FunctionDeclaration declaration, StaticContext argument) { InlineFunctionExpression expression = (InlineFunctionExpression) declaration.getExpression(); + if (expression.getActualReturnType() != null) { + expression.getActualReturnType().resolve(argument, declaration.getMetadata()); + } + for (Entry itemType : expression.getParams().entrySet()) { + itemType.getValue().resolve(argument, declaration.getMetadata()); + } // define a static context for the function body, add params to the context and visit the body expression - List modes = argument.getUserDefinedFunctionsExecutionModes() - .getParameterExecutionMode( - expression.getFunctionIdentifier(), - expression.getMetadata() - ); StaticContext functionDeclarationContext = new StaticContext(argument); - expression.setStaticContext(argument); - populateFunctionDeclarationStaticContext(functionDeclarationContext, modes, expression); + expression.setStaticContext(functionDeclarationContext); + populateFunctionDeclarationStaticContext(functionDeclarationContext, expression); // visit the body first to make its execution mode available while adding the function to the catalog this.visit(expression.getBody(), functionDeclarationContext); - expression.initHighestExecutionMode(this.visitorConfig); - declaration.initHighestExecutionMode(this.visitorConfig); - expression.registerUserDefinedFunctionExecutionMode( - this.visitorConfig + argument.addFunctionSignature( + expression.getFunctionIdentifier(), + new FunctionSignature( + new ArrayList<>(expression.getParams().values()), + expression.getReturnType() + ) ); return argument; } @@ -192,62 +175,29 @@ public StaticContext visitFunctionDeclaration(FunctionDeclaration declaration, S public StaticContext visitInlineFunctionExpr(InlineFunctionExpression expression, StaticContext argument) { // define a static context for the function body, add params to the context and visit the body expression StaticContext functionDeclarationContext = new StaticContext(argument); - expression.getParams() - .forEach( - (paramName, sequenceType) -> functionDeclarationContext.addVariable( - paramName, - sequenceType, - expression.getMetadata(), - ExecutionMode.LOCAL - ) + for (Entry entry : expression.getParams().entrySet()) { + functionDeclarationContext.addVariable( + entry.getKey(), + entry.getValue(), + expression.getMetadata() ); + } // visit the body first to make its execution mode available while adding the function to the catalog this.visit(expression.getBody(), functionDeclarationContext); - expression.initHighestExecutionMode(this.visitorConfig); - expression.registerUserDefinedFunctionExecutionMode( - this.visitorConfig - ); return functionDeclarationContext; } - @Override - public StaticContext visitFunctionCall(FunctionCallExpression expression, StaticContext argument) { - visitDescendants(expression, argument); - FunctionIdentifier identifier = expression.getFunctionIdentifier(); - if (!BuiltinFunctionCatalogue.exists(identifier)) { - List modes = new ArrayList<>(); - if (expression.isPartialApplication()) { - for (@SuppressWarnings("unused") - Expression parameter : expression.getArguments()) { - modes.add(ExecutionMode.LOCAL); - } - } else { - for (Expression parameter : expression.getArguments()) { - modes.add(parameter.getHighestExecutionMode(this.visitorConfig)); - } - } - argument.getUserDefinedFunctionsExecutionModes() - .setParameterExecutionMode( - identifier, - modes, - expression.getMetadata() - ); - } - expression.initFunctionCallHighestExecutionMode(this.visitorConfig); - return argument; - } // endregion // region FLWOR @Override public StaticContext visitFlowrExpression(FlworExpression expression, StaticContext argument) { Clause clause = expression.getReturnClause().getFirstClause(); - StaticContext result = this.visit(clause, argument); + StaticContext result = argument; while (clause != null) { result = this.visit(clause, result); clause = clause.getNextClause(); } - expression.initHighestExecutionMode(this.visitorConfig); return argument; } @@ -256,22 +206,20 @@ public StaticContext visitFlowrExpression(FlworExpression expression, StaticCont public StaticContext visitForClause(ForClause clause, StaticContext argument) { // TODO visit at... this.visit(clause.getExpression(), argument); - clause.initHighestExecutionMode(this.visitorConfig); StaticContext result = new StaticContext(argument); result.addVariable( clause.getVariableName(), clause.getActualSequenceType(), - clause.getMetadata(), - clause.getVariableHighestStorageMode(this.visitorConfig) + clause.getMetadata() ); + clause.getSequenceType().resolve(result, clause.getMetadata()); if (clause.getPositionalVariableName() != null) { result.addVariable( clause.getPositionalVariableName(), new SequenceType(BuiltinTypesCatalogue.integerItem), - clause.getMetadata(), - ExecutionMode.LOCAL + clause.getMetadata() ); } return result; @@ -280,15 +228,14 @@ public StaticContext visitForClause(ForClause clause, StaticContext argument) { @Override public StaticContext visitLetClause(LetClause clause, StaticContext argument) { this.visit(clause.getExpression(), argument); - clause.initHighestExecutionMode(this.visitorConfig); StaticContext result = new StaticContext(argument); result.addVariable( clause.getVariableName(), clause.getActualSequenceType(), - clause.getMetadata(), - clause.getVariableHighestStorageMode(this.visitorConfig) + clause.getMetadata() ); + clause.getSequenceType().resolve(result, clause.getMetadata()); return result; } @@ -303,8 +250,7 @@ public StaticContext visitGroupByClause(GroupByClause clause, StaticContext argu groupByClauseContext.addVariable( variable.getVariableName(), variable.getActualSequenceType(), - clause.getMetadata(), - ExecutionMode.LOCAL + clause.getMetadata() ); } else if (!argument.isInScope(variable.getVariableName())) { throw new UndeclaredVariableException( @@ -313,19 +259,16 @@ public StaticContext visitGroupByClause(GroupByClause clause, StaticContext argu ); } } - clause.initHighestExecutionMode(this.visitorConfig); return groupByClauseContext; } @Override public StaticContext visitCountClause(CountClause expression, StaticContext argument) { - expression.initHighestExecutionMode(this.visitorConfig); StaticContext result = new StaticContext(argument); result.addVariable( expression.getCountVariable().getVariableName(), new SequenceType(BuiltinTypesCatalogue.integerItem, SequenceType.Arity.One), - expression.getMetadata(), - ExecutionMode.LOCAL + expression.getMetadata() ); this.visit(expression.getCountVariable(), result); return result; @@ -344,11 +287,13 @@ public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, caseContext.addVariable( variableName, null, - expression.getMetadata(), - ExecutionMode.LOCAL + expression.getMetadata() ); } this.visit(c.getReturnExpression(), caseContext); + for (SequenceType sequenceType : c.getUnion()) { + sequenceType.resolve(argument, expression.getMetadata()); + } } Name defaultCaseVariableName = expression.getDefaultCase().getVariableName(); @@ -360,12 +305,10 @@ public StaticContext visitTypeSwitchExpression(TypeSwitchExpression expression, defaultCaseStaticContext.addVariable( defaultCaseVariableName, null, - expression.getMetadata(), - ExecutionMode.LOCAL + expression.getMetadata() ); this.visit(expression.getDefaultCase().getReturnExpression(), defaultCaseStaticContext); } - expression.initHighestExecutionMode(this.visitorConfig); // return the given context unchanged as defined variables go out of scope return argument; } @@ -376,23 +319,64 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar if (variableDeclaration.getExpression() != null) { this.visit(variableDeclaration.getExpression(), argument); } - variableDeclaration.initHighestExecutionMode(this.visitorConfig); - if (argument.hasVariable(variableDeclaration.getVariableName())) { - if (!this.visitorConfig.suppressErrorsForFunctionSignatureCollision()) { - throw new VariableAlreadyExistsException( - variableDeclaration.getVariableName(), - variableDeclaration.getMetadata() - ); - } - } else { - // first pass. - argument.addVariable( - variableDeclaration.getVariableName(), - variableDeclaration.getActualSequenceType(), - variableDeclaration.getMetadata(), - variableDeclaration.getVariableHighestStorageMode(this.visitorConfig) - ); + // first pass. + argument.addVariable( + variableDeclaration.getVariableName(), + variableDeclaration.getActualSequenceType(), + variableDeclaration.getMetadata() + ); + return argument; + } + + @Override + public StaticContext visitTypeDeclaration(TypeDeclaration declaration, StaticContext argument) { + ItemType type = declaration.getDefinition(); + // only first pass + argument.getInScopeSchemaTypes().addInScopeSchemaType(type, declaration.getMetadata()); + return argument; + } + + @Override + public StaticContext visitProlog(Prolog prolog, StaticContext argument) { + StaticContext generatedContext = visitDescendants(prolog, argument); + for (ItemType itemType : generatedContext.getInScopeSchemaTypes().getInScopeSchemaTypes()) { + itemType.resolve(generatedContext, prolog.getMetadata()); } + return generatedContext; + } + + @Override + public StaticContext visitValidateTypeExpression(ValidateTypeExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + expression.getSequenceType().resolve(argument, expression.getMetadata()); + return argument; + } + + @Override + public StaticContext visitCastExpression(CastExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + expression.getSequenceType().resolve(argument, expression.getMetadata()); + return argument; + } + + @Override + public StaticContext visitCastableExpression(CastableExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + expression.getSequenceType().resolve(argument, expression.getMetadata()); + return argument; + } + + @Override + public StaticContext visitTreatExpression(TreatExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + expression.getSequenceType().resolve(argument, expression.getMetadata()); + return argument; + } + + @Override + public StaticContext visitInstanceOfExpression(InstanceOfExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + expression.getSequenceType().resolve(argument, expression.getMetadata()); return argument; } diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index fdcfb10336..47d874e6f5 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -20,7 +20,7 @@ package org.rumbledb.compiler; -import static org.rumbledb.types.SequenceType.MOST_GENERAL_SEQUENCE_TYPE; +import static org.rumbledb.types.SequenceType.ITEM_STAR; import java.io.IOException; import java.math.BigDecimal; @@ -399,14 +399,14 @@ public Name parseName(JsoniqParser.QnameContext ctx, boolean isFunction, boolean @Override public Node visitFunctionDecl(JsoniqParser.FunctionDeclContext ctx) { Name name = parseName(ctx.qname(), true, false); - Map fnParams = new LinkedHashMap<>(); + LinkedHashMap fnParams = new LinkedHashMap<>(); SequenceType fnReturnType = null; Name paramName; SequenceType paramType; if (ctx.paramList() != null) { for (JsoniqParser.ParamContext param : ctx.paramList().param()) { paramName = parseName(param.qname(), false, false); - paramType = MOST_GENERAL_SEQUENCE_TYPE; + paramType = ITEM_STAR; if (fnParams.containsKey(paramName)) { throw new DuplicateParamNameException( name, @@ -417,7 +417,7 @@ public Node visitFunctionDecl(JsoniqParser.FunctionDeclContext ctx) { if (param.sequenceType() != null) { paramType = this.processSequenceType(param.sequenceType()); } else { - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; } fnParams.put(paramName, paramType); } @@ -470,7 +470,7 @@ public Node visitTypeDecl(JsoniqParser.TypeDeclContext ctx) { throw pe; } Name name = parseName(ctx.qname(), false, true); - ItemType type = ItemTypeFactory.createItemTypeFromJSoundCompactItem(name, definitionItem); + ItemType type = ItemTypeFactory.createItemTypeFromJSoundCompactItem(name, definitionItem, this.moduleContext); return new TypeDeclaration( type, createMetadataFromContext(ctx) @@ -1374,14 +1374,14 @@ public Node visitNamedFunctionRef(JsoniqParser.NamedFunctionRefContext ctx) { @Override public Node visitInlineFunctionExpr(JsoniqParser.InlineFunctionExprContext ctx) { - Map fnParams = new LinkedHashMap<>(); - SequenceType fnReturnType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + LinkedHashMap fnParams = new LinkedHashMap<>(); + SequenceType fnReturnType = SequenceType.ITEM_STAR; Name paramName; SequenceType paramType; if (ctx.paramList() != null) { for (JsoniqParser.ParamContext param : ctx.paramList().param()) { paramName = parseName(param.qname(), false, false); - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; if (fnParams.containsKey(paramName)) { throw new DuplicateParamNameException( Name.createVariableInDefaultFunctionNamespace("inline-function`"), @@ -1392,7 +1392,7 @@ public Node visitInlineFunctionExpr(JsoniqParser.InlineFunctionExprContext ctx) if (param.sequenceType() != null) { paramType = this.processSequenceType(param.sequenceType()); } else { - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; } fnParams.put(paramName, paramType); } diff --git a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java index 51f3134f70..21554015bd 100644 --- a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java +++ b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java @@ -55,10 +55,8 @@ private static void pruneModules(Node node, RumbleRuntimeConfiguration conf) { } private static void inferTypes(Module module, RumbleRuntimeConfiguration conf) { - System.out.println("* Starting type inference *"); new InferTypeVisitor(conf).visit(module, module.getStaticContext()); - System.out.println("* Completed type inference *"); - if (conf.printInferredTypes()) { + if (conf.printInferredTypes() || conf.isPrintIteratorTree()) { printTree(module, conf); } } @@ -141,9 +139,8 @@ public static MainModule parseJSONiqMainModule( pruneModules(mainModule, configuration); resolveDependencies(mainModule, configuration); populateStaticContext(mainModule, configuration); - if (configuration.doStaticAnalysis()) { - inferTypes(mainModule, configuration); - } + inferTypes(mainModule, configuration); + populateExecutionModes(mainModule, configuration); return mainModule; } catch (ParseCancellationException ex) { ParsingException e = new ParsingException( @@ -182,9 +179,8 @@ public static MainModule parseXQueryMainModule( pruneModules(mainModule, configuration); resolveDependencies(mainModule, configuration); populateStaticContext(mainModule, configuration); - if (configuration.doStaticAnalysis()) { - inferTypes(mainModule, configuration); - } + inferTypes(mainModule, configuration); + populateExecutionModes(mainModule, configuration); return mainModule; } catch (ParseCancellationException ex) { ParsingException e = new ParsingException( @@ -298,11 +294,11 @@ public static LibraryModule parseXQueryLibraryModule( } } - private static void populateStaticContext(Module module, RumbleRuntimeConfiguration conf) { + private static void populateExecutionModes(Module module, RumbleRuntimeConfiguration conf) { if (conf.isPrintIteratorTree()) { printTree(module, conf); } - StaticContextVisitor visitor = new StaticContextVisitor(); + ExecutionModeVisitor visitor = new ExecutionModeVisitor(); visitor.visit(module, module.getStaticContext()); @@ -351,6 +347,18 @@ private static void populateStaticContext(Module module, RumbleRuntimeConfigurat } + private static void populateStaticContext(Module module, RumbleRuntimeConfiguration conf) { + if (conf.isPrintIteratorTree()) { + printTree(module, conf); + } + StaticContextVisitor visitor = new StaticContextVisitor(); + visitor.visit(module, module.getStaticContext()); + + if (conf.isPrintIteratorTree()) { + printTree(module, conf); + } + } + public static DynamicContext createDynamicContext(Node node, RumbleRuntimeConfiguration configuration) { DynamicContextVisitor visitor = new DynamicContextVisitor(configuration); return visitor.visit(node, null); diff --git a/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java b/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java index c5bf1b20b3..78143f439b 100644 --- a/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java @@ -42,7 +42,7 @@ import java.net.URI; import java.util.*; -import static org.rumbledb.types.SequenceType.MOST_GENERAL_SEQUENCE_TYPE; +import static org.rumbledb.types.SequenceType.ITEM_STAR; public class XQueryTranslationVisitor extends org.rumbledb.parser.XQueryParserBaseVisitor { private StaticContext moduleContext; @@ -319,7 +319,7 @@ public Node visitVarDecl(XQueryParser.VarDeclContext ctx) { if (ctx.typeDeclaration() != null) { seq = this.processSequenceType(ctx.typeDeclaration().sequenceType()); } else { - seq = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + seq = SequenceType.ITEM_STAR; } XQueryParser.ExprSingleContext exprSingle = null; @@ -335,7 +335,7 @@ public Node visitVarDecl(XQueryParser.VarDeclContext ctx) { } if (exprSingle != null) { expr = (Expression) this.visitExprSingle(exprSingle); - if (!seq.equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (!seq.equals(SequenceType.ITEM_STAR)) { expr = new TreatExpression(expr, seq, ErrorCode.UnexpectedTypeErrorCode, expr.getMetadata()); } } @@ -375,8 +375,8 @@ private void processAnnotations(XQueryParser.AnnotationsContext annotations) { @Override public Node visitFunctionDecl(XQueryParser.FunctionDeclContext ctx) { Name name = parseName(ctx.eqName(), true, false); - Map fnParams = new LinkedHashMap<>(); - SequenceType fnReturnType = MOST_GENERAL_SEQUENCE_TYPE; + LinkedHashMap fnParams = new LinkedHashMap<>(); + SequenceType fnReturnType = ITEM_STAR; Name paramName; SequenceType paramType; @@ -387,7 +387,7 @@ public Node visitFunctionDecl(XQueryParser.FunctionDeclContext ctx) { if (ctx.functionParams() != null) { for (XQueryParser.FunctionParamContext param : ctx.functionParams().functionParam()) { paramName = parseName(param.qName(), false, false); - paramType = MOST_GENERAL_SEQUENCE_TYPE; + paramType = ITEM_STAR; if (fnParams.containsKey(paramName)) { throw new DuplicateParamNameException( name, @@ -398,7 +398,7 @@ public Node visitFunctionDecl(XQueryParser.FunctionDeclContext ctx) { if (param.typeDeclaration() != null) { paramType = this.processSequenceType(param.typeDeclaration().sequenceType()); } else { - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; } fnParams.put(paramName, paramType); } @@ -407,7 +407,7 @@ public Node visitFunctionDecl(XQueryParser.FunctionDeclContext ctx) { if (ctx.functionReturn() != null) { fnReturnType = this.processSequenceType(ctx.functionReturn().sequenceType()); } else { - fnReturnType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + fnReturnType = SequenceType.ITEM_STAR; } Expression bodyExpression = null; @@ -1283,15 +1283,15 @@ public Node visitNamedFunctionRef(XQueryParser.NamedFunctionRefContext ctx) { @Override public Node visitInlineFunctionRef(XQueryParser.InlineFunctionRefContext ctx) { - Map fnParams = new LinkedHashMap<>(); - SequenceType fnReturnType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + LinkedHashMap fnParams = new LinkedHashMap<>(); + SequenceType fnReturnType = SequenceType.ITEM_STAR; Name paramName; SequenceType paramType; if (ctx.functionParams() != null) { for (XQueryParser.FunctionParamContext param : ctx.functionParams().functionParam()) { // TODO here we have qname instead eqName paramName = parseName(param.name, false, false); - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; if (fnParams.containsKey(paramName)) { throw new DuplicateParamNameException( Name.createVariableInDefaultFunctionNamespace("inline-function`"), @@ -1302,7 +1302,7 @@ public Node visitInlineFunctionRef(XQueryParser.InlineFunctionRefContext ctx) { if (param.type.sequenceType() != null) { paramType = this.processSequenceType(param.type.sequenceType()); } else { - paramType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + paramType = SequenceType.ITEM_STAR; } fnParams.put(paramName, paramType); } @@ -1411,7 +1411,7 @@ public Node visitForBinding(XQueryParser.ForBindingContext ctx) { if (ctx.seq != null) { seq = this.processSequenceType(ctx.seq.sequenceType()); } else { - seq = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + seq = SequenceType.ITEM_STAR; } emptyFlag = (ctx.flag != null); Name atVar = null; @@ -1432,7 +1432,7 @@ public Node visitForBinding(XQueryParser.ForBindingContext ctx) { seq.getItemType(), SequenceType.Arity.ZeroOrMore ); - if (!expressionType.equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (!expressionType.equals(SequenceType.ITEM_STAR)) { expr = new TreatExpression(expr, expressionType, ErrorCode.UnexpectedTypeErrorCode, expr.getMetadata()); } @@ -1461,11 +1461,11 @@ public Node visitLetBinding(XQueryParser.LetBindingContext ctx) { if (ctx.typeDeclaration() != null) { seq = this.processSequenceType(ctx.typeDeclaration().sequenceType()); } else { - seq = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + seq = SequenceType.ITEM_STAR; } Expression expr = (Expression) this.visitExprSingle(ctx.exprSingle()); - if (!seq.equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (!seq.equals(SequenceType.ITEM_STAR)) { expr = new TreatExpression(expr, seq, ErrorCode.UnexpectedTypeErrorCode, expr.getMetadata()); } @@ -1507,12 +1507,12 @@ public GroupByVariableDeclaration processGroupByVar(XQueryParser.GroupingSpecCon if (ctx.typeDeclaration() != null) { seq = this.processSequenceType(ctx.typeDeclaration().sequenceType()); } else { - seq = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + seq = SequenceType.ITEM_STAR; } if (ctx.exprSingle() != null) { expr = (Expression) this.visitExprSingle(ctx.exprSingle()); - if (!seq.equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (!seq.equals(SequenceType.ITEM_STAR)) { expr = new TreatExpression(expr, seq, ErrorCode.UnexpectedTypeErrorCode, expr.getMetadata()); } @@ -1620,7 +1620,7 @@ public Node visitQuantifiedExpr(XQueryParser.QuantifiedExprContext ctx) { if (currentVariable.typeDeclaration() != null) { sequenceType = this.processSequenceType(currentVariable.typeDeclaration().sequenceType()); } else { - sequenceType = SequenceType.MOST_GENERAL_SEQUENCE_TYPE; + sequenceType = SequenceType.ITEM_STAR; } varExpression = (Expression) this.visitExprSingle(currentVariable.exprSingle()); diff --git a/src/main/java/org/rumbledb/config/RumbleRuntimeConfiguration.java b/src/main/java/org/rumbledb/config/RumbleRuntimeConfiguration.java index 8a20b1b317..a700c724d7 100644 --- a/src/main/java/org/rumbledb/config/RumbleRuntimeConfiguration.java +++ b/src/main/java/org/rumbledb/config/RumbleRuntimeConfiguration.java @@ -322,27 +322,78 @@ public boolean isLocal() { @Override public String toString() { - String result = ""; - result += "Master: " - + SparkSessionManager.getInstance().getJavaSparkContext().getConf().get("spark.master") - + "\n" - + + StringBuffer sb = new StringBuffer(); + sb.append( + "App name: " + + SparkSessionManager.getInstance().getJavaSparkContext().getConf().get("spark.app.name", "(not set)") + + "\n" + ); + sb.append( + "Master: " + + SparkSessionManager.getInstance().getJavaSparkContext().getConf().get("spark.master", "(not set)") + + "\n" + ); + sb.append( + "Driver's memory: " + + SparkSessionManager.getInstance() + .getJavaSparkContext() + .getConf() + .get("spark.driver.memory", "(not set)") + + "\n" + ); + sb.append( + "Number of executors (only applies if running on a cluster): " + + SparkSessionManager.getInstance() + .getJavaSparkContext() + .getConf() + .get("spark.executor.instances", "(not set)") + + "\n" + ); + sb.append( + "Cores per executor (only applies if running on a cluster): " + + SparkSessionManager.getInstance() + .getJavaSparkContext() + .getConf() + .get("spark.executor.cores", "(not set)") + + "\n" + ); + sb.append( + "Memory per executor (only applies if running on a cluster): " + + SparkSessionManager.getInstance() + .getJavaSparkContext() + .getConf() + .get("spark.executor.memory", "(not set)") + + "\n" + ); + sb.append( + "Dynamic allocation: " + + SparkSessionManager.getInstance() + .getJavaSparkContext() + .getConf() + .get("spark.dynamicAllocation.enabled", "(not set)") + + "\n" + ); + sb.append( "Item Display Limit: " - + getResultSizeCap() - + "\n" - + + + getResultSizeCap() + + "\n" + ); + sb.append( "Output Path: " - + (this.arguments.getOrDefault("output-path", "-")) - + "\n" - + + + (this.arguments.getOrDefault("output-path", "-")) + + "\n" + ); + sb.append( "Log Path: " - + (this.arguments.getOrDefault("log-path", "-")) - + "\n" - + + + (this.arguments.getOrDefault("log-path", "-")) + + "\n" + ); + sb.append( "Query Path : " - + (this.arguments.getOrDefault("query-path", "-")) - + "\n"; - return result; + + (this.arguments.getOrDefault("query-path", "-")) + + "\n" + ); + return sb.toString(); } @Override diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index d2b825030f..e340dafbb0 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -4,7 +4,6 @@ import java.util.Collections; import java.util.HashMap; -import org.rumbledb.exceptions.OurBadException; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.NullFunctionIterator; import org.rumbledb.runtime.functions.arrays.ArrayDescendantFunctionIterator; @@ -179,7 +178,7 @@ public static BuiltinFunction getBuiltinFunction(FunctionIdentifier identifier) return builtinFunctions.get(array); } } - throw new OurBadException("Unknown builtin function: " + identifier); + return null; } public static boolean exists(FunctionIdentifier identifier) { @@ -2298,7 +2297,23 @@ private static BuiltinFunction createBuiltinFunction( "get-transformer" ), "string", - "item", + "function(object*, object) as object*", + GetTransformerFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + + /** + * function fetches the transformer class from SparkML API + */ + static final BuiltinFunction get_transformer2 = createBuiltinFunction( + new Name( + Name.JN_NS, + "jn", + "get-transformer" + ), + "string", + "object", + "function(object*, object) as object*", GetTransformerFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -2313,7 +2328,23 @@ private static BuiltinFunction createBuiltinFunction( "get-estimator" ), "string", - "item", + "function(object*, object) as function(object*, object) as object*", + GetEstimatorFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + + /** + * function fetches the estimator class from SparkML API + */ + static final BuiltinFunction get_estimator2 = createBuiltinFunction( + new Name( + Name.JN_NS, + "jn", + "get-estimator" + ), + "string", + "object", + "function(object*, object) as function(object*, object) as object*", GetEstimatorFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -2327,9 +2358,9 @@ private static BuiltinFunction createBuiltinFunction( "jn", "annotate" ), - "item*", // TODO: revert back to ObjectItem when TypePromotionIter. has DF implementation + "object*", // TODO: revert back to ObjectItem when TypePromotionIter. has DF implementation "object", - "item*", // TODO: revert back to ObjectItem when TypePromotionIter. has DF implementation + "object*", // TODO: revert back to ObjectItem when TypePromotionIter. has DF implementation AnnotateFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.DATAFRAME ); @@ -2521,7 +2552,9 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(values.getIdentifier(), values); builtinFunctions.put(get_transformer.getIdentifier(), get_transformer); + builtinFunctions.put(get_transformer2.getIdentifier(), get_transformer2); builtinFunctions.put(get_estimator.getIdentifier(), get_estimator); + builtinFunctions.put(get_estimator2.getIdentifier(), get_estimator2); builtinFunctions.put(annotate.getIdentifier(), annotate); builtinFunctions.put(trace.getIdentifier(), trace); diff --git a/src/main/java/org/rumbledb/context/InScopeVariable.java b/src/main/java/org/rumbledb/context/InScopeVariable.java index 54d223131b..86f0e098a3 100644 --- a/src/main/java/org/rumbledb/context/InScopeVariable.java +++ b/src/main/java/org/rumbledb/context/InScopeVariable.java @@ -47,6 +47,10 @@ public ExecutionMode getStorageMode() { return this.storageMode; } + public void setStorageMode(ExecutionMode mode) { + this.storageMode = mode; + } + @Override public void write(Kryo kryo, Output output) { kryo.writeObject(output, this.name); diff --git a/src/main/java/org/rumbledb/context/Name.java b/src/main/java/org/rumbledb/context/Name.java index 0c25facff4..abfb635463 100644 --- a/src/main/java/org/rumbledb/context/Name.java +++ b/src/main/java/org/rumbledb/context/Name.java @@ -143,6 +143,30 @@ public static Name createVariableResolvingPrefix(String prefix, String localName } } + /** + * Creates an expanded name resolving the prefix from namespace bindings. + * + * @param prefixedName the QName literal. + * @param moduleContext the module context containing the bindings. + * @return the expanded name. + */ + public static Name createTypeNameFromLiteral(String prefixedName, StaticContext moduleContext) { + int pos = prefixedName.indexOf(":"); + String prefix = null; + String localName = prefixedName; + if (pos == -1) { + return new Name(JSONIQ_DEFAULT_TYPE_NS, prefix, localName); + } + prefix = prefixedName.substring(0, pos); + localName = prefixedName.substring(pos + 1); + String namespace = moduleContext.resolveNamespace(prefix); + if (namespace != null) { + return new Name(namespace, prefix, localName); + } else { + throw new OurBadException("Prefix " + prefix + " could not be resolved against a namespace in scope."); + } + } + /** * Converts the expanded name to an expanded name whose local name has a #n suffix, where n is the arity of the * function, diff --git a/src/main/java/org/rumbledb/context/NamedFunctions.java b/src/main/java/org/rumbledb/context/NamedFunctions.java index 5ac764d70a..6dd8bf242d 100644 --- a/src/main/java/org/rumbledb/context/NamedFunctions.java +++ b/src/main/java/org/rumbledb/context/NamedFunctions.java @@ -95,7 +95,7 @@ public static RuntimeIterator buildUserDefinedFunctionCallIterator( metadata ); SequenceType sequenceType = functionItem.getSignature().getReturnType(); - if (sequenceType.equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (sequenceType.equals(SequenceType.ITEM_STAR)) { return functionCallIterator; } if ( @@ -162,12 +162,15 @@ public static RuntimeIterator getBuiltInFunctionIterator( ExceptionMetadata metadata ) { BuiltinFunction builtinFunction = BuiltinFunctionCatalogue.getBuiltinFunction(identifier); + if (builtinFunction == null) { + throw new UnknownFunctionCallException(identifier.getName(), identifier.getArity(), metadata); + } for (int i = 0; i < arguments.size(); i++) { if ( !builtinFunction.getSignature() .getParameterTypes() .get(i) - .equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE) + .equals(SequenceType.ITEM_STAR) ) { SequenceType sequenceType = builtinFunction.getSignature().getParameterTypes().get(i); if ( @@ -215,7 +218,7 @@ public static RuntimeIterator getBuiltInFunctionIterator( ); } - if (!builtinFunction.getSignature().getReturnType().equals(SequenceType.MOST_GENERAL_SEQUENCE_TYPE)) { + if (!builtinFunction.getSignature().getReturnType().equals(SequenceType.ITEM_STAR)) { if (!checkReturnTypesOfBuiltinFunctions) { return functionCallIterator; } diff --git a/src/main/java/org/rumbledb/context/StaticContext.java b/src/main/java/org/rumbledb/context/StaticContext.java index 7069738b79..c02c9a1196 100644 --- a/src/main/java/org/rumbledb/context/StaticContext.java +++ b/src/main/java/org/rumbledb/context/StaticContext.java @@ -24,8 +24,10 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.SemanticException; +import org.rumbledb.exceptions.UnknownFunctionCallException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.types.FunctionSignature; +import org.rumbledb.types.ItemType; import org.rumbledb.types.SequenceType; import com.esotericsoftware.kryo.Kryo; @@ -37,6 +39,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; public class StaticContext implements Serializable, KryoSerializable { @@ -153,7 +156,7 @@ private InScopeVariable getInScopeVariable(Name varName) { } ancestor = ancestor.parent; } - throw new SemanticException("Variable " + varName + " not in scope", null); + throw new SemanticException("Variable " + varName + " not in scope", ExceptionMetadata.EMPTY_METADATA); } } @@ -168,7 +171,11 @@ public FunctionSignature getFunctionSignature(FunctionIdentifier identifier) { } ancestor = ancestor.parent; } - throw new SemanticException("function " + identifier + " not in scope", null); + throw new UnknownFunctionCallException( + identifier.getName(), + identifier.getArity(), + ExceptionMetadata.EMPTY_METADATA + ); } } @@ -193,29 +200,53 @@ public ExecutionMode getVariableStorageMode(Name varName) { return getInScopeVariable(varName).getStorageMode(); } + public void setVariableStorageMode(Name varName, ExecutionMode mode) { + getInScopeVariable(varName).setStorageMode(mode); + } + public void addVariable( Name varName, SequenceType type, - ExceptionMetadata metadata, - ExecutionMode storageMode + ExceptionMetadata metadata ) { - this.inScopeVariables.put(varName, new InScopeVariable(varName, type, metadata, storageMode)); + this.inScopeVariables.put(varName, new InScopeVariable(varName, type, metadata, ExecutionMode.UNSET)); } public void addFunctionSignature(FunctionIdentifier identifier, FunctionSignature signature) { this.staticallyKnownFunctionSignatures.put(identifier, signature); } - protected Map getInScopeVariables() { + public Map getInScopeVariables() { return this.inScopeVariables; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("Static context with variables: "); - this.inScopeVariables.keySet().forEach(a -> stringBuilder.append(a)); - stringBuilder.append("\n"); + stringBuilder.append("Static context with variables:\n"); + for (Entry entry : this.inScopeVariables.entrySet()) { + stringBuilder.append(entry.getKey()); + stringBuilder.append(" as " + entry.getValue().getSequenceType()); + stringBuilder.append(" (namespace " + entry.getKey().getNamespace() + ")"); + stringBuilder.append(" | " + entry.getValue().getStorageMode()); + stringBuilder.append("\n"); + } + stringBuilder.append("Static context with user-defined functions:\n"); + for (Entry entry : this.staticallyKnownFunctionSignatures.entrySet()) { + stringBuilder.append(entry.getKey()); + stringBuilder.append(" as " + entry.getValue()); + stringBuilder.append(" (namespace " + entry.getKey().getName().getNamespace() + ")"); + stringBuilder.append("\n"); + } + if (this.inScopeSchemaTypes != null) { + stringBuilder.append("Static context with user-defined types:\n"); + for (ItemType itemType : this.inScopeSchemaTypes.getInScopeSchemaTypes()) { + stringBuilder.append(itemType.getName()); + stringBuilder.append(itemType.isResolved() ? " (resolved)" : " (unresolved)"); + stringBuilder.append("\n"); + } + stringBuilder.append("\n"); + } if (this.userDefinedFunctionExecutionModes != null) { stringBuilder.append(this.userDefinedFunctionExecutionModes.toString()); } @@ -288,6 +319,12 @@ public void importModuleContext(StaticContext moduleContext, String targetNamesp this.inScopeVariables.put(name, variable); } } + for (FunctionIdentifier fi : moduleContext.staticallyKnownFunctionSignatures.keySet()) { + if (fi.getName().getNamespace().contentEquals(targetNamespace)) { + FunctionSignature signature = moduleContext.staticallyKnownFunctionSignatures.get(fi); + this.staticallyKnownFunctionSignatures.put(fi, signature); + } + } } public void setUserDefinedFunctionsExecutionModes( @@ -354,13 +391,13 @@ public void incrementArities(StaticContext stopContext, Set varToExclude) ); StaticContext current = this.parent; while (current != null && current != stopContext) { + System.err.println("Next loop: " + current); for (Map.Entry entry : current.inScopeVariables.entrySet()) { if (!this.inScopeVariables.containsKey(entry.getKey())) { this.addVariable( entry.getKey(), entry.getValue().getSequenceType().incrementArity(), - entry.getValue().getMetadata(), - entry.getValue().getStorageMode() + entry.getValue().getMetadata() ); } } diff --git a/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java b/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java index e5a6332997..d4401e2b3d 100644 --- a/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java +++ b/src/main/java/org/rumbledb/exceptions/ExceptionMetadata.java @@ -42,6 +42,7 @@ public class ExceptionMetadata implements Serializable { * @param location the URI of the JSONiq module at which the exception occurred. * @param line the line number at which the error occurred. * @param column the column number at which the error occurred. + * @param code the query code around the error. */ public ExceptionMetadata(String location, int line, int column, String code) { this.location = location; @@ -78,9 +79,9 @@ public String getLocation() { } /** - * Returns the column number. + * Returns the the query code around the error. * - * @return the column number. + * @return the the query code around the error. */ public String getCode() { return this.code; diff --git a/src/main/java/org/rumbledb/exceptions/InvalidRumbleMLParamException.java b/src/main/java/org/rumbledb/exceptions/InvalidRumbleMLParamException.java index 5b42aede50..b8e16355f4 100644 --- a/src/main/java/org/rumbledb/exceptions/InvalidRumbleMLParamException.java +++ b/src/main/java/org/rumbledb/exceptions/InvalidRumbleMLParamException.java @@ -26,11 +26,18 @@ public class InvalidRumbleMLParamException extends RumbleException { private static final long serialVersionUID = 1L; + String message; + public InvalidRumbleMLParamException(String message, ExceptionMetadata metadata) { super( "Invalid Param; " + message, ErrorCode.InvalidRumbleMLParamErrorCode, metadata ); + this.message = message; + } + + public String getMLMessage() { + return this.message; } } diff --git a/src/main/java/org/rumbledb/exceptions/RumbleException.java b/src/main/java/org/rumbledb/exceptions/RumbleException.java index 3f5b4d66fd..fe2772adb0 100644 --- a/src/main/java/org/rumbledb/exceptions/RumbleException.java +++ b/src/main/java/org/rumbledb/exceptions/RumbleException.java @@ -123,6 +123,10 @@ public ExceptionMetadata getMetadata() { return this.metadata; } + public void setMetadata(ExceptionMetadata metadata) { + this.metadata = metadata; + } + public String getJSONiqErrorMessage() { return this.errorMessage; } diff --git a/src/main/java/org/rumbledb/exceptions/UnknownFunctionCallException.java b/src/main/java/org/rumbledb/exceptions/UnknownFunctionCallException.java index 0c0e150641..aa8e889c05 100644 --- a/src/main/java/org/rumbledb/exceptions/UnknownFunctionCallException.java +++ b/src/main/java/org/rumbledb/exceptions/UnknownFunctionCallException.java @@ -20,6 +20,7 @@ package org.rumbledb.exceptions; +import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; import org.rumbledb.errorcodes.ErrorCode; @@ -39,4 +40,17 @@ public UnknownFunctionCallException(Name fnName, int arity, ExceptionMetadata me metadata ); } + + public UnknownFunctionCallException(FunctionIdentifier identifier, ExceptionMetadata metadata) { + super( + "Undefined function call; Entered function name and arity doesn't match a defined function signature: \"" + + + identifier.getName() + + "\" called with " + + identifier.getArity() + + " parameters.", + ErrorCode.InvalidFunctionCallErrorCode, + metadata + ); + } } diff --git a/src/main/java/org/rumbledb/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index 9cc6c5529d..6ba0e8a19c 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -23,6 +23,7 @@ import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.types.SequenceType; +import org.rumbledb.types.SequenceType.Arity; /** * An expression is the first-class citizen in JSONiq syntax. Any expression @@ -38,7 +39,7 @@ public abstract class Expression extends Node { protected StaticContext staticContext; - protected SequenceType inferredSequenceType; + protected SequenceType staticSequenceType; protected Expression(ExceptionMetadata metadata) { super(metadata); @@ -68,18 +69,32 @@ public void setStaticContext(StaticContext staticContext) { * * @return the statically inferred sequence type. */ - public SequenceType getInferredSequenceType() { - return this.inferredSequenceType; + public SequenceType getStaticSequenceType() { + return this.staticSequenceType; + } + + /** + * Tells whether this expression is guaranteed to return + * zero or one item but not more. + * + * @return true if yes, false otherwise. + */ + public boolean alwaysReturnsAtMostOneItem() { + return this.staticSequenceType.getArity().equals(Arity.One) + || + this.staticSequenceType.getArity().equals(Arity.OneOrZero) + || + this.staticSequenceType.getArity().equals(Arity.Zero); } /** * Sets the inferred static type, for used by the static * analysis visitor. * - * @param inferredSequenceType the statically inferred sequence type to set. + * @param staticSequenceType the statically inferred sequence type to set. */ - public void setInferredSequenceType(SequenceType inferredSequenceType) { - this.inferredSequenceType = inferredSequenceType; + public void setStaticSequenceType(SequenceType staticSequenceType) { + this.staticSequenceType = staticSequenceType; } @Override @@ -89,7 +104,13 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/Node.java b/src/main/java/org/rumbledb/expressions/Node.java index 4105b8b561..6b562ad668 100644 --- a/src/main/java/org/rumbledb/expressions/Node.java +++ b/src/main/java/org/rumbledb/expressions/Node.java @@ -53,12 +53,28 @@ protected Node(ExceptionMetadata metadata) { * overridden by subclasses that support higher execution modes. By * default, the highest execution mode is assumed to be local. * + * This method is deprecated as the logic of execution mode + * initialization is being moved to the ExecutionModeVisitor + * which invokes setHighestExecutionMode. + * * @param visitorConfig the configuration of the visitor. */ public void initHighestExecutionMode(VisitorConfig visitorConfig) { this.highestExecutionMode = ExecutionMode.LOCAL; } + /** + * Initializes the highest execution mode of this node, which determines + * whether evaluation will be done locally, with RDDs or with DataFrames. + * + * This method is used during the static analysis. It is meant to be + * overridden by subclasses that support higher execution modes. By + * default, the highest execution mode is assumed to be local. + */ + public final void setHighestExecutionMode(ExecutionMode newMode) { + this.highestExecutionMode = newMode; + } + /** * Gets the highest execution mode of this node, which determines * whether evaluation will be done locally, with RDDs or with DataFrames. diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java index c99b7c2f85..b8176dbb2b 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java @@ -75,7 +75,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.isMinus ? "-" : "+") + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java index 16423c5a59..5ea6859317 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java @@ -111,7 +111,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.multiplicativeOperator) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java index caaed0664d..cf5974b810 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java @@ -70,7 +70,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.negated ? "-" : "+") + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java b/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java index 4525c5d4a0..301953df28 100644 --- a/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java +++ b/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java @@ -151,7 +151,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.comparisonOperator) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/FlworExpression.java b/src/main/java/org/rumbledb/expressions/flowr/FlworExpression.java index f728b0a023..ce0797434a 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/FlworExpression.java +++ b/src/main/java/org/rumbledb/expressions/flowr/FlworExpression.java @@ -20,7 +20,6 @@ package org.rumbledb.expressions.flowr; -import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.SemanticException; import org.rumbledb.expressions.AbstractNodeVisitor; @@ -55,11 +54,6 @@ public ReturnClause getReturnClause() { return this.returnClause; } - @Override - public void initHighestExecutionMode(VisitorConfig visitorConfig) { - this.highestExecutionMode = this.returnClause.getHighestExecutionMode(visitorConfig); - } - public List getChildren() { return Collections.singletonList(this.returnClause); } diff --git a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java index 31a3373a17..435c0dadf1 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java @@ -132,6 +132,7 @@ public void print(StringBuffer buffer, int indent) { + (this.variableName) + ", " + this.getSequenceType().toString() + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + ", " + (this.allowingEmpty ? "allowing empty, " : "") + this.positionalVariableName diff --git a/src/main/java/org/rumbledb/expressions/flowr/GroupByVariableDeclaration.java b/src/main/java/org/rumbledb/expressions/flowr/GroupByVariableDeclaration.java index a9dd4e8c48..817cb406b3 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/GroupByVariableDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/flowr/GroupByVariableDeclaration.java @@ -52,7 +52,7 @@ public Expression getExpression() { } public SequenceType getSequenceType() { - return this.sequenceType == null ? SequenceType.MOST_GENERAL_SEQUENCE_TYPE : this.sequenceType; + return this.sequenceType == null ? SequenceType.ITEM_STAR : this.sequenceType; } public SequenceType getActualSequenceType() { diff --git a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java index 8be7d8545d..b548b22efb 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java @@ -63,7 +63,7 @@ public Name getVariableName() { } public SequenceType getSequenceType() { - return this.sequenceType == null ? SequenceType.MOST_GENERAL_SEQUENCE_TYPE : this.sequenceType; + return this.sequenceType == null ? SequenceType.ITEM_STAR : this.sequenceType; } public SequenceType getActualSequenceType() { @@ -114,7 +114,14 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.variableName) + ", " + this.getSequenceType().toString() + ") "); + buffer.append( + " (" + + (this.variableName) + + ", " + + this.getSequenceType().toString() + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); buffer.append("\n"); diff --git a/src/main/java/org/rumbledb/expressions/flowr/ReturnClause.java b/src/main/java/org/rumbledb/expressions/flowr/ReturnClause.java index 5753a05840..265eaa9ec3 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/ReturnClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/ReturnClause.java @@ -20,10 +20,8 @@ package org.rumbledb.expressions.flowr; -import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; @@ -44,23 +42,6 @@ public Expression getReturnExpr() { return this.returnExpr; } - @Override - public void initHighestExecutionMode(VisitorConfig visitorConfig) { - if (this.previousClause.getHighestExecutionMode(visitorConfig).isDataFrame()) { - this.highestExecutionMode = ExecutionMode.RDD; - return; - } - if (this.returnExpr.getHighestExecutionMode(visitorConfig).isRDD()) { - this.highestExecutionMode = ExecutionMode.RDD; - return; - } - if (this.returnExpr.getHighestExecutionMode(visitorConfig).isDataFrame()) { - this.highestExecutionMode = ExecutionMode.DATAFRAME; - return; - } - this.highestExecutionMode = ExecutionMode.LOCAL; - } - @Override public List getChildren() { List result = new ArrayList<>(); diff --git a/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java b/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java index 91ef9bc425..a9c8dd5c96 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java +++ b/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java @@ -66,7 +66,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (!)"); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java b/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java index 9a2d858cff..0b8f67be57 100644 --- a/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java @@ -70,7 +70,13 @@ public boolean external() { // return item* if sequenceType is [null] public SequenceType getSequenceType() { - return this.sequenceType == null ? SequenceType.MOST_GENERAL_SEQUENCE_TYPE : this.sequenceType; + if (this.sequenceType != null) { + return this.sequenceType; + } + if (this.expression != null && this.expression.getStaticSequenceType() != null) { + return this.expression.getStaticSequenceType(); + } + return SequenceType.ITEM_STAR; } // as above but does NOT default to item* diff --git a/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java b/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java index d2aa9cf11e..b77e5bd990 100644 --- a/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java +++ b/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java @@ -20,11 +20,15 @@ package org.rumbledb.expressions.postfix; +import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import org.rumbledb.types.SequenceType.Arity; + import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -82,11 +86,18 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); + this.mainExpression.print(buffer, indent + 1); for (Expression arg : this.arguments) { if (arg == null) { - for (int i = 0; i < indent; ++i) { + for (int i = 0; i < indent + 1; ++i) { buffer.append(" "); } buffer.append("?\n"); @@ -115,4 +126,20 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { } sb.append(")\n"); } + + @Override + public void initHighestExecutionMode(VisitorConfig visitorConfig) { + if (this.arguments.size() == 0) { + this.highestExecutionMode = ExecutionMode.LOCAL; + return; + } + if (this.getStaticSequenceType().getArity().equals(Arity.One)) { + this.highestExecutionMode = ExecutionMode.LOCAL; + return; + } + this.highestExecutionMode = this.arguments.get(0).getHighestExecutionMode(visitorConfig); + if (this.highestExecutionMode.equals(ExecutionMode.RDD)) { + this.highestExecutionMode = ExecutionMode.LOCAL; + } + } } diff --git a/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java index b276978f98..62ac22aea8 100644 --- a/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java @@ -59,7 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java index b1c7e35589..5d4eb39bad 100644 --- a/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java @@ -60,7 +60,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java index 3db15cc36a..0313eb5db7 100644 --- a/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java @@ -59,7 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java b/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java index ceb14792fc..1a497038fc 100644 --- a/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java @@ -95,6 +95,13 @@ public void initFunctionCallHighestExecutionMode(VisitorConfig visitorConfig) { ); } BuiltinFunction builtinFunction = BuiltinFunctionCatalogue.getBuiltinFunction(this.identifier); + if (builtinFunction == null) { + throw new UnknownFunctionCallException( + this.identifier.getName(), + this.identifier.getArity(), + this.getMetadata() + ); + } this.highestExecutionMode = this.getBuiltInFunctionExecutionMode(builtinFunction, visitorConfig); return; } @@ -173,11 +180,17 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Expression arg : this.arguments) { if (arg == null) { - for (int i = 0; i < indent; ++i) { + for (int i = 0; i < indent + 1; ++i) { buffer.append(" "); } buffer.append("?\n"); diff --git a/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java b/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java index e37f19c9dc..31964210ca 100644 --- a/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java @@ -70,7 +70,7 @@ public Map getParams() { } public SequenceType getReturnType() { - return this.returnType == null ? SequenceType.MOST_GENERAL_SEQUENCE_TYPE : this.returnType; + return this.returnType == null ? SequenceType.ITEM_STAR : this.returnType; } public SequenceType getActualReturnType() { @@ -116,13 +116,25 @@ public void print(StringBuffer buffer, int indent) { for (Map.Entry entry : this.params.entrySet()) { buffer.append(entry.getKey()); buffer.append(", "); - buffer.append(entry.getValue().toString()); + buffer.append( + entry.getValue().toString() + (entry.getValue().isResolved() ? " (resolved)" : " (unresolved)") + ); buffer.append(", "); } - buffer.append(this.returnType == null ? "not set" : this.returnType.toString()); + buffer.append( + this.returnType == null + ? "not set" + : this.returnType.toString() + (this.returnType.isResolved() ? " (resolved)" : " (unresolved)") + ); buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (int i = 0; i < indent + 2; ++i) { buffer.append(" "); diff --git a/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java index fcbf9a639f..bd906a343e 100644 --- a/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java @@ -59,7 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.lexicalValue) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/primary/NamedFunctionReferenceExpression.java b/src/main/java/org/rumbledb/expressions/primary/NamedFunctionReferenceExpression.java index b3342992c3..c9d7c89c11 100644 --- a/src/main/java/org/rumbledb/expressions/primary/NamedFunctionReferenceExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/NamedFunctionReferenceExpression.java @@ -60,7 +60,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" (" + this.identifier.getName() + "#" + this.identifier.getArity() + ") "); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); } diff --git a/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java index da81e29a81..86d7971592 100644 --- a/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java @@ -60,7 +60,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java b/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java index 5fd2ea8004..363a204896 100644 --- a/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java @@ -26,7 +26,6 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; import org.rumbledb.types.SequenceType; @@ -47,24 +46,20 @@ public VariableReferenceExpression(Name name, ExceptionMetadata metadata) { this.name = name; } - public void setHighestExecutionMode(ExecutionMode highestExecutionMode) { - this.highestExecutionMode = highestExecutionMode; - } - public Name getVariableName() { return this.name; } // default to item* if type is null public SequenceType getType() { - return this.type == null ? SequenceType.MOST_GENERAL_SEQUENCE_TYPE : this.type; + return this.type == null ? SequenceType.ITEM_STAR : this.type; } public SequenceType getActualType() { return this.type; } - public void setType(SequenceType type) { + public void setActualType(SequenceType type) { this.type = type; } @@ -92,7 +87,13 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" ($" + this.name + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/CastExpression.java b/src/main/java/org/rumbledb/expressions/typing/CastExpression.java index 6dd9e10bbe..b17d62cfb3 100644 --- a/src/main/java/org/rumbledb/expressions/typing/CastExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/CastExpression.java @@ -53,9 +53,20 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.sequenceType.toString()) + ") "); + buffer.append( + " (" + + (this.sequenceType.toString()) + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java b/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java index d790fa91cf..d2e05dfbed 100644 --- a/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java @@ -53,9 +53,14 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.sequenceType.toString()) + ") "); + buffer.append( + " (" + + (this.sequenceType.toString()) + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java b/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java index ef730359a8..0805f3dfe8 100644 --- a/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java @@ -72,9 +72,14 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.sequenceType.toString()) + ") "); + buffer.append( + " (" + + (this.sequenceType.toString()) + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java b/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java index cad37ad1d1..99b992642a 100644 --- a/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java @@ -52,7 +52,13 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.sequenceType.toString()) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java b/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java index 8d740040be..c7d7c4fd3e 100644 --- a/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java @@ -90,9 +90,14 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.sequenceType.toString()) + ") "); + buffer.append( + " (" + + (this.sequenceType.toString()) + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java index 85543b4965..6e69da76ed 100644 --- a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java @@ -54,9 +54,20 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" "); } buffer.append(getClass().getSimpleName()); - buffer.append(" (" + (this.sequenceType.toString()) + ") "); + buffer.append( + " (" + + (this.sequenceType.toString()) + + (this.getSequenceType().isResolved() ? " (resolved)" : " (unresolved)") + + ") " + ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + (this.inferredSequenceType == null ? "not set" : this.inferredSequenceType)); + buffer.append( + " | " + + (this.staticSequenceType == null + ? "not set" + : this.staticSequenceType + + (this.staticSequenceType.isResolved() ? " (resolved)" : " (unresolved)")) + ); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/items/FunctionItem.java b/src/main/java/org/rumbledb/items/FunctionItem.java index 5a219b04c6..83824fe9d7 100644 --- a/src/main/java/org/rumbledb/items/FunctionItem.java +++ b/src/main/java/org/rumbledb/items/FunctionItem.java @@ -31,6 +31,8 @@ import java.util.Map; import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.ml.Estimator; +import org.apache.spark.ml.Transformer; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.FunctionIdentifier; @@ -50,6 +52,9 @@ import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; +import sparksoniq.spark.ml.ApplyEstimatorRuntimeIterator; +import sparksoniq.spark.ml.ApplyTransformerRuntimeIterator; + public class FunctionItem implements Item { private static final long serialVersionUID = 1L; @@ -326,4 +331,32 @@ public void populateClosureFromDynamicContext(DynamicContext dynamicContext, Exc ); } } + + @Override + public boolean isEstimator() { + return this.bodyIterator instanceof ApplyEstimatorRuntimeIterator; + } + + @Override + public Estimator getEstimator() { + if (!isEstimator()) { + throw new OurBadException("This is not an estimator.", ExceptionMetadata.EMPTY_METADATA); + } + return ((ApplyEstimatorRuntimeIterator) this.bodyIterator).getEstimator(); + } + + @Override + public boolean isTransformer() { + return this.bodyIterator instanceof ApplyTransformerRuntimeIterator; + } + + @Override + public Transformer getTransformer() { + if (!isTransformer()) { + throw new OurBadException("This is not a transformer.", ExceptionMetadata.EMPTY_METADATA); + } + return ((ApplyTransformerRuntimeIterator) this.bodyIterator).getTransformer(); + } + + } diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java index 8d70dc2279..1ec498d348 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java @@ -413,7 +413,7 @@ public Dataset getDataFrameAsJoin( RuntimeIterator filteringPredicateIterator = new PredicateIterator( new VariableReferenceIterator( this.variableName, - SequenceType.MOST_GENERAL_SEQUENCE_TYPE, + SequenceType.ITEM_STAR, ExecutionMode.LOCAL, getMetadata() ), diff --git a/src/main/java/org/rumbledb/runtime/functions/DynamicFunctionCallIterator.java b/src/main/java/org/rumbledb/runtime/functions/DynamicFunctionCallIterator.java index ec07f74a5e..1fa5b6bae2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/DynamicFunctionCallIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/DynamicFunctionCallIterator.java @@ -20,20 +20,24 @@ package org.rumbledb.runtime.functions; +import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.NamedFunctions; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.InvalidRumbleMLParamException; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.MoreThanOneItemException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.runtime.LocalRuntimeIterator; +import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import java.util.List; -public class DynamicFunctionCallIterator extends LocalRuntimeIterator { +public class DynamicFunctionCallIterator extends HybridRuntimeIterator { // dynamic: functionIdentifier is not known at compile time // it is known only after evaluating postfix expression at runtime @@ -45,6 +49,7 @@ public class DynamicFunctionCallIterator extends LocalRuntimeIterator { // calculated fields private Item functionItem; private RuntimeIterator functionCallIterator; + private boolean isPartialApplication; private Item nextResult; public DynamicFunctionCallIterator( @@ -54,9 +59,12 @@ public DynamicFunctionCallIterator( ExceptionMetadata iteratorMetadata ) { super(null, executionMode, iteratorMetadata); + this.isPartialApplication = false; for (RuntimeIterator arg : functionArguments) { if (arg != null) { this.children.add(arg); + } else { + this.isPartialApplication = true; } } if (!this.children.contains(functionItemIterator)) { @@ -67,15 +75,24 @@ public DynamicFunctionCallIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - setFunctionItemAndIteratorWithCurrentContext(); - this.functionCallIterator.open(this.currentDynamicContextForLocalExecution); + public void openLocal() { + setFunctionItemAndIteratorWithCurrentContext(this.currentDynamicContextForLocalExecution); + try { + this.functionCallIterator.open(this.currentDynamicContextForLocalExecution); + } catch (InvalidRumbleMLParamException e) { + String m = e.getMLMessage(); + throw new InvalidRumbleMLParamException(m, getMetadata()); + } setNextResult(); } @Override - public Item next() { + protected boolean hasNextLocal() { + return this.hasNext; + } + + @Override + public Item nextLocal() { if (this.hasNext) { Item result = this.nextResult; setNextResult(); @@ -93,7 +110,12 @@ public Item next() { public void setNextResult() { this.nextResult = null; if (this.functionCallIterator.hasNext()) { - this.nextResult = this.functionCallIterator.next(); + try { + this.nextResult = this.functionCallIterator.next(); + } catch (InvalidRumbleMLParamException e) { + String m = e.getMLMessage(); + throw new InvalidRumbleMLParamException(m, getMetadata()); + } } if (this.nextResult == null) { @@ -103,45 +125,74 @@ public void setNextResult() { } } - private void setFunctionItemAndIteratorWithCurrentContext() { + private void setFunctionItemAndIteratorWithCurrentContext(DynamicContext context) { try { - this.functionItem = this.functionItemIterator.materializeAtMostOneItemOrNull( - this.currentDynamicContextForLocalExecution - ); + this.functionItem = this.functionItemIterator.materializeAtMostOneItemOrNull(context); } catch (MoreThanOneItemException e) { throw new UnexpectedTypeException( "A dynamic function call can not be performed on a sequence of more than one item.", getMetadata() ); } - if (this.functionItem == null && !this.functionItem.isFunction()) { + if (this.functionItem == null || !this.functionItem.isFunction()) { throw new UnexpectedTypeException( "Dynamic function calls can only be performed on functions.", getMetadata() ); } + if ( + this.functionItem.getBodyIterator().getHighestExecutionMode().equals(ExecutionMode.LOCAL) + && this.getHighestExecutionMode().equals(ExecutionMode.DATAFRAME) + ) { + throw new OurBadException( + "Execution mode mismatch in dynamic function call. At this point, Rumble only supports higher-order functions " + + "that are either machine learning models or estimators (which process validated and structured sequences of objects at any scale), or that take and return just one item at a time.", + getMetadata() + ); + } this.functionCallIterator = NamedFunctions.buildUserDefinedFunctionCallIterator( this.functionItem, - this.functionItem.getBodyIterator().getHighestExecutionMode(), + this.isPartialApplication + ? ExecutionMode.LOCAL + : this.functionItem.getBodyIterator().getHighestExecutionMode(), getMetadata(), this.functionArguments ); } @Override - public void reset(DynamicContext context) { - super.reset(context); + public void resetLocal() { this.functionCallIterator.reset(this.currentDynamicContextForLocalExecution); setNextResult(); } @Override - public void close() { + public void closeLocal() { // ensure that recursive function calls terminate gracefully // the function call in the body of the deepest recursion call is never visited, never opened and never closed if (this.isOpen) { this.functionCallIterator.close(); } - super.close(); + } + + protected boolean implementsDataFrames() { + return true; + } + + @Override + public JavaRDD getRDDAux(DynamicContext dynamicContext) { + setFunctionItemAndIteratorWithCurrentContext(dynamicContext); + return this.functionCallIterator.getRDD(dynamicContext); + } + + @Override + public JSoundDataFrame getDataFrame(DynamicContext dynamicContext) { + setFunctionItemAndIteratorWithCurrentContext(dynamicContext); + try { + return this.functionCallIterator.getDataFrame(dynamicContext); + } catch (InvalidRumbleMLParamException e) { + String m = e.getMLMessage(); + throw new InvalidRumbleMLParamException(m, getMetadata()); + } } } diff --git a/src/main/java/org/rumbledb/runtime/functions/FunctionItemCallIterator.java b/src/main/java/org/rumbledb/runtime/functions/FunctionItemCallIterator.java index 88241894dd..3816b736eb 100644 --- a/src/main/java/org/rumbledb/runtime/functions/FunctionItemCallIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/FunctionItemCallIterator.java @@ -41,7 +41,7 @@ import org.rumbledb.types.SequenceType; import org.rumbledb.types.SequenceType.Arity; -import static org.rumbledb.types.SequenceType.MOST_GENERAL_SEQUENCE_TYPE; +import static org.rumbledb.types.SequenceType.ITEM_STAR; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -124,7 +124,7 @@ private void wrapArgumentIteratorsWithTypeCheckingIterators() { && !this.functionItem.getSignature() .getParameterTypes() .get(i) - .equals(MOST_GENERAL_SEQUENCE_TYPE) + .equals(ITEM_STAR) ) { SequenceType sequenceType = this.functionItem.getSignature().getParameterTypes().get(i); ExecutionMode executionMode = this.functionArguments.get(i).getHighestExecutionMode(); diff --git a/src/main/java/org/rumbledb/types/ArrayItemType.java b/src/main/java/org/rumbledb/types/ArrayItemType.java index ae2a05e5f4..511b7267db 100644 --- a/src/main/java/org/rumbledb/types/ArrayItemType.java +++ b/src/main/java/org/rumbledb/types/ArrayItemType.java @@ -3,7 +3,9 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; import java.util.*; @@ -45,6 +47,9 @@ public class ArrayItemType implements ItemType { List enumeration ) { this.name = name; + if (baseType == null) { + throw new OurBadException("Unexpected error: baseType is null."); + } this.baseType = baseType; this.typeTreeDepth = baseType.getTypeTreeDepth() + 1; if (content == null) { @@ -62,7 +67,7 @@ public boolean equals(Object other) { if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) other).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -160,7 +165,10 @@ public String getIdentifierString() { @Override public String toString() { // consider add content and various stuff - return this.name.toString(); + return ((this.name == null) ? "" : this.name.toString()) + + "(array of " + + this.getArrayContentFacet().getType() + + ")"; } @Override @@ -175,6 +183,13 @@ public void resolve(DynamicContext context, ExceptionMetadata metadata) { } } + @Override + public void resolve(StaticContext context, ExceptionMetadata metadata) { + if (!this.content.getType().isResolved()) { + this.content.getType().resolve(context, metadata); + } + } + @Override public boolean isResolved() { return this.content.getType().isResolved(); diff --git a/src/main/java/org/rumbledb/types/AtomicItemType.java b/src/main/java/org/rumbledb/types/AtomicItemType.java index 99e865fb07..7f947a4676 100644 --- a/src/main/java/org/rumbledb/types/AtomicItemType.java +++ b/src/main/java/org/rumbledb/types/AtomicItemType.java @@ -231,7 +231,7 @@ public class AtomicItemType implements ItemType { public AtomicItemType() { } - private AtomicItemType(Name name, Set allowedFacets, DataType dataFrameType) { + AtomicItemType(Name name, Set allowedFacets, DataType dataFrameType) { this.name = name; this.allowedFacets = allowedFacets; this.dataFrameType = dataFrameType; @@ -242,7 +242,7 @@ public boolean equals(Object other) { if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) other).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -511,4 +511,9 @@ public DataType toDataFrameType() { public boolean isDataFrameType() { return true; } + + @Override + public boolean isResolved() { + return true; + } } diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 42418660c7..954ccef642 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -1,38 +1,287 @@ package org.rumbledb.types; +import org.apache.spark.sql.types.DataTypes; import org.rumbledb.context.Name; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.items.IntItem; +import org.rumbledb.items.IntegerItem; +import java.math.BigInteger; import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.List; public class BuiltinTypesCatalogue { - public static final ItemType item = ItemItemType.item; - public static final ItemType atomicItem = AtomicItemType.atomicItem; - public static final ItemType stringItem = AtomicItemType.stringItem; - public static final ItemType integerItem = DerivedAtomicItemType.integerItem; - public static final ItemType decimalItem = AtomicItemType.decimalItem; - public static final ItemType doubleItem = AtomicItemType.doubleItem; - public static final ItemType floatItem = AtomicItemType.floatItem; - public static final ItemType numericItem = AtomicItemType.numericItem; - public static final ItemType booleanItem = AtomicItemType.booleanItem; - public static final ItemType nullItem = AtomicItemType.nullItem; - public static final ItemType durationItem = AtomicItemType.durationItem; - public static final ItemType yearMonthDurationItem = AtomicItemType.yearMonthDurationItem; - public static final ItemType dayTimeDurationItem = AtomicItemType.dayTimeDurationItem; - public static final ItemType dateTimeItem = AtomicItemType.dateTimeItem; - public static final ItemType dateItem = AtomicItemType.dateItem; - public static final ItemType timeItem = AtomicItemType.timeItem; - public static final ItemType hexBinaryItem = AtomicItemType.hexBinaryItem; - public static final ItemType anyURIItem = AtomicItemType.anyURIItem; - public static final ItemType base64BinaryItem = AtomicItemType.base64BinaryItem; - public static final ItemType JSONItem = JsonItemType.jsonItem; - public static final ItemType objectItem = ObjectItemType.anyObjectItem; - public static final ItemType arrayItem = ArrayItemType.anyArrayItem; - public static final ItemType longItem = DerivedAtomicItemType.longItem; - public static final ItemType intItem = DerivedAtomicItemType.intItem; - public static final ItemType shortItem = DerivedAtomicItemType.shortItem; - public static final ItemType anyFunctionItem = FunctionItemType.anyFunctionItem; + public static final ItemType item = new ItemItemType(Name.createVariableInDefaultTypeNamespace("item")); + + public static final ItemType atomicItem = new AtomicItemType( + new Name(Name.JS_NS, "js", "atomic"), + Collections.emptySet(), + DataTypes.BinaryType + ); + public static final ItemType stringItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "string"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.LENGTH, + FacetTypes.MINLENGTH, + FacetTypes.MAXLENGTH + ) + ), + DataTypes.StringType + ); + + // numeric is an internal type for avoiding function overloading, it is not available in JSONiq + // it is the base type for xs:decimal, xs:double, and xs:float (those are now treated specially in type functions) + public static final ItemType numericItem = new AtomicItemType( + new Name(Name.JS_NS, "js", "numeric"), + Collections.emptySet(), + DataTypes.BinaryType // TODO: consider if specific type is needed + ); + + public static final ItemType decimalItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "decimal"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.TOTALDIGITS, + FacetTypes.FRACTIONDIGITS + ) + ), + DataTypes.createDecimalType() + ); + public static final ItemType doubleItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "double"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE + ) + ), + DataTypes.DoubleType + ); + public static final ItemType floatItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "float"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE + ) + ), + DataTypes.FloatType + ); + + public static final ItemType booleanItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "boolean"), + new HashSet<>(Arrays.asList(FacetTypes.ENUMERATION, FacetTypes.CONSTRAINTS)), + DataTypes.BooleanType + ); + public static final ItemType nullItem = new AtomicItemType( + new Name(Name.JS_NS, "js", "null"), + Collections.emptySet(), + DataTypes.NullType // TODO : see appropriate type + ); + public static final ItemType durationItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "duration"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE + ) + ), + DataTypes.BinaryType // TODO : appropriate datatype + ); + public static final ItemType yearMonthDurationItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "yearMonthDuration"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE + ) + ), + DataTypes.BinaryType // TODO : appropriate datatype + ); + public static final ItemType dayTimeDurationItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "dayTimeDuration"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE + ) + ), + DataTypes.BinaryType // TODO : appropriate datatype + ); + public static final ItemType dateTimeItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "dateTime"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); + public static final ItemType dateItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "date"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.TimestampType + ); + public static final ItemType timeItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "time"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.TimestampType + ); + public static final ItemType hexBinaryItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "hexBinary"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.LENGTH, + FacetTypes.MINLENGTH, + FacetTypes.MAXLENGTH + ) + ), + DataTypes.BinaryType + ); + public static final ItemType anyURIItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "anyURI"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.LENGTH, + FacetTypes.MINLENGTH, + FacetTypes.MAXLENGTH + ) + ), + DataTypes.StringType + ); + public static final ItemType base64BinaryItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "base64Binary"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.LENGTH, + FacetTypes.MINLENGTH, + FacetTypes.MAXLENGTH + ) + ), + DataTypes.BinaryType + ); + + public static final ItemType integerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "integer"), + AtomicItemType.decimalItem, + AtomicItemType.decimalItem, + Facets.getIntegerFacets(), + false, + DataTypes.createDecimalType() // TODO : how to support arbitrary-sized integer + ); + + public static final ItemType longItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "long"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("-9223372036854775808")), + new IntegerItem(new BigInteger("9223372036854775807")), + true + ), + false, + DataTypes.LongType // TODO : how to support arbitrary-sized integer + ); + + public static final ItemType intItem = new DerivedAtomicItemType( + Name.createVariableInDefaultTypeNamespace("int"), + longItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(-2147483648), new IntItem(2147483647), true), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + public static final ItemType shortItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "short"), + intItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(-32768), new IntItem(32767), true), + false, + DataTypes.ShortType // TODO : how to support arbitrary-sized integer + ); + + public static final ItemType JSONItem = new JsonItemType(); + public static final ItemType objectItem = new ObjectItemType( + new Name(Name.JS_NS, "js", "object"), + BuiltinTypesCatalogue.JSONItem, + false, + Collections.emptyMap(), + Collections.emptyList(), + null + ); + public static final ItemType arrayItem = new ArrayItemType( + new Name(Name.JS_NS, "js", "array"), + BuiltinTypesCatalogue.JSONItem, + null, + null, + null, + null + ); + public static final ItemType anyFunctionItem = new FunctionItemType(true); public static boolean typeExists(Name name) { for (ItemType builtInItemType : builtInItemTypes) { diff --git a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java index 36d4ab633d..ac40cfd644 100644 --- a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java +++ b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java @@ -72,7 +72,7 @@ public class DerivedAtomicItemType implements ItemType { } // TODO : turn builtin derived atomic types into this class - private DerivedAtomicItemType( + DerivedAtomicItemType( Name name, ItemType baseType, ItemType primitiveType, @@ -112,7 +112,7 @@ public boolean equals(Object other) { if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) other).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override diff --git a/src/main/java/org/rumbledb/types/FunctionItemType.java b/src/main/java/org/rumbledb/types/FunctionItemType.java index d14a4c7a76..3cd7f7abdd 100644 --- a/src/main/java/org/rumbledb/types/FunctionItemType.java +++ b/src/main/java/org/rumbledb/types/FunctionItemType.java @@ -1,5 +1,6 @@ package org.rumbledb.types; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.OurBadException; import java.util.Set; @@ -22,17 +23,22 @@ public class FunctionItemType implements ItemType { } // we have a parameter because the empty one is public and inherited - private FunctionItemType(boolean isGeneric) { + FunctionItemType(boolean isGeneric) { this.isGeneric = true; this.signature = null; } + @Override + public Name getName() { + return null; + } + @Override public boolean equals(Object other) { - if (!(other instanceof FunctionItemType)) { + if (!(other instanceof ItemType)) { return false; } - return this.toString().equals(other.toString()); + return isEqualTo((ItemType) other); } @Override @@ -52,6 +58,9 @@ public boolean isSubtypeOf(ItemType superType) { ) { return true; } + if (this.signature == null) { + return false; + } if (superType.isFunctionItemType() && this.signature.isSubtypeOf(superType.getSignature())) { return true; } diff --git a/src/main/java/org/rumbledb/types/ItemItemType.java b/src/main/java/org/rumbledb/types/ItemItemType.java index cedb5aeb07..84b9a241fa 100644 --- a/src/main/java/org/rumbledb/types/ItemItemType.java +++ b/src/main/java/org/rumbledb/types/ItemItemType.java @@ -19,16 +19,16 @@ public class ItemItemType implements ItemType { public ItemItemType() { } - private ItemItemType(Name name) { + ItemItemType(Name name) { this.name = name; } @Override - public boolean equals(Object o) { - if (!(o instanceof ItemType)) { + public boolean equals(Object other) { + if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) o).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -80,4 +80,9 @@ public DataType toDataFrameType() { public boolean isDataFrameType() { return false; } + + @Override + public boolean isResolved() { + return true; + } } diff --git a/src/main/java/org/rumbledb/types/ItemType.java b/src/main/java/org/rumbledb/types/ItemType.java index 3af43dd021..f9333fb05d 100644 --- a/src/main/java/org/rumbledb/types/ItemType.java +++ b/src/main/java/org/rumbledb/types/ItemType.java @@ -25,6 +25,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import java.io.Serializable; @@ -39,11 +40,30 @@ public interface ItemType extends Serializable { /** * Tests for itemType equality. * - * @param other another item type. + * @param other another object. * @return true it is equal to other, false otherwise. */ boolean equals(Object other); + + /** + * Tests for itemType equality. + * + * @param otherType another item type. + * @return true it is equal to other, false otherwise. + */ + default boolean isEqualTo(ItemType otherType) { + if (this instanceof FunctionItemType || otherType instanceof FunctionItemType) { + if (!(this instanceof FunctionItemType) || !(otherType instanceof FunctionItemType)) { + return false; + } + return this.toString().equals(otherType.toString()); + } + if (this.getName() == null || otherType.getName() == null) { + return this == otherType; + } + return this.getName().equals(otherType.getName()); + } // region kind /** @@ -393,7 +413,9 @@ default boolean getClosedFacet() { * @return content facet value for array item types */ default ArrayContentDescriptor getArrayContentFacet() { - throw new UnsupportedOperationException("array content facet is allowed only for array item types"); + throw new UnsupportedOperationException( + "array content facet is allowed only for array item types " + this.getClass().getCanonicalName() + ); } /** @@ -432,4 +454,8 @@ default boolean isResolved() { default void resolve(DynamicContext context, ExceptionMetadata metadata) { return; } + + default void resolve(StaticContext context, ExceptionMetadata metadata) { + return; + } } diff --git a/src/main/java/org/rumbledb/types/ItemTypeFactory.java b/src/main/java/org/rumbledb/types/ItemTypeFactory.java index f02314b455..d420c310b2 100644 --- a/src/main/java/org/rumbledb/types/ItemTypeFactory.java +++ b/src/main/java/org/rumbledb/types/ItemTypeFactory.java @@ -11,6 +11,7 @@ import org.apache.spark.sql.types.VarcharType; import org.rumbledb.api.Item; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidSchemaException; import org.rumbledb.exceptions.OurBadException; @@ -22,21 +23,20 @@ public class ItemTypeFactory { - public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item) { + public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item, StaticContext staticContext) { if (item.isString()) { String typeString = item.getStringValue(); if (typeString.contains("=")) { throw new InvalidSchemaException("= not supported yet", ExceptionMetadata.EMPTY_METADATA); } - Name typeName = Name.createVariableInDefaultTypeNamespace(typeString); - return new ItemTypeReference(typeName); + return new ItemTypeReference(Name.createTypeNameFromLiteral(typeString, staticContext)); } if (item.isArray()) { List members = item.getItems(); if (members.size() != 1) { throw new InvalidSchemaException("Invalid JSound: " + item, ExceptionMetadata.EMPTY_METADATA); } - ItemType memberType = createItemTypeFromJSoundCompactItem(null, members.get(0)); + ItemType memberType = createItemTypeFromJSoundCompactItem(null, members.get(0), staticContext); return new ArrayItemType( null, BuiltinTypesCatalogue.arrayItem, @@ -64,7 +64,7 @@ public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item) FieldDescriptor fieldDescriptor = new FieldDescriptor(); fieldDescriptor.setName(key); fieldDescriptor.setRequired(required); - fieldDescriptor.setType(createItemTypeFromJSoundCompactItem(null, value)); + fieldDescriptor.setType(createItemTypeFromJSoundCompactItem(null, value, staticContext)); fieldDescriptor.setUnique(false); fieldDescriptor.setDefaultValue(null); fields.put(key, fieldDescriptor); @@ -105,9 +105,6 @@ private static ItemType createItemTypeFromSparkStructType(StructType structType) ItemType mappedItemType; if (filedType instanceof StructType) { mappedItemType = createItemTypeFromSparkStructType((StructType) filedType); - } else if (filedType instanceof ArrayType) { - // TODO : add proper function - mappedItemType = BuiltinTypesCatalogue.arrayItem; } else { mappedItemType = createItemType(filedType); } diff --git a/src/main/java/org/rumbledb/types/ItemTypeReference.java b/src/main/java/org/rumbledb/types/ItemTypeReference.java index 1ef76128fa..8c0012bf09 100644 --- a/src/main/java/org/rumbledb/types/ItemTypeReference.java +++ b/src/main/java/org/rumbledb/types/ItemTypeReference.java @@ -4,6 +4,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.UndefinedTypeException; @@ -18,6 +19,9 @@ public class ItemTypeReference implements ItemType { private Name name; public ItemTypeReference(Name name) { + if (name == null) { + throw new OurBadException("A type name cannot be null!"); + } this.name = name; } @@ -35,6 +39,16 @@ public void resolve(DynamicContext context, ExceptionMetadata metadata) { } } + public void resolve(StaticContext context, ExceptionMetadata metadata) { + if (!context.getInScopeSchemaTypes().checkInScopeSchemaTypeExists(this.name)) { + throw new UndefinedTypeException("Type undefined: " + this.name, metadata); + } + this.resolvedItemType = context.getInScopeSchemaTypes().getInScopeSchemaType(this.name); + if (!this.resolvedItemType.isResolved()) { + this.resolvedItemType.resolve(context, metadata); + } + } + @Override public int getTypeTreeDepth() { if (this.resolvedItemType == null) { @@ -121,6 +135,9 @@ public boolean hasName() { public Name getName() { + if (this.resolvedItemType != null) { + return this.resolvedItemType.getName(); + } return this.name; } @@ -299,6 +316,13 @@ public String getIdentifierString() { return this.name.toString(); } + public String toString() { + if (!this.hasName()) { + return ""; + } + return this.name.toString(); + } + public DataType toDataFrameType() { if (this.resolvedItemType == null) { throw new OurBadException("Unresolved type: " + this.name); diff --git a/src/main/java/org/rumbledb/types/JsonItemType.java b/src/main/java/org/rumbledb/types/JsonItemType.java index f71ed7b559..17017aeb17 100644 --- a/src/main/java/org/rumbledb/types/JsonItemType.java +++ b/src/main/java/org/rumbledb/types/JsonItemType.java @@ -13,19 +13,19 @@ public class JsonItemType implements ItemType { private static final long serialVersionUID = 1L; - static final ItemType jsonItem = new JsonItemType(new Name(Name.JS_NS, "js", "json-item")); + static final ItemType jsonItem = new JsonItemType(); private final Name name; - private JsonItemType(Name name) { - this.name = name; + JsonItemType() { + this.name = new Name(Name.JS_NS, "js", "json-item"); } @Override - public boolean equals(Object o) { - if (!(o instanceof ItemType)) { + public boolean equals(Object other) { + if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) o).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -80,4 +80,9 @@ public DataType toDataFrameType() { public boolean isDataFrameType() { return false; } + + @Override + public boolean isResolved() { + return true; + } } diff --git a/src/main/java/org/rumbledb/types/ObjectItemType.java b/src/main/java/org/rumbledb/types/ObjectItemType.java index 39f39ae923..c6f22cd9ca 100644 --- a/src/main/java/org/rumbledb/types/ObjectItemType.java +++ b/src/main/java/org/rumbledb/types/ObjectItemType.java @@ -4,6 +4,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import java.util.*; @@ -60,7 +61,7 @@ public boolean equals(Object other) { if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) other).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -204,7 +205,7 @@ public String toString() { sb.append(" (object item)\n"); sb.append("base type : "); - sb.append(this.baseType.getIdentifierString()); + sb.append(this.baseType.toString()); sb.append("\n"); List fields = new ArrayList<>(this.getObjectContentFacet().values()); @@ -218,7 +219,7 @@ public String toString() { sb.append(" (required)"); } sb.append(" : "); - sb.append(field.getType().getIdentifierString()); + sb.append(field.getType().toString()); sb.append("\n"); } } @@ -243,6 +244,7 @@ public boolean isDataFrameType() { public boolean isResolved() { for (Map.Entry entry : this.content.entrySet()) { if (!entry.getValue().getType().isResolved()) { + System.err.println("Unresolved: " + entry.getValue().getType().getClass().getCanonicalName()); return false; } } @@ -257,4 +259,13 @@ public void resolve(DynamicContext context, ExceptionMetadata metadata) { } } } + + @Override + public void resolve(StaticContext context, ExceptionMetadata metadata) { + for (Map.Entry entry : this.content.entrySet()) { + if (!entry.getValue().getType().isResolved()) { + entry.getValue().getType().resolve(context, metadata); + } + } + } } diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index f60a40243c..28492073f9 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -21,21 +21,22 @@ package org.rumbledb.types; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import java.io.Serializable; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class SequenceType implements Serializable { private static final long serialVersionUID = 1L; - private Arity arity; private ItemType itemType; - private boolean isEmptySequence = false; + private Arity arity; - public final static SequenceType MOST_GENERAL_SEQUENCE_TYPE = new SequenceType( + public final static SequenceType ITEM_STAR = new SequenceType( BuiltinTypesCatalogue.item, Arity.ZeroOrMore ); @@ -44,55 +45,79 @@ public class SequenceType implements Serializable { public SequenceType(ItemType itemType, Arity arity) { + if (arity == Arity.Zero) { + this.itemType = BuiltinTypesCatalogue.item; + this.arity = Arity.Zero; + return; + } this.itemType = itemType; this.arity = arity; + if (this.itemType == null) { + System.err.println( + "[WARNING] Missing item type in incomplete sequence type " + + this.arity + + ", defaulting to item. Please let us know as we would like to look into this!" + ); + this.itemType = BuiltinTypesCatalogue.item; + } + if (this.arity == null) { + System.err.println( + "[WARNING] Missing arity in incomplete sequence type " + + this.itemType + + ", defaulting to *. Please let us know as we would like to look into this!" + ); + this.arity = Arity.ZeroOrMore; + } } public SequenceType(ItemType itemType) { this.itemType = itemType; this.arity = Arity.One; + if (this.itemType == null) { + throw new OurBadException("Missing item type in incomplete sequence type " + this.arity); + } } private SequenceType() { - this.itemType = null; - this.arity = null; - this.isEmptySequence = true; + this.itemType = BuiltinTypesCatalogue.item; + this.arity = Arity.Zero; } public boolean isResolved() { - if (this.isEmptySequence) { + if (isEmptySequence()) { return true; } return this.itemType.isResolved(); } public void resolve(DynamicContext context, ExceptionMetadata metadata) { - if (this.isEmptySequence) { + if (isEmptySequence()) { + return; + } + this.itemType.resolve(context, metadata); + } + + public void resolve(StaticContext context, ExceptionMetadata metadata) { + if (isEmptySequence()) { return; } this.itemType.resolve(context, metadata); } public boolean isEmptySequence() { - return this.isEmptySequence; + return this.arity == Arity.Zero; } public ItemType getItemType() { - if (this.isEmptySequence) { - throw new OurBadException("Empty sequence type has no item"); - } return this.itemType; } public Arity getArity() { - if (this.isEmptySequence) { - throw new OurBadException("Empty sequence type has no arity"); - } return this.arity; } public boolean isSubtypeOf(SequenceType superType) { - if (this.isEmptySequence) { + if (isEmptySequence()) { return superType.arity == Arity.OneOrZero || superType.arity == Arity.ZeroOrMore; } return this.itemType.isSubtypeOf(superType.getItemType()) @@ -102,7 +127,7 @@ public boolean isSubtypeOf(SequenceType superType) { // keep in consideration also automatic promotion of integer > decimal > double and anyURI > string public boolean isSubtypeOfOrCanBePromotedTo(SequenceType superType) { - if (this.isEmptySequence) { + if (isEmptySequence()) { return superType.arity == Arity.OneOrZero || superType.arity == Arity.ZeroOrMore; } return this.isAritySubtypeOf(superType.arity) @@ -118,7 +143,7 @@ public boolean isAritySubtypeOf(Arity superArity) { } public boolean hasEffectiveBooleanValue() { - if (this.isEmptySequence) { + if (isEmptySequence()) { return true; } else if (this.itemType.isSubtypeOf(BuiltinTypesCatalogue.JSONItem)) { return true; @@ -142,7 +167,7 @@ public boolean hasEffectiveBooleanValue() { public boolean hasOverlapWith(SequenceType other) { // types overlap if both itemType and Arity overlap, we also need to take care of empty sequence - if (this.isEmptySequence()) { + if (isEmptySequence()) { return other.isEmptySequence() || other.getArity() == Arity.OneOrZero || other.getArity() == Arity.ZeroOrMore; @@ -156,7 +181,7 @@ public boolean hasOverlapWith(SequenceType other) { } public SequenceType leastCommonSupertypeWith(SequenceType other) { - if (this.isEmptySequence) { + if (isEmptySequence()) { if (other.isEmptySequence()) { return this; } else { @@ -192,7 +217,7 @@ public SequenceType leastCommonSupertypeWith(SequenceType other) { // increment arity of a sequence type from ? to * and from 1 to +, leave others arity or sequence types untouched public SequenceType incrementArity() { - if (!this.isEmptySequence()) { + if (!isEmptySequence()) { if (this.arity == Arity.One) { return new SequenceType(this.getItemType(), Arity.OneOrMore); } else if (this.arity == Arity.OneOrZero) { @@ -208,7 +233,7 @@ public boolean equals(Object other) { return false; } SequenceType sequenceType = (SequenceType) other; - if (this.isEmptySequence) { + if (isEmptySequence()) { return sequenceType.isEmptySequence(); } if (sequenceType.isEmptySequence()) { @@ -241,11 +266,23 @@ public String getSymbol() { public String getSymbol() { return ""; } + }, + Zero { + @Override + public String getSymbol() { + return ""; + } }; public abstract String getSymbol(); public boolean isSubtypeOf(Arity superArity) { + if (superArity == Zero) { + return this == Arity.Zero; + } + if (this == Zero) { + return this == Arity.ZeroOrMore || this == Arity.OneOrZero; + } if (superArity == Arity.ZeroOrMore || superArity == this) return true; else @@ -253,6 +290,9 @@ public boolean isSubtypeOf(Arity superArity) { } public Arity multiplyWith(Arity other) { + if (this == Zero || other == Zero) { + return Zero; + } if (this == One && other == One) { return One; } else if (this.isSubtypeOf(OneOrZero) && other.isSubtypeOf(OneOrZero)) { @@ -268,7 +308,7 @@ public Arity multiplyWith(Arity other) { @Override public String toString() { - if (this.isEmptySequence) { + if (isEmptySequence()) { return "()"; } StringBuilder result = new StringBuilder(); @@ -388,6 +428,50 @@ public String toString() { ); sequenceTypes.put("null?", new SequenceType(BuiltinTypesCatalogue.nullItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put( + "function(object*, object) as object*", + new SequenceType( + ItemTypeFactory.createFunctionItemType( + new FunctionSignature( + Arrays.asList( + new SequenceType(BuiltinTypesCatalogue.objectItem, SequenceType.Arity.ZeroOrMore), + new SequenceType(BuiltinTypesCatalogue.objectItem) + ), + new SequenceType(BuiltinTypesCatalogue.objectItem, SequenceType.Arity.ZeroOrMore) + ) + ) + ) + ); + sequenceTypes.put( + "function(object*, object) as function(object*, object) as object*", + new SequenceType( + ItemTypeFactory.createFunctionItemType( + new FunctionSignature( + Arrays.asList( + new SequenceType(BuiltinTypesCatalogue.objectItem, SequenceType.Arity.ZeroOrMore), + new SequenceType(BuiltinTypesCatalogue.objectItem) + ), + new SequenceType( + ItemTypeFactory.createFunctionItemType( + new FunctionSignature( + Arrays.asList( + new SequenceType( + BuiltinTypesCatalogue.objectItem, + SequenceType.Arity.ZeroOrMore + ), + new SequenceType(BuiltinTypesCatalogue.objectItem) + ), + new SequenceType( + BuiltinTypesCatalogue.objectItem, + SequenceType.Arity.ZeroOrMore + ) + ) + ) + ) + ) + ) + ) + ); } public static SequenceType createSequenceType(String userFriendlyName) { diff --git a/src/main/java/org/rumbledb/types/UnionItemType.java b/src/main/java/org/rumbledb/types/UnionItemType.java index 013c90ac6f..1f66bf3925 100644 --- a/src/main/java/org/rumbledb/types/UnionItemType.java +++ b/src/main/java/org/rumbledb/types/UnionItemType.java @@ -4,6 +4,7 @@ import org.apache.spark.sql.types.DataTypes; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; +import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import java.util.Arrays; @@ -40,7 +41,7 @@ public boolean equals(Object other) { if (!(other instanceof ItemType)) { return false; } - return this.getIdentifierString().equals(((ItemType) other).getIdentifierString()); + return isEqualTo((ItemType) other); } @Override @@ -148,4 +149,13 @@ public void resolve(DynamicContext context, ExceptionMetadata metadata) { } } } + + @Override + public void resolve(StaticContext context, ExceptionMetadata metadata) { + for (ItemType itemType : this.content.getTypes()) { + if (!itemType.isResolved()) { + itemType.resolve(context, metadata); + } + } + } } diff --git a/src/main/java/sparksoniq/spark/DataFrameUtils.java b/src/main/java/sparksoniq/spark/DataFrameUtils.java index 5ceb22bd44..7ca241a805 100644 --- a/src/main/java/sparksoniq/spark/DataFrameUtils.java +++ b/src/main/java/sparksoniq/spark/DataFrameUtils.java @@ -11,15 +11,17 @@ import org.rumbledb.api.Item; import org.rumbledb.context.Name; import org.rumbledb.exceptions.InvalidInstanceException; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.items.ObjectItem; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.runtime.typing.ValidateTypeIterator; import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.FieldDescriptor; import org.rumbledb.types.ItemType; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Map.Entry; public class DataFrameUtils { public static Dataset convertItemRDDToDataFrame( @@ -158,55 +160,87 @@ private static void validateArrayItemInSchema(Item item) { } public static void validateSchemaItemAgainstDataFrame( - Item schemaItem, - StructType dataFrameSchema + ItemType expectedType, + ItemType actualType ) { - StructType generatedSchema = generateDataFrameSchemaFromSchemaItem(schemaItem); - for (StructField column : dataFrameSchema.fields()) { - final String columnName = column.name(); - final DataType columnDataType = column.dataType(); - - boolean columnMatched = Arrays.stream(generatedSchema.fields()).anyMatch(structField -> { - String generatedColumnName = structField.name(); - if (!generatedColumnName.equals(columnName)) { - return false; + if (expectedType.isAtomicItemType()) { + if (actualType.isSubtypeOf(expectedType)) { + return; + } + throw new InvalidInstanceException( + "Type mismatch: " + expectedType + " vs. " + actualType + ); + } + if (expectedType.isArrayItemType()) { + if (actualType.isArrayItemType()) { + if ( + actualType.getArrayContentFacet() + .getType() + .isSubtypeOf(expectedType.getArrayContentFacet().getType()) + ) { + return; } + } + throw new InvalidInstanceException( + "Type mismatch: expected " + + expectedType.getArrayContentFacet().getType() + + " but actually " + + actualType.getArrayContentFacet().getType() + ); + } + for (Entry actualTypeDescriptor : actualType.getObjectContentFacet().entrySet()) { + final String actualColumnName = actualTypeDescriptor.getKey(); + final ItemType columnDataType = actualTypeDescriptor.getValue().getType(); - DataType generatedDataType = structField.dataType(); - if (isUserTypeApplicable(generatedDataType, columnDataType)) { - return true; + boolean columnMatched = false; + for ( + Entry expectedTypeDescriptor : expectedType.getObjectContentFacet().entrySet() + ) { + String expectedColumnName = expectedTypeDescriptor.getKey(); + if (!expectedColumnName.equals(actualColumnName)) { + continue; } - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "expected '" - + ItemParser.getItemTypeNameFromDataFrameDataType(columnDataType) - + "' type for field '" - + columnName - + "', but found '" - + ItemParser.getItemTypeNameFromDataFrameDataType(generatedDataType) - + "'" - ); - }); + ItemType expectedColumnType = expectedTypeDescriptor.getValue().getType(); + try { + validateSchemaItemAgainstDataFrame(expectedColumnType, columnDataType); + } catch (Exception e) { + RumbleException ex = new InvalidInstanceException( + "Fields defined in schema must fully match the fields of input data: " + + "expected '" + + expectedColumnType + + "' type for field '" + + actualColumnName + + "', but found '" + + columnDataType + + "'" + ); + ex.initCause(e); + throw ex; + } + + columnMatched = true; + break; + } if (!columnMatched) { throw new InvalidInstanceException( "Fields defined in schema must fully match the fields of input data: " + "missing type information for '" - + columnName + + actualColumnName + "' field." ); } } - for (String generatedSchemaColumnName : generatedSchema.fieldNames()) { - boolean userColumnMatched = Arrays.asList(dataFrameSchema.fieldNames()).contains(generatedSchemaColumnName); + for (String expectedColumnName : expectedType.getObjectContentFacet().keySet()) { + boolean userColumnMatched = actualType.getObjectContentFacet().keySet().contains(expectedColumnName); if (!userColumnMatched) { throw new InvalidInstanceException( "Fields defined in schema must fully match the fields of input data: " + "redundant type information for non-existent field '" - + generatedSchemaColumnName + + expectedColumnName + "'." ); } diff --git a/src/main/java/sparksoniq/spark/SparkSessionManager.java b/src/main/java/sparksoniq/spark/SparkSessionManager.java index e4cc9deb4c..5e77f7b410 100644 --- a/src/main/java/sparksoniq/spark/SparkSessionManager.java +++ b/src/main/java/sparksoniq/spark/SparkSessionManager.java @@ -51,7 +51,7 @@ public class SparkSessionManager { - private static final String APP_NAME = "jsoniq-on-spark"; + private static final String APP_NAME = "Rumble application"; public static int COLLECT_ITEM_LIMIT = 0; private static SparkSessionManager instance; private static Level LOG_LEVEL = Level.FATAL; @@ -91,9 +91,12 @@ public SparkSession getOrCreateSession() { private void setDefaultConfiguration() { try { - this.configuration = new SparkConf() - .setAppName(APP_NAME) - .set("spark.sql.crossJoin.enabled", "true"); // enables cartesian product + this.configuration = new SparkConf(); + if (this.configuration.get("spark.app.name", "").equals(" long collectRDDwithLimitWarningOnly(JavaRDD rdd, List ou return count; } } + } diff --git a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java index 57bc782b9b..c8b22fdc6e 100644 --- a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java @@ -10,6 +10,8 @@ import org.rumbledb.runtime.DataFrameRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; +import org.rumbledb.types.ItemTypeFactory; import sparksoniq.spark.DataFrameUtils; @@ -32,15 +34,21 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { RuntimeIterator inputDataIterator = this.children.get(0); RuntimeIterator schemaIterator = this.children.get(1); Item schemaItem = schemaIterator.materializeFirstItemOrNull(context); - + ItemType schemaType = ItemTypeFactory.createItemTypeFromJSoundCompactItem(null, schemaItem, null); + schemaType.resolve(context, getMetadata()); try { if (inputDataIterator.isDataFrame()) { JSoundDataFrame inputDataAsDataFrame = inputDataIterator.getDataFrame(context); - DataFrameUtils.validateSchemaItemAgainstDataFrame( - schemaItem, + inputDataAsDataFrame.getDataFrame().printSchema(); + inputDataAsDataFrame.getDataFrame().show(); + ItemType actualSchemaType = ItemTypeFactory.createItemType( inputDataAsDataFrame.getDataFrame().schema() ); + DataFrameUtils.validateSchemaItemAgainstDataFrame( + schemaType, + actualSchemaType + ); return inputDataAsDataFrame; } diff --git a/src/main/java/sparksoniq/spark/ml/ApplyEstimatorRuntimeIterator.java b/src/main/java/sparksoniq/spark/ml/ApplyEstimatorRuntimeIterator.java index 7df04db024..a84f8192bf 100644 --- a/src/main/java/sparksoniq/spark/ml/ApplyEstimatorRuntimeIterator.java +++ b/src/main/java/sparksoniq/spark/ml/ApplyEstimatorRuntimeIterator.java @@ -15,6 +15,7 @@ import org.rumbledb.exceptions.InvalidRumbleMLParamException; import org.rumbledb.exceptions.MLNotADataFrameException; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.FunctionItem; import org.rumbledb.items.structured.JSoundDataFrame; @@ -29,6 +30,8 @@ import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static sparksoniq.spark.ml.RumbleMLUtils.convertRumbleObjectItemToSparkMLParamMap; @@ -53,6 +56,10 @@ public ApplyEstimatorRuntimeIterator( this.estimator = estimator; } + public Estimator getEstimator() { + return this.estimator; + } + @Override public Item materializeFirstItemOrNull( DynamicContext dynamicContext @@ -73,13 +80,117 @@ public Item materializeFirstItemOrNull( try { fittedModel = this.estimator.fit(this.inputDataset.getDataFrame(), paramMap); } catch (IllegalArgumentException | NoSuchElementException e) { - throw new InvalidRumbleMLParamException( + String message = e.getMessage(); + Pattern pattern = Pattern.compile("(.* ]) does not exist. Available: (.*)"); + Matcher matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the estimator " + + this.estimatorShortName + + "." + + "\nIt seems you provided an array of strings (" + + matcher.group(1) + + ") for parameter featuresCol, inputCol or similar." + + "\nHowever, this parameter should be a string, which is the name of the field associated with an array of features to train on or to transform." + + "\nIf you do not have such a field in your data, then you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data-with-features := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nand then" + + "\nlet $est := get-estimator(\"" + + this.estimatorShortName + + "\")" + + "\nlet $model := $est($data-with-features, {\"featuresCol\" : \"features\" }) (: assuming featuresCol is the parameter :)" + + "\n\nIf the features are in already your data, you can specify that field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator.", + getMetadata() + ); + ex.initCause(e); + throw ex; + } + pattern = Pattern.compile("(.*) does not exist. Available: (.*)"); + matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the estimator " + + this.estimatorShortName + + "." + + "\nIt seems you provided a field (" + + matcher.group(1) + + ") that does not exist" + + "\nThe available fields are: " + + matcher.group(2), + getMetadata() + ); + ex.initCause(e); + throw ex; + } + pattern = Pattern.compile( + "requirement failed: Column (.*) must be of type struct,values:array> but was actually .*" + ); + matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the estimator " + + this.estimatorShortName + + "." + + "\nIt seems you provided an field that is not an array of features for parameter featuresCol, inputCol or similar." + + "\nIf you do not have such a field in your data, then you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data-with-features := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nand then" + + "\nlet $est := get-estimator(\"" + + this.estimatorShortName + + "\")" + + "\nlet $model := $est($data-with-features, {\"featuresCol\" : \"features\" }) (: assuming featuresCol is the parameter :)" + + "\n\nIf the features are already in your data, you can specify that field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator.", + getMetadata() + ); + ex.initCause(e); + throw ex; + } + pattern = Pattern.compile( + "requirement failed: Column (.*) must be of type struct,values:array> but was actually .*" + ); + matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the estimator " + + this.estimatorShortName + + "." + + "\nIt seems you provided an field that is not an array of features for parameter featuresCol, inputCol or similar." + + "\nIf you do not have such a field in your data, then you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data-with-features := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nand then" + + "\nlet $est := get-estimator(\"" + + this.estimatorShortName + + "\")" + + "\nlet $model := $est($data-with-features, {\"featuresCol\" : \"features\" }) (: assuming featuresCol is the parameter :)" + + "\n\nIf the features are already in your data, you can specify that field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator.", + getMetadata() + ); + ex.initCause(e); + throw ex; + } + RumbleException ex = new InvalidRumbleMLParamException( "Parameters provided to " + this.estimatorShortName + " causes the following error: " - + e.getMessage(), + + e.getMessage() + + "\n\nWe are happy to give you a few hints:" + + "\nBy default, we look for the features used to train the model in the field 'features'." + + "\nIf this field does not exist, you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nIf the features are in your data, but in a different field than 'features', you can specify that different field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator." + + "\n\nIf the error says that it must be of the type struct,values:array> but was actually something different, then it means you specified a field that is not an assembled features array. You need to use the VectorAssembler to prepare it.", getMetadata() ); + ex.initCause(e); + throw ex; } return generateTransformerFunctionItem(fittedModel); diff --git a/src/main/java/sparksoniq/spark/ml/ApplyTransformerRuntimeIterator.java b/src/main/java/sparksoniq/spark/ml/ApplyTransformerRuntimeIterator.java index 08365639d9..dc6f2c2037 100644 --- a/src/main/java/sparksoniq/spark/ml/ApplyTransformerRuntimeIterator.java +++ b/src/main/java/sparksoniq/spark/ml/ApplyTransformerRuntimeIterator.java @@ -15,6 +15,7 @@ import org.rumbledb.exceptions.InvalidRumbleMLParamException; import org.rumbledb.exceptions.MLNotADataFrameException; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.DataFrameRuntimeIterator; @@ -24,6 +25,8 @@ import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static sparksoniq.spark.ml.RumbleMLUtils.convertRumbleObjectItemToSparkMLParamMap; @@ -49,6 +52,10 @@ public ApplyTransformerRuntimeIterator( this.transformer = transformer; } + public Transformer getTransformer() { + return this.transformer; + } + @Override public JSoundDataFrame getDataFrame(DynamicContext context) { this.inputDataset = getInputDataset(context); @@ -80,13 +87,92 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { getMetadata() ); } - throw new InvalidRumbleMLParamException( + String message = e.getMessage(); + Pattern pattern = Pattern.compile("(.* ]) does not exist. Available: (.*)"); + Matcher matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the transformer " + + this.transformerShortName + + "." + + "\nIt seems you provided an array of strings (" + + matcher.group(1) + + ") for parameter featuresCol, inputCol or similar." + + "\nHowever, this parameter should be a string, which is the name of the field associated with an array of features to train on or to transform." + + "\nIf you do not have such a field in your data, then you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data-with-features := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nand then" + + "\nlet $est := get-transformer(\"" + + this.transformerShortName + + "\")" + + "\nlet $model := $est($data-with-features, {\"inputCol\" : \"features\" }) (: assuming inputCol is the parameter :)" + + "\n\nIf the features are in already your data, you can specify that field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator.", + getMetadata() + ); + ex.initCause(e); + throw ex; + } + pattern = Pattern.compile("(.*) does not exist. Available: (.*)"); + matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the transformer " + + this.transformerShortName + + "." + + "\nIt seems you provided a field (" + + matcher.group(1) + + ") that does not exist" + + "\nThe available fields are: " + + matcher.group(2), + getMetadata() + ); + ex.initCause(e); + throw ex; + } + pattern = Pattern.compile( + "requirement failed: Column (.*) must be of type struct,values:array> but was actually .*" + ); + matcher = pattern.matcher(message); + if (matcher.find()) { + RumbleException ex = new InvalidRumbleMLParamException( + "There is an issue with the parameters provided to the transformer " + + this.transformerShortName + + "." + + "\nIt seems you provided an field that is not an array of features for parameter featuresCol, inputCol or similar." + + "\nIf you do not have such a field in your data, then you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data-with-features := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nand then" + + "\nlet $est := get-estimator(\"" + + this.transformerShortName + + "\")" + + "\nlet $model := $est($data-with-features, {\"inputCol\" : \"features\" }) (: assuming inputCol is the parameter :)" + + "\n\nIf the features are already in your data, you can specify that field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator.", + getMetadata() + ); + ex.initCause(e); + throw ex; + } + RumbleException ex = new InvalidRumbleMLParamException( "Parameters provided to " + this.transformerShortName + " causes the following error: " - + e.getMessage(), + + e.getMessage() + + "\n\nWe are happy to give you a few hints:" + + "\nBy default, we look for the features used to apply the model in the field 'features'." + + "\nIf this field does not exist, you can build it with the VectorAssembler transformer by combining the fields you want to include." + + "\n\nFor example:" + + "\nlet $vector-assembler := get-transformer(\"VectorAssembler\")" + + "\nlet $data := $vector-assembler($data, {\"inputCols\" : [ \"age\", \"weight\" ], \"outputCol\" : \"features\" })" + + "\n\nIf the features are in your data, but in a different field than 'features', you can specify that different field name with the parameter 'featuresCol' or 'inputCol' (check the documentation of the estimator to be sure) passed to your estimator." + + "\n\nIf the error says that it must be of the type struct,values:array> but was actually something different, then it means you specified a field that is not an assembled features array. You need to use the VectorAssembler to prepare it.", getMetadata() ); + ex.initCause(e); + throw ex; } } diff --git a/src/main/java/sparksoniq/spark/ml/GetEstimatorFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/GetEstimatorFunctionIterator.java index 011ba47834..2a5d1431c4 100644 --- a/src/main/java/sparksoniq/spark/ml/GetEstimatorFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/GetEstimatorFunctionIterator.java @@ -26,14 +26,11 @@ import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.FunctionItem; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.SequenceType; @@ -42,7 +39,7 @@ import java.util.Collections; import java.util.List; -public class GetEstimatorFunctionIterator extends LocalFunctionCallIterator { +public class GetEstimatorFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; public static final List estimatorFunctionParameterNames = new ArrayList<>( @@ -55,8 +52,6 @@ public class GetEstimatorFunctionIterator extends LocalFunctionCallIterator { ) ) ); - private String estimatorShortName; - private Class estimatorSparkMLClass; public GetEstimatorFunctionIterator( List arguments, @@ -67,92 +62,87 @@ public GetEstimatorFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - - RuntimeIterator nameIterator = this.children.get(0); - nameIterator.open(context); - if (!nameIterator.hasNext()) { - throw new UnexpectedTypeException( - "Invalid args. Estimator lookup can't be performed with empty sequence as the transformer name", - getMetadata() - ); - } - this.estimatorShortName = nameIterator.next().getStringValue(); - if (nameIterator.hasNext()) { - throw new UnexpectedTypeException( - "Estimator lookup can't be performed on a sequence.", - getMetadata() - ); + public Item materializeFirstItemOrNull( + DynamicContext dynamicContext + ) { + String estimatorShortName = this.children.get(0).materializeFirstItemOrNull(dynamicContext).getStringValue(); + Item paramMapItem = null; + if (this.children.size() >= 2) { + paramMapItem = this.children.get(1).materializeFirstItemOrNull(dynamicContext); } - nameIterator.close(); String estimatorFullClassName = RumbleMLCatalog.getEstimatorFullClassName( - this.estimatorShortName, + estimatorShortName, getMetadata() ); + + Class estimatorSparkMLClass = null; try { - this.estimatorSparkMLClass = Class.forName(estimatorFullClassName); - this.hasNext = true; + estimatorSparkMLClass = Class.forName(estimatorFullClassName); } catch (ClassNotFoundException e) { throw new OurBadException( - "No SparkML estimator implementation found with the given full class name." + estimatorShortName + + ": we could not find any estimator with that name. Please check the documentation." ); } - } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - Estimator estimator = (Estimator) this.estimatorSparkMLClass.newInstance(); - RuntimeIterator bodyIterator = new ApplyEstimatorRuntimeIterator( - this.estimatorShortName, - estimator, - ExecutionMode.LOCAL, + try { + Estimator estimator = (Estimator) estimatorSparkMLClass.newInstance(); + + if (paramMapItem != null) { + for (int paramIndex = 0; paramIndex < paramMapItem.getKeys().size(); paramIndex++) { + String paramName = paramMapItem.getKeys().get(paramIndex); + Item paramValue = paramMapItem.getValues().get(paramIndex); + + RumbleMLCatalog.validateEstimatorParameterByName(estimatorShortName, paramName, getMetadata()); + + String paramJavaTypeName = RumbleMLCatalog.getJavaTypeNameOfParamByName(paramName, getMetadata()); + Object paramValueInJava = RumbleMLUtils.convertParamItemToJava( + paramName, + paramValue, + paramJavaTypeName, getMetadata() - ); - List paramTypes = Collections.unmodifiableList( - Arrays.asList( - new SequenceType( - BuiltinTypesCatalogue.item, // TODO: revert back to ObjectItem - SequenceType.Arity.ZeroOrMore - ), - new SequenceType( - BuiltinTypesCatalogue.objectItem, - SequenceType.Arity.One - ) - ) - ); - SequenceType returnType = new SequenceType( - BuiltinTypesCatalogue.anyFunctionItem, - SequenceType.Arity.One - ); - - return new FunctionItem( - new FunctionIdentifier( - Name.createVariableInDefaultFunctionNamespace( - this.estimatorSparkMLClass.getName() - ), - 2 - ), - estimatorFunctionParameterNames, - new FunctionSignature( - paramTypes, - returnType - ), - new DynamicContext(this.currentDynamicContextForLocalExecution.getRumbleRuntimeConfiguration()), - bodyIterator - ); - - } catch (InstantiationException | IllegalAccessException e) { - throw new OurBadException("Error while generating an instance from transformer class.", getMetadata()); + ); + + estimator.set(paramName, paramValueInJava); + } } + + RuntimeIterator bodyIterator = new ApplyEstimatorRuntimeIterator( + estimatorShortName, + estimator, + ExecutionMode.LOCAL, + getMetadata() + ); + List paramTypes = Collections.unmodifiableList( + Arrays.asList( + SequenceType.createSequenceType("object*"), + SequenceType.createSequenceType("object") + ) + ); + SequenceType returnType = SequenceType.createSequenceType("function(object*, object) as object*"); + + return new FunctionItem( + new FunctionIdentifier( + Name.createVariableInDefaultFunctionNamespace( + estimatorSparkMLClass.getName() + ), + 2 + ), + estimatorFunctionParameterNames, + new FunctionSignature( + paramTypes, + returnType + ), + new DynamicContext(this.currentDynamicContextForLocalExecution.getRumbleRuntimeConfiguration()), + bodyIterator + ); + + } catch (InstantiationException | IllegalAccessException e) { + throw new OurBadException( + "Error while generating an instance from the estimator class " + estimatorFullClassName, + getMetadata() + ); } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + "get-transformer function", - getMetadata() - ); } } diff --git a/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java index c12ab7b965..ee49819b65 100644 --- a/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java @@ -26,14 +26,12 @@ import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.exceptions.UnexpectedTypeException; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.FunctionItem; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.SequenceType; @@ -41,8 +39,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.NoSuchElementException; -public class GetTransformerFunctionIterator extends LocalFunctionCallIterator { +public class GetTransformerFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; public static final List transformerParameterNames = new ArrayList<>( @@ -55,8 +54,6 @@ public class GetTransformerFunctionIterator extends LocalFunctionCallIterator { ) ) ); - private String transformerShortName; - private Class transformerSparkMLClass; public GetTransformerFunctionIterator( List arguments, @@ -67,92 +64,95 @@ public GetTransformerFunctionIterator( } @Override - public void open(DynamicContext context) { - super.open(context); - - RuntimeIterator nameIterator = this.children.get(0); - nameIterator.open(context); - if (!nameIterator.hasNext()) { - throw new UnexpectedTypeException( - "Invalid args. Transformer lookup can't be performed with empty sequence as the transformer name", - getMetadata() - ); - } - this.transformerShortName = nameIterator.next().getStringValue(); - if (nameIterator.hasNext()) { - throw new UnexpectedTypeException( - "Transformer lookup can't be performed on a sequence.", - getMetadata() - ); + public Item materializeFirstItemOrNull( + DynamicContext dynamicContext + ) { + String transformerShortName = this.children.get(0).materializeFirstItemOrNull(dynamicContext).getStringValue(); + Item paramMapItem = null; + if (this.children.size() >= 2) { + paramMapItem = this.children.get(1).materializeFirstItemOrNull(dynamicContext); } - nameIterator.close(); String transformerFullClassName = RumbleMLCatalog.getTransformerFullClassName( - this.transformerShortName, + transformerShortName, getMetadata() ); + + Class transformerSparkMLClass = null; try { - this.transformerSparkMLClass = Class.forName(transformerFullClassName); - this.hasNext = true; + transformerSparkMLClass = Class.forName(transformerFullClassName); } catch (ClassNotFoundException e) { throw new OurBadException( - "No SparkML transformer implementation found with the given full class name." + transformerShortName + + ": we could not find any transformer with that name. Please check the documentation." ); } - } - @Override - public Item next() { - if (this.hasNext) { - this.hasNext = false; - try { - Transformer transformer = (Transformer) this.transformerSparkMLClass.newInstance(); - RuntimeIterator bodyIterator = new ApplyTransformerRuntimeIterator( - this.transformerShortName, - transformer, - ExecutionMode.DATAFRAME, + try { + Transformer transformer = (Transformer) transformerSparkMLClass.newInstance(); + + if (paramMapItem != null) { + for (int paramIndex = 0; paramIndex < paramMapItem.getKeys().size(); paramIndex++) { + String paramName = paramMapItem.getKeys().get(paramIndex); + Item paramValue = paramMapItem.getValues().get(paramIndex); + + RumbleMLCatalog.validateTransformerParameterByName(transformerShortName, paramName, getMetadata()); + + String paramJavaTypeName = RumbleMLCatalog.getJavaTypeNameOfParamByName(paramName, getMetadata()); + Object paramValueInJava = RumbleMLUtils.convertParamItemToJava( + paramName, + paramValue, + paramJavaTypeName, getMetadata() - ); - List paramTypes = Collections.unmodifiableList( - Arrays.asList( - new SequenceType( - BuiltinTypesCatalogue.item, // TODO: revert back to ObjectItem - SequenceType.Arity.ZeroOrMore - ), - new SequenceType( - BuiltinTypesCatalogue.objectItem, - SequenceType.Arity.One - ) - ) - ); - SequenceType returnType = new SequenceType( - BuiltinTypesCatalogue.objectItem, - SequenceType.Arity.ZeroOrMore - ); - - return new FunctionItem( - new FunctionIdentifier( - Name.createVariableInDefaultFunctionNamespace( - this.transformerSparkMLClass.getName() - ), - 2 - ), - transformerParameterNames, - new FunctionSignature( - paramTypes, - returnType - ), - new DynamicContext(this.currentDynamicContextForLocalExecution.getRumbleRuntimeConfiguration()), - bodyIterator - ); - - } catch (InstantiationException | IllegalAccessException e) { - throw new OurBadException("Error while generating an instance from transformer class.", getMetadata()); + ); + + System.err.println("Setting " + paramJavaTypeName + " to " + paramValueInJava); + try { + transformer.set(paramName, paramValueInJava); + } catch (NoSuchElementException e) { + RumbleException ex = new OurBadException( + "Error in a parameter for transformer " + transformerShortName + ": " + e.getMessage(), + getMetadata() + ); + ex.initCause(e); + } + } } + RuntimeIterator bodyIterator = new ApplyTransformerRuntimeIterator( + transformerShortName, + transformer, + ExecutionMode.DATAFRAME, + getMetadata() + ); + List paramTypes = Collections.unmodifiableList( + Arrays.asList( + SequenceType.createSequenceType("object*"), + SequenceType.createSequenceType("object") + ) + ); + SequenceType returnType = SequenceType.createSequenceType("object*"); + + return new FunctionItem( + new FunctionIdentifier( + Name.createVariableInDefaultFunctionNamespace( + transformerSparkMLClass.getName() + ), + 2 + ), + transformerParameterNames, + new FunctionSignature( + paramTypes, + returnType + ), + new DynamicContext(dynamicContext.getRumbleRuntimeConfiguration()), + bodyIterator + ); + + } catch (InstantiationException | IllegalAccessException e) { + throw new OurBadException( + "Error while generating an instance from transformer class + " + transformerFullClassName, + getMetadata() + ); } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + "get-transformer function", - getMetadata() - ); } } diff --git a/src/main/java/sparksoniq/spark/ml/RumbleMLCatalog.java b/src/main/java/sparksoniq/spark/ml/RumbleMLCatalog.java index 60fa2b53a9..8ced548751 100644 --- a/src/main/java/sparksoniq/spark/ml/RumbleMLCatalog.java +++ b/src/main/java/sparksoniq/spark/ml/RumbleMLCatalog.java @@ -310,6 +310,7 @@ public class RumbleMLCatalog { paramJavaTypeNames.put("solver", "String"); paramJavaTypeNames.put("splits", "double[]"); paramJavaTypeNames.put("splitsArray", "double[][]"); + paramJavaTypeNames.put("stages", "PipelineStage[]"); paramJavaTypeNames.put("standardization", "boolean"); paramJavaTypeNames.put("statement", "String"); paramJavaTypeNames.put("stepSize", "double"); @@ -734,7 +735,7 @@ public class RumbleMLCatalog { ) ); estimatorParams.put("PCA", new ArrayList<>(Arrays.asList("inputCol", "k", "outputCol"))); - estimatorParams.put("Pipeline", new ArrayList<>(Arrays.asList())); + estimatorParams.put("Pipeline", new ArrayList<>(Arrays.asList("stages"))); estimatorParams.put( "QuantileDiscretizer", new ArrayList<>( @@ -1288,8 +1289,8 @@ static String getRumbleMLShortName(String javaFullClassName) { private static final String featuresColParamName = "featuresCol"; private static final String inputColParamName = "inputCol"; static { - specialParamsThatMayReferToAColumnOfVectors.add(featuresColParamName); - specialParamsThatMayReferToAColumnOfVectors.add(inputColParamName); + // specialParamsThatMayReferToAColumnOfVectors.add(featuresColParamName); + // specialParamsThatMayReferToAColumnOfVectors.add(inputColParamName); defaultSparkMLValuesOfSpecialParams.put(featuresColParamName, "features"); diff --git a/src/main/java/sparksoniq/spark/ml/RumbleMLUtils.java b/src/main/java/sparksoniq/spark/ml/RumbleMLUtils.java index 2dd7f4cfd3..ae3938539d 100644 --- a/src/main/java/sparksoniq/spark/ml/RumbleMLUtils.java +++ b/src/main/java/sparksoniq/spark/ml/RumbleMLUtils.java @@ -1,6 +1,7 @@ package sparksoniq.spark.ml; import org.apache.spark.ml.Estimator; +import org.apache.spark.ml.PipelineStage; import org.apache.spark.ml.Transformer; import org.apache.spark.ml.feature.VectorAssembler; import org.apache.spark.ml.param.Param; @@ -121,9 +122,17 @@ public static Object convertParamItemToJava( return convertArrayListToPrimitiveArray(paramAsListInJava, paramJavaTypeName); } else if (expectedJavaTypeMatchesRumbleAtomic(paramJavaTypeName)) { return convertRumbleAtomicToJava(param, paramJavaTypeName); + } else if (paramJavaTypeName.equals("PipelineStage")) { + if (param.isEstimator()) { + return param.getEstimator(); + } + if (param.isTransformer()) { + return param.getTransformer(); + } + throw new InvalidArgumentTypeException(paramName + " is expected to be an pipeline stage", metadata); } else { // complex SparkML parameters such as Estimator, Transformer, Classifier etc. are not implemented yet - throw new OurBadException("Not Implemented"); + throw new OurBadException("We have not implemented parameter support for type " + paramJavaTypeName); } } @@ -147,6 +156,12 @@ private static Object convertArrayListToPrimitiveArray(List paramAsListI doubleArray[i] = (Double) paramAsListInJava.get(i); } return doubleArray; + case "PipelineStage[]": + PipelineStage[] stageArray = new PipelineStage[paramAsListInJava.size()]; + for (int i = 0; i < stageArray.length; i++) { + stageArray[i] = (PipelineStage) paramAsListInJava.get(i); + } + return stageArray; default: throw new OurBadException("Unhandled case of arrayList to primitive[] conversion found."); } diff --git a/src/test/java/iq/base/AnnotationsTestsBase.java b/src/test/java/iq/base/AnnotationsTestsBase.java index b0447c30c5..9cdc860e15 100644 --- a/src/test/java/iq/base/AnnotationsTestsBase.java +++ b/src/test/java/iq/base/AnnotationsTestsBase.java @@ -20,6 +20,7 @@ package iq.base; +import org.apache.commons.lang.exception.ExceptionUtils; import org.junit.Assert; import org.rumbledb.api.Item; import org.rumbledb.api.Rumble; @@ -175,7 +176,7 @@ protected void testAnnotations(String path, RumbleRuntimeConfiguration configura checkExpectedOutput(this.currentAnnotation.getOutput(), sequence); } catch (RumbleException exception) { String errorOutput = exception.getMessage(); - exception.printStackTrace(); + errorOutput += "\n" + ExceptionUtils.getStackTrace(exception); Assert.fail("Program did not run when expected to.\nError output: " + errorOutput + "\n"); } } else { diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq new file mode 100644 index 0000000000..af35d747bd --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq @@ -0,0 +1,7 @@ +(:JIQS: ShouldRun; Output="({ "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 1 }, { "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 2 }, { "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 3 })" :) +declare type local:at as { "foo" : "integer" }; +declare type local:bt as { "foobar" : "integer", "bar" : [ "local:at" ] }; + +let $y := validate type local:bt* { (1 to 3)!{"foobar" : $$, "bar":[ (1 to 3)! {"foo":$$}] } } + +return $y \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/typeError11.jq b/src/test/resources/test_files/runtime-native-flwor/udt/typeError11.jq index 2156ca107c..9cb8b2fbba 100644 --- a/src/test/resources/test_files/runtime-native-flwor/udt/typeError11.jq +++ b/src/test/resources/test_files/runtime-native-flwor/udt/typeError11.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XPST0051"; ErrorMetadata="LINE:3:COLUMN:0:" :) +(:JIQS: ShouldNotCompile; ErrorCode="XPST0051"; ErrorMetadata="LINE:3:COLUMN:0:" :) declare type local:x as { "foo" : "integer" }; 1 cast as local:y diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/typeError12.jq b/src/test/resources/test_files/runtime-native-flwor/udt/typeError12.jq index 616c81b381..9a6affd9c5 100644 --- a/src/test/resources/test_files/runtime-native-flwor/udt/typeError12.jq +++ b/src/test/resources/test_files/runtime-native-flwor/udt/typeError12.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XPST0051"; ErrorMetadata="LINE:3:COLUMN:0:" :) +(:JIQS: ShouldNotCompile; ErrorCode="XPST0051"; ErrorMetadata="LINE:3:COLUMN:0:" :) declare type local:x as { "foo" : "integer" }; 1 castable as local:y diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError1.jq index 0e7465fd23..3595daaae4 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) +(:JIQS: ShouldCrash; ErrorCode="XQST0012"; :) annotate( structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), {"id": "decimal", "age": "decimal", "weight": "double", "i-should-not-exist": null} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError3.jq index 3e3f27a9a4..5cbfe8ba2d 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) +(:JIQS: ShouldCrash; ErrorCode="XPST0051"; :) annotate( structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), {"id": "int", "age": "int", "weight": "dou"} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq index 86c67e0d41..440b3a5892 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq @@ -1,7 +1,7 @@ (:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) annotate( structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), - {"id": "integer", "age": "integer", "weight": "double"} + {"id": "integer", "age": "integer", "weight": "decimal"} ) (: schema has incorrect types :) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq index bd47907751..e41775902c 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq @@ -1,7 +1,7 @@ (:JIQS: ShouldRun; Output="({ "label" : 0, "features" : { } }, { "label" : 1, "features" : { "0" : 0.1, "1" : 0.1, "2" : 0.1 } }, { "label" : 2, "features" : { "0" : 0.2, "1" : 0.2, "2" : 0.2 } }, { "label" : 3, "features" : { "0" : 9, "1" : 9, "2" : 9 } }, { "label" : 4, "features" : { "0" : 9.1, "1" : 9.1, "2" : 9.1 } }, { "label" : 5, "features" : { "0" : 9.2, "1" : 9.2, "2" : 9.2 } })" :) annotate( libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-kmeans.txt"), - {"label": "double", "features": "object"} + {"label": "double", "features": "array"} ) (: annotate with vector type representation in the 'features' :) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq index e9bde2d1b3..05e08126c6 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq @@ -1,10 +1,10 @@ -(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") let $intermediate-data := $binarizer($data, {"inputCol": "weight", "outputCol": "binarized_weight", "threshold": 70.0}) -let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "decimal", "binarized_weight": "double"}) +let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "double", "binarized_weight": "double"}) return $df-intermediate-data (: calling annotate on the results of a transformer :) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq index 2929d2a840..4b9cb48843 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq @@ -1,10 +1,10 @@ -(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0, "binarized_weight2" : 0 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1, "binarized_weight2" : 0 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1, "binarized_weight2" : 0 })" :) +(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0, "binarized_weight2" : 0 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1, "binarized_weight2" : 0 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1, "binarized_weight2" : 0 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") let $intermediate-data := $binarizer($data, {"inputCol": "weight", "outputCol": "binarized_weight", "threshold": 70.0}) -let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "decimal", "binarized_weight": "double"}) +let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "double", "binarized_weight": "double"}) for $i in $binarizer( $df-intermediate-data, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq index 437854bc45..25be9df18a 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq @@ -1,20 +1,22 @@ -(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0, "prediction" : 1 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1, "prediction" : 0 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1, "prediction" : 0 })" :) +(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0, "features" : [ 0 ], "prediction" : 1 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") let $intermediate-data := $binarizer($data, {"inputCol": "weight", "outputCol": "binarized_weight", "threshold": 70.0}) -let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "decimal", "binarized_weight": "double"}) +let $df-intermediate-data := annotate($intermediate-data, {"id": "integer", "age": "integer", "weight": "double", "binarized_weight": "double"}) +let $vector-assembler := get-transformer("VectorAssembler") +let $df-intermediate-data := $vector-assembler($df-intermediate-data, {"inputCols" : [ "binarized_weight" ], "outputCol" : "features" }) let $est := get-estimator("KMeans") let $tra := $est( $df-intermediate-data, - {"featuresCol": ["binarized_weight"]} + { } ) for $i in $tra( $df-intermediate-data, - {"featuresCol": ["binarized_weight"]} + { } ) return $i diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForEstimator1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForEstimator1.jq index bac814b3f3..c8b1c3fbcb 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForEstimator1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForEstimator1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "col1" : 0, "col2" : 0, "col3" : 0, "prediction" : 0 }, { "id" : 1, "col1" : 0.1, "col2" : 0.1, "col3" : 0.1, "prediction" : 0 }, { "id" : 2, "col1" : 0.2, "col2" : 0.2, "col3" : 0.2, "prediction" : 0 }, { "id" : 3, "col1" : 9, "col2" : 9, "col3" : 9, "prediction" : 1 }, { "id" : 4, "col1" : 9.1, "col2" : 9.1, "col3" : 9.1, "prediction" : 1 }, { "id" : 5, "col1" : 9.2, "col2" : 9.2, "col3" : 9.2, "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "col1" : 0, "col2" : 0, "col3" : 0, "features" : { }, "prediction" : 0 }, { "id" : 1, "col1" : 0.1, "col2" : 0.1, "col3" : 0.1, "features" : [ 0.1, 0.1, 0.1 ], "prediction" : 0 }, { "id" : 2, "col1" : 0.2, "col2" : 0.2, "col3" : 0.2, "features" : [ 0.2, 0.2, 0.2 ], "prediction" : 0 }, { "id" : 3, "col1" : 9, "col2" : 9, "col3" : 9, "features" : [ 9, 9, 9 ], "prediction" : 1 }, { "id" : 4, "col1" : 9.1, "col2" : 9.1, "col3" : 9.1, "features" : [ 9.1, 9.1, 9.1 ], "prediction" : 1 }, { "id" : 5, "col1" : 9.2, "col2" : 9.2, "col3" : 9.2, "features" : [ 9.2, 9.2, 9.2 ], "prediction" : 1 })" :) let $local-data := ( {"id": 0, "col1": 0.0, "col2": 0.0, "col3": 0.0}, {"id": 1, "col1": 0.1, "col2": 0.1, "col3": 0.1}, @@ -8,15 +8,17 @@ let $local-data := ( {"id": 5, "col1": 9.2, "col2": 9.2, "col3": 9.2} ) let $df-data := annotate($local-data, {"id": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $vector-assembler := get-transformer("VectorAssembler") +let $df-data := $vector-assembler($df-data, {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) let $est := get-estimator("KMeans") let $tra := $est( $df-data, - {"featuresCol": ["col1", "col2", "col3"]} + { } ) for $i in $tra( $df-data, - {"featuresCol": ["col1", "col2", "col3"]} + { } ) return $i diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateLocal-SchemaError3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateLocal-SchemaError3.jq index 78dbf97ebc..3a8fa32d40 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateLocal-SchemaError3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateLocal-SchemaError3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) +(:JIQS: ShouldCrash; ErrorCode="XPST0051"; :) annotate( ( {"id": 1, "age": 20, "weight": 68.8}, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateRDD-SchemaError3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateRDD-SchemaError3.jq index fec9acd4d4..18fab02d0a 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateRDD-SchemaError3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateRDD-SchemaError3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) +(:JIQS: ShouldCrash; ErrorCode="XPST0051"; :) annotate( json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), {"id": "int", "age": "str", "weight": "dec"} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-AFTSurvivalRegression.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-AFTSurvivalRegression.jq index 6342f94026..f46e146d66 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-AFTSurvivalRegression.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-AFTSurvivalRegression.jq @@ -11,15 +11,17 @@ let $data := annotate( $raw-data, { "label": "double", "censor": "double", "feature1": "double", "feature2": "double"} ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "feature1", "feature2" ], "outputCol" : "features" }) let $est := get-estimator("AFTSurvivalRegression") let $tra := $est( $data, - { "featuresCol": ["feature1", "feature2"], "quantileProbabilities": [0.3, 0.6], "quantilesCol": "quantiles"} + { "quantileProbabilities": [0.3, 0.6], "quantilesCol": "quantiles"} ) for $result in $tra( $data, - { "featuresCol": ["feature1", "feature2"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BisectingKMeans.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BisectingKMeans.jq index fc1e8899e0..7c46988c84 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BisectingKMeans.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BisectingKMeans.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("BisectingKMeans") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "k": 2, "seed": 1 } + { "k": 2, "seed": 1 } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BucketedRandomProjectionLSH.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BucketedRandomProjectionLSH.jq index 9c11f12258..edfff24972 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BucketedRandomProjectionLSH.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-BucketedRandomProjectionLSH.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("BucketedRandomProjectionLSH") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "bucketLength": 2.0, "numHashTables": 3, "outputCol": "hashes" } + { "inputCol": "features", "bucketLength": 2.0, "numHashTables": 3, "outputCol": "hashes" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-ChiSqSelector.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-ChiSqSelector.jq index 05ce05a491..09126a13f5 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-ChiSqSelector.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-ChiSqSelector.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("ChiSqSelector") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "numTopFeatures": 1, "outputCol": "selectedFeatures"} + { "numTopFeatures": 1, "outputCol": "selectedFeatures"} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeClassifier.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeClassifier.jq index 6ae2553ede..f4e7d2d6ec 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeClassifier.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeClassifier.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("DecisionTreeClassifier") let $tra := $est( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeRegressor.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeRegressor.jq index bcd517b8c6..2557322e20 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeRegressor.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-DecisionTreeRegressor.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("DecisionTreeRegressor") let $tra := $est( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTClassifier.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTClassifier.jq index 44e2c0f05a..de3f0f1e48 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTClassifier.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTClassifier.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("GBTClassifier") let $tra := $est( $data, - { "labelCol": "binaryLabel", "featuresCol": ["age", "weight"], "maxIter": 10, "featureSubsetStrategy": "auto"} + { "labelCol": "binaryLabel", "maxIter": 10, "featureSubsetStrategy": "auto"} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "binaryLabel": $result.binaryLabel, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTRegressor.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTRegressor.jq index 4450c9fb37..21fea4e0cb 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTRegressor.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GBTRegressor.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("GBTRegressor") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "maxIter": 10} + { "featuresCol": "features", "maxIter": 10} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GaussianMixture.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GaussianMixture.jq index 5d612b4f49..2dc10be993 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GaussianMixture.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GaussianMixture.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("GaussianMixture") let $tra := $est( $data, - { "featuresCol": ["age", "weight"] } + { } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GeneralizedLinearRegression.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GeneralizedLinearRegression.jq index edecc40cf6..4b4f0995da 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GeneralizedLinearRegression.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-GeneralizedLinearRegression.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("GeneralizedLinearRegression") let $tra := $est( $data, - { "family": "gaussian", "link": "identity", "featuresCol": ["age", "weight"], "maxIter": 10, "regParam": 0.3 } + { "family": "gaussian", "link": "identity", "maxIter": 10, "regParam": 0.3 } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IDF.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IDF.jq index 2b945ac8ec..3218146725 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IDF.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IDF.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("IDF") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "idf" } + { "inputCol": "features", "outputCol": "idf" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IsotonicRegression.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IsotonicRegression.jq index 666af14a7c..c49d1c0aec 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IsotonicRegression.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-IsotonicRegression.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("IsotonicRegression") let $tra := $est( $data, - { "featuresCol": ["age", "weight"] } + { } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-KMeans1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-KMeans1.jq index 067ee3d211..a2dd4a0136 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-KMeans1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-KMeans1.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("KMeans") let $tra := $est( $data, - { "k": 2, "seed": 1, "featuresCol": ["age", "weight"] } + { "k": 2, "seed": 1 } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "binaryLabel": $result.binaryLabel, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LDA.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LDA.jq index ebbfba39ab..2d997d3258 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LDA.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LDA.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("LDA") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "k": 2, "maxIter": 10} + { "k": 2, "maxIter": 10} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearRegression.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearRegression.jq index 17effe2c34..e5604411e7 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearRegression.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearRegression.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("LinearRegression") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "maxIter": 10, "regParam": 0.3, "elasticNetParam": 0.8} + { "maxIter": 10, "regParam": 0.3, "elasticNetParam": 0.8} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearSVC.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearSVC.jq index 090a8e6c50..e3b1482a90 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearSVC.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LinearSVC.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("LinearSVC") let $tra := $est( $data, - { "labelCol": "binaryLabel", "featuresCol": ["age", "weight"], "maxIter": 10, "regParam": 0.1 } + { "labelCol": "binaryLabel", "maxIter": 10, "regParam": 0.1 } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "binaryLabel": $result.binaryLabel, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LogisticRegression1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LogisticRegression1.jq index d191dc1161..b00e1036a7 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LogisticRegression1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-LogisticRegression1.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("LogisticRegression") let $tra := $est( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MaxAbsScaler.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MaxAbsScaler.jq index fac2a2554b..d1e3dcf950 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MaxAbsScaler.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MaxAbsScaler.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("MaxAbsScaler") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "scaled" } + { "inputCol": "features", "outputCol": "scaled" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinHashLSH.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinHashLSH.jq index 38ec7c6315..be0cbf201f 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinHashLSH.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinHashLSH.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("MinHashLSH") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "minhashlsh" } + { "inputCol": "features", "outputCol": "minhashlsh" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinMaxScaler.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinMaxScaler.jq index 7eb2fb32c3..fe7bd0b2c0 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinMaxScaler.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MinMaxScaler.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("MinMaxScaler") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "scaled" } + { "inputCol": "features", "outputCol": "scaled" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MultilayerPerceptronClassifier2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MultilayerPerceptronClassifier2.jq index f99ea7d617..161a77b733 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MultilayerPerceptronClassifier2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-MultilayerPerceptronClassifier2.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("MultilayerPerceptronClassifier") let $tra := $est( $data, - { "labelCol": "binaryLabel", "featuresCol": ["age", "weight"], "layers": [2, 5, 4, 6], "blockSize": 128, "seed": 1234, "maxIter": 3} + { "labelCol": "binaryLabel", "layers": [2, 5, 4, 6], "blockSize": 128, "seed": 1234, "maxIter": 3} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-NaiveBayes.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-NaiveBayes.jq index 5cfc42542b..67c76ecaca 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-NaiveBayes.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-NaiveBayes.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("NaiveBayes") let $tra := $est( $data, - { "featuresCol": ["age", "weight"]} + { "featuresCol": "features"} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { "featuresCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-PCA.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-PCA.jq index 13076924d8..eb032bbd91 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-PCA.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-PCA.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("MinMaxScaler") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "pca" } + { "inputCol": "features", "outputCol": "pca" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestClassifier.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestClassifier.jq index b605d9324f..2f3a9aafba 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestClassifier.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestClassifier.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("RandomForestClassifier") let $tra := $est( $data, - { "featuresCol": ["age", "weight"], "numTrees": 10} + { "numTrees": 10} ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestRegressor.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestRegressor.jq index 9c7da26008..975e195f3c 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestRegressor.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-RandomForestRegressor.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("RandomForestRegressor") let $tra := $est( $data, - { "featuresCol": ["age", "weight"]} + { } ) for $result in $tra( $data, - { "featuresCol": ["age", "weight"] } + { } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-StandardScaler.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-StandardScaler.jq index d0a2d6d694..e72aa73f41 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-StandardScaler.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-StandardScaler.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("StandardScaler") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "scaled" } + { "inputCol": "features", "outputCol": "scaled" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-VectorIndexer.jq b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-VectorIndexer.jq index 022362075f..f9ad4a02b6 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-VectorIndexer.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/EstimatorTests/MLEstimator-VectorIndexer.jq @@ -3,15 +3,17 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $est := get-estimator("VectorIndexer") let $tra := $est( $data, - { "inputCol": ["age", "weight"], "outputCol": "indexed" } + { "inputCol": "features", "outputCol": "indexed" } ) for $result in $tra( $data, - { "inputCol": ["age", "weight"] } + { "inputCol": "features" } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization-Error1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization-Error1.jq index 05fc13d337..a138692df3 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization-Error1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization-Error1.jq @@ -1,8 +1,8 @@ -(:JIQS: ShouldCrash; ErrorCode="FORG0006"; :) +(:JIQS: ShouldCrash; ErrorCode="RBML0003"; :) let $est := get-estimator("LogisticRegression") let $tra := $est( libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-short.txt"), - {"featuresCol": "label"} + {"featuresCol": [ "label" ]} ) let $res := $tra( libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-short.txt"), @@ -10,4 +10,4 @@ let $res := $tra( ) return $res -(: estimator's featuresCol is not an array :) +(: estimator's featuresCol is not a string :) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization1.jq index ed45868e26..f95f04b7d6 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/FeatureVectorization/MLFeatureVectorization1.jq @@ -2,11 +2,11 @@ let $est := get-estimator("LogisticRegression") let $tra := $est( libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-short.txt"), - {"featuresCol": ["features"]} + {"featuresCol": "features"} ) for $resultRow in $tra( libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-short.txt"), - {"featuresCol": ["features"] } + {"featuresCol": "features" } ) return { "label": $resultRow.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq new file mode 100644 index 0000000000..62d29dfd5d --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +let $vector-assembler := get-transformer("VectorAssembler") +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $est := get-estimator("PCA") +let $my-training-data := $vector-assembler($my-training-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-test-data := $vector-assembler($my-test-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq new file mode 100644 index 0000000000..4466476be8 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $est := get-estimator("PCA") +let $my-training-data := $vector-assembler($my-training-data) +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-test-data := $vector-assembler($my-test-data) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq new file mode 100644 index 0000000000..5dcc007192 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq @@ -0,0 +1,36 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) + +declare type local:mytype as { + "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" +}; + +let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := validate type local:mytype* { $training-data } +let $my-training-data := $vector-assembler($my-training-data) +let $my-test-data := validate type local:mytype* {$test-data } +let $my-test-data := $vector-assembler($my-test-data) + +let $est := get-estimator("PCA") +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) + +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq new file mode 100644 index 0000000000..2f918638f8 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) + +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + + +declare function local:pipeline($trainingset as object*, $testset as object*) as object* +{ + let $logisticregression := get-estimator("LogisticRegression") + let $model := $logisticregression($trainingset, {"featuresCol": "features"}) + return $model($testset, {"featuresCol": "features"}) +}; + +let $vector-assembler := get-transformer("VectorAssembler")(?, {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) + + +let $training-data := $vector-assembler(validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +}) +let $test-data := $vector-assembler(validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +}) + +let $pip := local:pipeline($training-data, ?) +return $pip($test-data) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq new file mode 100644 index 0000000000..ef83c7cdc5 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq @@ -0,0 +1,23 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + +let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) +let $logisticregression := get-estimator("LogisticRegression", { "featuresCol" : "features" }) + +let $pipeline := get-estimator("Pipeline", { "stages" : [ $vector-assembler, $logisticregression ] }) + + +let $training-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +} +let $test-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +} + +let $pip := $pipeline($training-data, {}) +return $pip($test-data, {}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq new file mode 100644 index 0000000000..c5f2d43411 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq @@ -0,0 +1,24 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + +let $pipeline := get-estimator("Pipeline", { + "stages" : [ + get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}), + get-estimator("LogisticRegression", { "featuresCol" : "features" }) + ] +}) + +let $training-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +} +let $test-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +} + +let $pip := $pipeline($training-data, {}) +return $pip($test-data, {}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-DiscreteCosineTransform(DCT)1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-DiscreteCosineTransform(DCT)1.jq index c7e75934e3..caf9d7e79f 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-DiscreteCosineTransform(DCT)1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-DiscreteCosineTransform(DCT)1.jq @@ -3,11 +3,13 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $transformer := get-transformer("DCT") for $result in $transformer( $data, - { "inputCol": ["age", "weight"], "outputCol": "dct_output", "inverse": false} + { "inputCol": "features", "outputCol": "dct_output", "inverse": false} ) return { diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Normalizer1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Normalizer1.jq index 5aaa2bb586..15c775ecda 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Normalizer1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Normalizer1.jq @@ -3,11 +3,13 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $transformer := get-transformer("Normalizer") for $result in $transformer( $data, - {"inputCol": ["age", "weight"], "outputCol": "output", "p": 1.0} + {"inputCol": "features", "outputCol": "output", "p": 1.0} ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-PolynomialExpansion1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-PolynomialExpansion1.jq index b39c469d31..dea9763dd1 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-PolynomialExpansion1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-PolynomialExpansion1.jq @@ -3,11 +3,13 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $transformer := get-transformer("PolynomialExpansion") for $result in $transformer( $data, - {"inputCol": ["age", "weight"], "outputCol": "output", "degree": 3} + {"inputCol": "features", "outputCol": "output", "degree": 3} ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Tokenizer2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Tokenizer2.jq new file mode 100644 index 0000000000..9ce8e04a57 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-Tokenizer2.jq @@ -0,0 +1,20 @@ +(:JIQS: ShouldRun; Output="({ "label" : 1, "stringCol" : "foo bar foobar", "output" : [ "foo", "bar", "foobar" ] }, { "label" : 2, "stringCol" : "foo bar foobar", "output" : [ "foo", "bar", "foobar" ] }, { "label" : 3, "stringCol" : "foo bar foobar", "output" : [ "foo", "bar", "foobar" ] }, { "label" : 4, "stringCol" : "foo bar foobar", "output" : [ "foo", "bar", "foobar" ] }, { "label" : 5, "stringCol" : "foo bar foobar", "output" : [ "foo", "bar", "foobar" ] })" :) + +let $data := annotate( + for $i in 1 to 10000 + return { "label" : $i, "stringCol" : "foo bar foobar" }, + { "label": "integer", "stringCol": "string" } +) + +let $transformer := get-transformer("Tokenizer") +for $result in $transformer( + $data, + {"inputCol": "stringCol", "outputCol": "output"} +) +count $c +where $c le 5 +return { + "label": $result.label, + "stringCol": $result.stringCol, + "output": $result.output +} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSizeHint1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSizeHint1.jq index c2ba9c100e..c2b2721ba9 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSizeHint1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSizeHint1.jq @@ -3,11 +3,13 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $transformer := get-transformer("VectorSizeHint") for $result in $transformer( $data, - {"inputCol": ["age", "weight"], "handleInvalid": "skip", "size": 2} + {"inputCol": "features", "handleInvalid": "skip", "size": 2} ) return { "label": $result.label, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSlicer1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSlicer1.jq index 067dfbe1ee..ae1e9a70eb 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSlicer1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/TransformerTests/MLTransformer-VectorSlicer1.jq @@ -3,11 +3,13 @@ let $data := annotate( json-file("../../../../queries/rumbleML/sample-ml-data-flat.json"), { "label": "integer", "binaryLabel": "integer", "name": "string", "age": "double", "weight": "double", "booleanCol": "boolean", "nullCol": "null", "stringCol": "string", "stringArrayCol": ["string"], "intArrayCol": ["integer"], "doubleArrayCol": ["double"], "doubleArrayArrayCol": [["double"]] } ) +let $vector-assembler := get-transformer("VectorAssembler") +let $data := $vector-assembler($data, {"inputCols" : [ "age", "weight" ], "outputCol" : "features" }) let $transformer := get-transformer("VectorSlicer") for $result in $transformer( $data, - {"inputCol": ["age", "weight"], "outputCol": "output", "indices": [ 1 ] } + {"inputCol": "features", "outputCol": "output", "indices": [ 1 ] } ) return { "label": $result.label, diff --git a/src/test/resources/test_files/static-typing/postfix/dynamicfunc1.jq b/src/test/resources/test_files/static-typing/postfix/dynamicfunc1.jq index 81f0bcb7c3..f96996af94 100644 --- a/src/test/resources/test_files/static-typing/postfix/dynamicfunc1.jq +++ b/src/test/resources/test_files/static-typing/postfix/dynamicfunc1.jq @@ -1,4 +1,4 @@ (:JIQS: ShouldRun :) declare function a($b as atomic) { "a" || $b }; declare variable $a := a#1; -$a(12) is statically string \ No newline at end of file +$a(12) is statically item* \ No newline at end of file diff --git a/src/test/resources/test_files/static-typing/postfix/dynamicfunc3.jq b/src/test/resources/test_files/static-typing/postfix/dynamicfunc3.jq index 03c286d7d0..ccf8a8a601 100644 --- a/src/test/resources/test_files/static-typing/postfix/dynamicfunc3.jq +++ b/src/test/resources/test_files/static-typing/postfix/dynamicfunc3.jq @@ -1,4 +1,4 @@ (:JIQS: ShouldCrash; ErrorCode="SENR0001" :) declare function a($b as atomic) { "a" || $b }; declare variable $a := a#1; -$a is statically function(atomic) as string \ No newline at end of file +$a is statically function(atomic) as item* \ No newline at end of file From 9e6a856fa653b4cf9c7b36d43b21e18780f1882d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 30 Jun 2021 13:36:16 +0000 Subject: [PATCH 050/142] merge annotatedItem branch --- src/main/java/org/rumbledb/api/Item.java | 20 +- .../context/BuiltinFunctionCatalogue.java | 102 ++--- .../org/rumbledb/items/AnnotatedItem.java | 359 ++++++++++++++++++ .../java/org/rumbledb/items/BooleanItem.java | 5 + .../java/org/rumbledb/items/DateItem.java | 5 + .../java/org/rumbledb/items/DateTimeItem.java | 5 + .../org/rumbledb/items/DateTimeStampItem.java | 237 ++++++++++++ .../java/org/rumbledb/items/DecimalItem.java | 5 + .../java/org/rumbledb/items/DoubleItem.java | 5 + .../java/org/rumbledb/items/DurationItem.java | 5 + .../java/org/rumbledb/items/FloatItem.java | 6 + src/main/java/org/rumbledb/items/IntItem.java | 5 + .../java/org/rumbledb/items/IntegerItem.java | 5 + .../java/org/rumbledb/items/ItemFactory.java | 12 + .../ArrayDescendantFunctionIterator.java | 2 + .../components/ImplicitTimezoneIterator.java | 34 ++ .../RoundHalfToEvenFunctionIterator.java | 38 +- .../strings/StringFunctionIterator.java | 63 +++ .../rumbledb/runtime/typing/CastIterator.java | 97 +++++ .../org/rumbledb/types/AtomicItemType.java | 15 + .../rumbledb/types/BuiltinTypesCatalogue.java | 134 ++++++- .../rumbledb/types/DerivedAtomicItemType.java | 105 +++++ .../java/org/rumbledb/types/JsonItemType.java | 1 + .../java/org/rumbledb/types/SequenceType.java | 67 ++++ .../test_files/runtime/CastAnnotated.jq | 10 + .../test_files/runtime/CastAnnotatedError1.jq | 4 + .../test_files/runtime/CastAnnotatedError2.jq | 4 + .../FunctionDateTimeStamp.jq | 7 + .../FunctionDateTimeStampError1.jq | 4 + .../runtime/FunctionString/String.jq | 6 + 30 files changed, 1311 insertions(+), 56 deletions(-) create mode 100644 src/main/java/org/rumbledb/items/AnnotatedItem.java create mode 100644 src/main/java/org/rumbledb/items/DateTimeStampItem.java create mode 100644 src/main/java/org/rumbledb/runtime/functions/durations/components/ImplicitTimezoneIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/functions/strings/StringFunctionIterator.java create mode 100644 src/test/resources/test_files/runtime/CastAnnotated.jq create mode 100644 src/test/resources/test_files/runtime/CastAnnotatedError1.jq create mode 100644 src/test/resources/test_files/runtime/CastAnnotatedError2.jq create mode 100644 src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStamp.jq create mode 100644 src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStampError1.jq create mode 100644 src/test/resources/test_files/runtime/FunctionString/String.jq diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 2169d3b562..02ea233d6f 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -160,6 +160,15 @@ default boolean isFloat() { return false; } + /** + * Tests whether the item is an atomic item of type annotatedItem. + * + * @return true if it is an atomic item of type annotatedItem, false otherwise. + */ + default boolean isAnnotatedItemType() { + return false; + } + /** * Tests whether the item is an atomic item of type duration. * @@ -307,7 +316,7 @@ default int getSize() { } /** - * Returns the string value of the item, if it is a string. + * Returns the string value of the item, if it is an atomic type. * * @return the string value. */ @@ -369,6 +378,15 @@ default BigDecimal getDecimalValue() { throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); } + /** + * Returns the AnnotatedItem value of the item, if it is a AnnotatedItem. + * + * @return the AnnotatedItem value. + */ + default long getAnnotatedItemValue() { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + /** * Returns the period value of the item, if it is a duration. * diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index e340dafbb0..3b57c0701a 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -19,30 +19,8 @@ import org.rumbledb.runtime.functions.datetime.FormatDateFunctionIterator; import org.rumbledb.runtime.functions.datetime.FormatDateTimeFunctionIterator; import org.rumbledb.runtime.functions.datetime.FormatTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.AdjustDateTimeToTimezone; -import org.rumbledb.runtime.functions.datetime.components.AdjustDateToTimezone; -import org.rumbledb.runtime.functions.datetime.components.AdjustTimeToTimezone; -import org.rumbledb.runtime.functions.datetime.components.DayFromDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.DayFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.HoursFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.HoursFromTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.MinutesFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.MinutesFromTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.MonthFromDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.MonthFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.SecondsFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.SecondsFromTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.TimezoneFromDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.TimezoneFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.TimezoneFromTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.YearFromDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.components.YearFromDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.DaysFromDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.HoursFromDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.MinutesFromDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.MonthsFromDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.SecondsFromDurationFunctionIterator; -import org.rumbledb.runtime.functions.durations.components.YearsFromDurationFunctionIterator; +import org.rumbledb.runtime.functions.datetime.components.*; +import org.rumbledb.runtime.functions.durations.components.*; import org.rumbledb.runtime.functions.input.AvroFileFunctionIterator; import org.rumbledb.runtime.functions.input.CSVFileFunctionIterator; import org.rumbledb.runtime.functions.input.JsonFileFunctionIterator; @@ -104,28 +82,7 @@ import org.rumbledb.runtime.functions.sequences.value.DeepEqualFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.DistinctValuesFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.IndexOfFunctionIterator; -import org.rumbledb.runtime.functions.strings.CodepointEqualFunctionIterator; -import org.rumbledb.runtime.functions.strings.CodepointsToStringFunctionIterator; -import org.rumbledb.runtime.functions.strings.ConcatFunctionIterator; -import org.rumbledb.runtime.functions.strings.ContainsFunctionIterator; -import org.rumbledb.runtime.functions.strings.EncodeForURIFunctionIterator; -import org.rumbledb.runtime.functions.strings.EndsWithFunctionIterator; -import org.rumbledb.runtime.functions.strings.LowerCaseFunctionIterator; -import org.rumbledb.runtime.functions.strings.MatchesFunctionIterator; -import org.rumbledb.runtime.functions.strings.NormalizeSpaceFunctionIterator; -import org.rumbledb.runtime.functions.strings.NormalizeUnicodeFunctionIterator; -import org.rumbledb.runtime.functions.strings.ReplaceFunctionIterator; -import org.rumbledb.runtime.functions.strings.SerializeFunctionIterator; -import org.rumbledb.runtime.functions.strings.StartsWithFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringJoinFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringLengthFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringToCodepointsFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringAfterFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringBeforeFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringFunctionIterator; -import org.rumbledb.runtime.functions.strings.TokenizeFunctionIterator; -import org.rumbledb.runtime.functions.strings.TranslateFunctionIterator; -import org.rumbledb.runtime.functions.strings.UpperCaseFunctionIterator; +import org.rumbledb.runtime.functions.strings.*; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.SequenceType; @@ -926,7 +883,7 @@ private static BuiltinFunction createBuiltinFunction( ); /** * function that rounds a value to a specified number of decimal places, rounding to make the last digit even if - * two such values are equally near + * two such values are equally nearinT */ static final BuiltinFunction round_half_to_even1 = createBuiltinFunction( new Name( @@ -934,8 +891,8 @@ private static BuiltinFunction createBuiltinFunction( "fn", "round-half-to-even" ), - "double?", - "double?", + "numeric?", + "numeric?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -945,9 +902,9 @@ private static BuiltinFunction createBuiltinFunction( "fn", "round-half-to-even" ), - "double?", + "numeric?", "integer", - "double?", + "numeric?", RoundHalfToEvenFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -1151,6 +1108,31 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns string + */ + static final BuiltinFunction string0 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "string" + ), + "string", + StringFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction string1 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "string" + ), + "item?", + "string", + StringFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + /** * function that returns substrings */ @@ -2102,6 +2084,20 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns the value of the implicit timezone property from the dynamic context. + */ + static final BuiltinFunction implicit_timezone = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "implicit-timezone" + ), + "dayTimeDuration?", + ImplicitTimezoneIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + /** * function that returns the keys of a Json Object */ @@ -2459,6 +2455,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(atan.getIdentifier(), atan); builtinFunctions.put(atan2.getIdentifier(), atan2); + builtinFunctions.put(string0.getIdentifier(), string0); + builtinFunctions.put(string1.getIdentifier(), string1); builtinFunctions.put(codepoints_to_string.getIdentifier(), codepoints_to_string); builtinFunctions.put(string_to_codepoints.getIdentifier(), string_to_codepoints); builtinFunctions.put(replace1.getIdentifier(), replace1); @@ -2519,6 +2517,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(adjust_dateTime_to_timezone1.getIdentifier(), adjust_dateTime_to_timezone1); builtinFunctions.put(adjust_dateTime_to_timezone2.getIdentifier(), adjust_dateTime_to_timezone2); + builtinFunctions.put(implicit_timezone.getIdentifier(), implicit_timezone); + builtinFunctions.put(current_date.getIdentifier(), current_date); builtinFunctions.put(format_date.getIdentifier(), format_date); builtinFunctions.put(year_from_date.getIdentifier(), year_from_date); diff --git a/src/main/java/org/rumbledb/items/AnnotatedItem.java b/src/main/java/org/rumbledb/items/AnnotatedItem.java new file mode 100644 index 0000000000..37faa3ca09 --- /dev/null +++ b/src/main/java/org/rumbledb/items/AnnotatedItem.java @@ -0,0 +1,359 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.apache.spark.api.java.JavaRDD; +import org.joda.time.DateTime; +import org.joda.time.Period; +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.FunctionIdentifier; +import org.rumbledb.context.Name; +import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.flwor.NativeClauseContext; +import org.rumbledb.types.FunctionSignature; +import org.rumbledb.types.ItemType; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +public class AnnotatedItem implements Item { + + private static final long serialVersionUID = 1L; + + private Item itemToAnnotate; + private ItemType type; + + public AnnotatedItem() { + super(); + } + + public AnnotatedItem(Item itemToAnnotate, ItemType type) { + this.itemToAnnotate = itemToAnnotate; + this.type = type; + } + + @Override + public void write(Kryo kryo, Output output) { + this.itemToAnnotate.write(kryo, output); + } + + @Override + public void read(Kryo kryo, Input input) { + this.itemToAnnotate.read(kryo, input); + } + + @Override + public boolean isArray() { + return this.itemToAnnotate.isArray(); + } + + @Override + public boolean isObject() { + return this.itemToAnnotate.isObject(); + } + + @Override + public boolean isFunction() { + return this.itemToAnnotate.isFunction(); + } + + @Override + public boolean isAtomic() { + return this.itemToAnnotate.isAtomic(); + } + + @Override + public boolean isString() { + return this.itemToAnnotate.isString(); + } + + @Override + public boolean isBoolean() { + return this.itemToAnnotate.isBoolean(); + } + + @Override + public boolean isNull() { + return this.itemToAnnotate.isNull(); + } + + @Override + public boolean isNumeric() { + return this.itemToAnnotate.isNumeric(); + } + + @Override + public boolean isDecimal() { + return this.itemToAnnotate.isDecimal(); + } + + @Override + public boolean isInteger() { + return this.itemToAnnotate.isInteger(); + } + + @Override + public boolean isInt() { + return this.itemToAnnotate.isInt(); + } + + @Override + public boolean isDouble() { + return this.itemToAnnotate.isDouble(); + } + + @Override + public boolean isFloat() { + return this.itemToAnnotate.isFloat(); + } + + @Override + public boolean isAnnotatedItemType() { + return this.itemToAnnotate.isAnnotatedItemType(); + } + + @Override + public boolean isDuration() { + return this.itemToAnnotate.isDuration(); + } + + @Override + public boolean isYearMonthDuration() { + return this.itemToAnnotate.isYearMonthDuration(); + } + + @Override + public boolean isDayTimeDuration() { + return this.itemToAnnotate.isDayTimeDuration(); + } + + @Override + public boolean isDateTime() { + return this.itemToAnnotate.isDateTime(); + } + + @Override + public boolean isDate() { + return this.itemToAnnotate.isDate(); + } + + @Override + public boolean isTime() { + return this.itemToAnnotate.isTime(); + } + + @Override + public boolean isAnyURI() { + return this.itemToAnnotate.isAnyURI(); + } + + @Override + public boolean isBinary() { + return this.itemToAnnotate.isBinary(); + } + + @Override + public boolean isHexBinary() { + return this.itemToAnnotate.isHexBinary(); + } + + @Override + public boolean isBase64Binary() { + return this.itemToAnnotate.isBase64Binary(); + } + + @Override + public List getItems() { + return this.itemToAnnotate.getItems(); + } + + @Override + public Item getItemAt(int position) { + return this.itemToAnnotate.getItemAt(position); + } + + @Override + public List getKeys() { + return this.itemToAnnotate.getKeys(); + } + + @Override + public List getValues() { + return this.itemToAnnotate.getValues(); + } + + @Override + public Item getItemByKey(String key) { + return this.itemToAnnotate.getItemByKey(key); + } + + @Override + public int getSize() { + return this.itemToAnnotate.getSize(); + } + + @Override + public String getStringValue() { + return this.itemToAnnotate.getStringValue(); + } + + @Override + public boolean getBooleanValue() { + return this.itemToAnnotate.getBooleanValue(); + } + + @Override + public double getDoubleValue() { + return this.itemToAnnotate.getDoubleValue(); + } + + @Override + public float getFloatValue() { + return this.itemToAnnotate.getFloatValue(); + } + + @Override + public int getIntValue() { + return this.itemToAnnotate.getIntValue(); + } + + @Override + public BigInteger getIntegerValue() { + return this.itemToAnnotate.getIntegerValue(); + } + + @Override + public BigDecimal getDecimalValue() { + return this.itemToAnnotate.getDecimalValue(); + } + + @Override + public Period getDurationValue() { + return this.itemToAnnotate.getDurationValue(); + } + + @Override + public DateTime getDateTimeValue() { + return this.itemToAnnotate.getDateTimeValue(); + } + + @Override + public byte[] getBinaryValue() { + return this.itemToAnnotate.getBinaryValue(); + } + + @Override + public ItemType getDynamicType() { + return this.type; + } + + @Override + public FunctionIdentifier getIdentifier() { + return this.itemToAnnotate.getIdentifier(); + } + + @Override + public List getParameterNames() { + return this.itemToAnnotate.getParameterNames(); + } + + @Override + public FunctionSignature getSignature() { + return this.itemToAnnotate.getSignature(); + } + + @Override + public RuntimeIterator getBodyIterator() { + return this.itemToAnnotate.getBodyIterator(); + } + + @Override + public Map> getLocalVariablesInClosure() { + return this.itemToAnnotate.getLocalVariablesInClosure(); + } + + @Override + public Map> getRDDVariablesInClosure() { + return this.itemToAnnotate.getRDDVariablesInClosure(); + } + + @Override + public Map getDFVariablesInClosure() { + return this.itemToAnnotate.getDFVariablesInClosure(); + } + + @Override + public DynamicContext getModuleDynamicContext() { + return this.itemToAnnotate.getModuleDynamicContext(); + } + + @Override + public boolean hasTimeZone() { + return this.itemToAnnotate.hasTimeZone(); + } + + @Override + public boolean hasDateTime() { + return this.itemToAnnotate.hasDateTime(); + } + + @Override + public boolean getEffectiveBooleanValue() { + return this.itemToAnnotate.getEffectiveBooleanValue(); + } + + @Override + public void putItem(Item item) { + this.itemToAnnotate.putItem(item); + } + + @Override + public void append(Item value) { + this.itemToAnnotate.append(value); + } + + @Override + public void putItemByKey(String key, Item value) { + this.itemToAnnotate.putItemByKey(key, value); + } + + @Override + public double castToDoubleValue() { + return this.itemToAnnotate.castToDoubleValue(); + } + + @Override + public float castToFloatValue() { + return this.itemToAnnotate.castToFloatValue(); + } + + @Override + public BigDecimal castToDecimalValue() { + return this.itemToAnnotate.castToDecimalValue(); + } + + @Override + public BigInteger castToIntegerValue() { + return this.itemToAnnotate.castToIntegerValue(); + } + + @Override + public int castToIntValue() { + return this.itemToAnnotate.castToIntValue(); + } + + @Override + public String serialize() { + return this.itemToAnnotate.serialize(); + } + + @Override + public NativeClauseContext generateNativeQuery(NativeClauseContext context) { + return this.itemToAnnotate.generateNativeQuery(context); + } +} diff --git a/src/main/java/org/rumbledb/items/BooleanItem.java b/src/main/java/org/rumbledb/items/BooleanItem.java index 9eef00ad7b..4c038b451e 100644 --- a/src/main/java/org/rumbledb/items/BooleanItem.java +++ b/src/main/java/org/rumbledb/items/BooleanItem.java @@ -51,6 +51,11 @@ public boolean getBooleanValue() { return this.getValue(); } + @Override + public String getStringValue() { + return String.valueOf(this.value); + } + @Override public boolean getEffectiveBooleanValue() { return this.getBooleanValue(); diff --git a/src/main/java/org/rumbledb/items/DateItem.java b/src/main/java/org/rumbledb/items/DateItem.java index 07f9a4a13b..1980d3e8dd 100644 --- a/src/main/java/org/rumbledb/items/DateItem.java +++ b/src/main/java/org/rumbledb/items/DateItem.java @@ -59,6 +59,11 @@ public DateTime getDateTimeValue() { return this.value; } + @Override + public String getStringValue() { + return this.value.toString(); + } + @Override public boolean isDate() { return true; diff --git a/src/main/java/org/rumbledb/items/DateTimeItem.java b/src/main/java/org/rumbledb/items/DateTimeItem.java index 60ced6796c..51c318e505 100644 --- a/src/main/java/org/rumbledb/items/DateTimeItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeItem.java @@ -95,6 +95,11 @@ public DateTime getDateTimeValue() { return this.getValue(); } + @Override + public String getStringValue() { + return this.value.toString(); + } + @Override public boolean hasTimeZone() { return this.hasTimeZone; diff --git a/src/main/java/org/rumbledb/items/DateTimeStampItem.java b/src/main/java/org/rumbledb/items/DateTimeStampItem.java new file mode 100644 index 0000000000..f3af8b6687 --- /dev/null +++ b/src/main/java/org/rumbledb/items/DateTimeStampItem.java @@ -0,0 +1,237 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.DateTimeFormatterBuilder; +import org.joda.time.format.DateTimeParser; +import org.joda.time.format.ISODateTimeFormat; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression.ComparisonOperator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + +import static org.joda.time.format.ISODateTimeFormat.dateElementParser; + +public class DateTimeStampItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeStampLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + private static final String timeLexicalRep = "(" + timeFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern dateTimeStampPattern = Pattern.compile(dateTimeStampLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + private static final Pattern timePattern = Pattern.compile(timeLexicalRep); + + + private static final long serialVersionUID = 1L; + private DateTime value; + + public DateTimeStampItem() { + super(); + } + + DateTimeStampItem(DateTime value) { + super(); + this.value = value; + } + + DateTimeStampItem(String dateTimeStampString) { + this.value = parseDateTime(dateTimeStampString, BuiltinTypesCatalogue.dateTimeStampItem); + // DateTimeStamp requires the time zone expression at the end of the value + if (!dateTimeStampString.endsWith("Z") && this.value.getZone() == DateTimeZone.getDefault()) { + return; + } + } + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public DateTime getValue() { + return this.value; + } + + @Override + public DateTime getDateTimeValue() { + return this.getValue(); + } + + @Override + public String getStringValue() { + return this.value.toString(); + } + + @Override + public boolean isDateTime() { + return true; + } + + @Override + public boolean hasDateTime() { + return true; + } + + @Override + public boolean getEffectiveBooleanValue() { + return false; + } + + @Override + public int hashCode() { + return this.getValue().hashCode(); + } + + @Override + public String serialize() { + String value = this.getValue().toString(); + String zoneString = this.getValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getValue().getZone().toString().equals(DateTimeZone.getDefault().toString()) + ? "" + : value.substring(value.length() - 6); + value = value.substring(0, value.length() - zoneString.length()); + value = this.getValue().getMillisOfSecond() == 0 ? value.substring(0, value.length() - 4) : value; + return value + zoneString; + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.value = new DateTime(millis, zone); + } + + private static DateTimeFormatter getDateTimeStampFormatter(ItemType dateTimeStampType) { + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + return ISODateTimeFormat.dateTimeParser().withOffsetParsed(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return ISODateTimeFormat.dateTimeParser().withOffsetParsed(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateItem)) { + DateTimeParser dtParser = new DateTimeFormatterBuilder().appendOptional( + ((new DateTimeFormatterBuilder()).appendTimeZoneOffset("Z", true, 2, 4).toFormatter()).getParser() + ).toParser(); + return (new DateTimeFormatterBuilder()).append(dateElementParser()) + .appendOptional(dtParser) + .toFormatter() + .withOffsetParsed(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.timeItem)) { + return ISODateTimeFormat.timeParser().withOffsetParsed(); + } + throw new IllegalArgumentException(); + } + + private static boolean checkInvalidDateTimeFormat(String dateTimeStamp, ItemType dateTimeStampType) { + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + return dateTimeStampPattern.matcher(dateTimeStamp).matches(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(dateTimeStamp).matches(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(dateTimeStamp).matches(); + } + if (dateTimeStampType.equals(BuiltinTypesCatalogue.timeItem)) { + return timePattern.matcher(dateTimeStamp).matches(); + } + return false; + } + + private static String fixEndOfDay(String dateTimeStamp) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTimeStamp.contains(endOfDay)) { + if (dateTimeStamp.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTimeStamp.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTimeStamp.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTimeStamp.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTimeStamp.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTimeStamp.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTimeStamp.substring(indexOfT + endOfDay.length() + 1); + } + return dateTimeStamp; + } + + static DateTime parseDateTime(String dateTimeStamp, ItemType dateTimeStampType) throws IllegalArgumentException { + if (!checkInvalidDateTimeFormat(dateTimeStamp, dateTimeStampType)) { + throw new IllegalArgumentException(); + } + dateTimeStamp = fixEndOfDay(dateTimeStamp); + return DateTime.parse(dateTimeStamp, getDateTimeStampFormatter(dateTimeStampType)); + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.dateTimeStampItem; + } + + @Override + public boolean isAtomic() { + return true; + } +} + diff --git a/src/main/java/org/rumbledb/items/DecimalItem.java b/src/main/java/org/rumbledb/items/DecimalItem.java index d5b714950c..6140eac503 100644 --- a/src/main/java/org/rumbledb/items/DecimalItem.java +++ b/src/main/java/org/rumbledb/items/DecimalItem.java @@ -72,6 +72,11 @@ public BigDecimal getDecimalValue() { return this.value; } + @Override + public String getStringValue() { + return this.value.toString(); + } + @Override public boolean getEffectiveBooleanValue() { return !this.getDecimalValue().equals(BigDecimal.ZERO); diff --git a/src/main/java/org/rumbledb/items/DoubleItem.java b/src/main/java/org/rumbledb/items/DoubleItem.java index 20553d8546..aa512344ba 100644 --- a/src/main/java/org/rumbledb/items/DoubleItem.java +++ b/src/main/java/org/rumbledb/items/DoubleItem.java @@ -68,6 +68,11 @@ public double getDoubleValue() { return this.value; } + @Override + public String getStringValue() { + return String.valueOf(this.value); + } + @Override public boolean getEffectiveBooleanValue() { return this.value != 0; diff --git a/src/main/java/org/rumbledb/items/DurationItem.java b/src/main/java/org/rumbledb/items/DurationItem.java index 7d3db3704a..8dee9dc221 100644 --- a/src/main/java/org/rumbledb/items/DurationItem.java +++ b/src/main/java/org/rumbledb/items/DurationItem.java @@ -98,6 +98,11 @@ public Period getDurationValue() { return this.getValue(); } + @Override + public String getStringValue() { + return this.value.toString(); + } + @Override public boolean isAtomic() { return true; diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index bade17b112..0473fbb4ca 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -71,6 +71,11 @@ public boolean getEffectiveBooleanValue() { return this.value != 0; } + @Override + public String getStringValue() { + return String.valueOf(this.value); + } + @Override public double castToDoubleValue() { return (double) this.value; @@ -122,6 +127,7 @@ public String serialize() { if (abs >= 0.000001 && abs <= 1000000) { return this.castToDecimalValue().stripTrailingZeros().toPlainString(); } + // When use float.toString or not return Float.toString(this.value); } diff --git a/src/main/java/org/rumbledb/items/IntItem.java b/src/main/java/org/rumbledb/items/IntItem.java index 2feaf4a607..6327197b40 100644 --- a/src/main/java/org/rumbledb/items/IntItem.java +++ b/src/main/java/org/rumbledb/items/IntItem.java @@ -83,6 +83,11 @@ public boolean getEffectiveBooleanValue() { return this.value != 0; } + @Override + public String getStringValue() { + return String.valueOf(this.value); + } + public double castToDoubleValue() { return new Integer(this.value).doubleValue(); } diff --git a/src/main/java/org/rumbledb/items/IntegerItem.java b/src/main/java/org/rumbledb/items/IntegerItem.java index 37645da91f..6fe5ef56b0 100644 --- a/src/main/java/org/rumbledb/items/IntegerItem.java +++ b/src/main/java/org/rumbledb/items/IntegerItem.java @@ -72,6 +72,11 @@ public BigDecimal getDecimalValue() { return new BigDecimal(this.value); } + @Override + public String getStringValue() { + return this.value.toString(); + } + @Override public boolean getEffectiveBooleanValue() { return !this.value.equals(BigInteger.ZERO); diff --git a/src/main/java/org/rumbledb/items/ItemFactory.java b/src/main/java/org/rumbledb/items/ItemFactory.java index 086f14e6fb..76968875d3 100644 --- a/src/main/java/org/rumbledb/items/ItemFactory.java +++ b/src/main/java/org/rumbledb/items/ItemFactory.java @@ -97,6 +97,10 @@ public Item createFloatItem(float d) { return new FloatItem(d); } + public Item createAnnotatedItem(Item itemToAnnotate, ItemType type) { + return new AnnotatedItem(itemToAnnotate, type); + } + public Item createDurationItem(Period p) { return new DurationItem(p); } @@ -117,6 +121,14 @@ public Item createDateTimeItem(String s) { return new DateTimeItem(s); } + public Item createDateTimeStampItem(DateTime value) { + return new DateTimeStampItem(value); + } + + public Item createDateTimeStampItem(String s) { + return new DateTimeStampItem(s); + } + public Item createDateItem(DateTime dt, boolean hasTimeZone) { return new DateItem(dt, hasTimeZone); } diff --git a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java index 86452a2e27..1797ca247d 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java @@ -133,4 +133,6 @@ public JavaRDD getRDDAux(DynamicContext dynamicContext) { FlatMapFunction transformation = new ArrayDescendantClosure(); return childRDD.flatMap(transformation); } + + // can extend dataframe support } diff --git a/src/main/java/org/rumbledb/runtime/functions/durations/components/ImplicitTimezoneIterator.java b/src/main/java/org/rumbledb/runtime/functions/durations/components/ImplicitTimezoneIterator.java new file mode 100644 index 0000000000..39ac5e8c9d --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/durations/components/ImplicitTimezoneIterator.java @@ -0,0 +1,34 @@ +package org.rumbledb.runtime.functions.durations.components; + +import org.joda.time.DateTime; +import org.joda.time.Period; +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class ImplicitTimezoneIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public ImplicitTimezoneIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + DateTime dt = new DateTime(); + return ItemFactory.getInstance() + .createDayTimeDurationItem(new Period(dt.getZone().toTimeZone().getRawOffset())); + } + +} diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index 3d6bd94dbe..3fe7c54088 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -24,6 +24,7 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; +import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; @@ -53,6 +54,15 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } + if (value.isDouble() && Double.isNaN(value.getDoubleValue())) { + return value; + } + if (value.isDouble() && Double.isInfinite(value.getDoubleValue())) { + return value; + } + if (value.isDouble() && value.getDoubleValue() == 0d) { + return value; + } int precision; if (this.children.size() > 1) { @@ -65,9 +75,31 @@ public Item materializeFirstItemOrNull(DynamicContext context) { precision = 0; } try { - BigDecimal bd = new BigDecimal(value.castToDoubleValue()); - bd = bd.setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + if (value.isInt()) { + BigDecimal bd = new BigDecimal(value.getIntValue()).setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntItem(bd.intValue()); + } + if (value.isInteger()) { + BigDecimal bd = new BigDecimal(value.getIntegerValue()).setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); + } + if (value.isDecimal()) { + BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDecimalItem(bd); + } + if (value.isDouble()) { + BigDecimal bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + } + if (value.isFloat()) { + BigDecimal bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_EVEN); + return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + } + throw new UnexpectedTypeException( + "Unexpected value in round-half-to-even(): " + value.getDynamicType(), + getMetadata() + ); + } catch (IteratorFlowException e) { throw new IteratorFlowException(e.getJSONiqErrorMessage(), getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringFunctionIterator.java new file mode 100644 index 0000000000..3817c6b708 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringFunctionIterator.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.runtime.functions.strings; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class StringFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public StringFunctionIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 0) { + List items = context.getVariableValues().getLocalVariableValue(Name.CONTEXT_ITEM, getMetadata()); + return ItemFactory.getInstance().createStringItem(items.get(0).getStringValue()); + } + + Item item = this.children.get(0) + .materializeFirstItemOrNull(context); + + if (item == null) { + return null; + } + + return ItemFactory.getInstance().createStringItem(item.getStringValue()); + } + +} diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 2ea90acc6a..591f92af38 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -229,6 +229,55 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { + if (!item.isString() && !item.isNumeric()) { + // If it is not a number, we fail (in this method, this is done with a null as the exception will + // only be thrown if the attempt to cast is made in particular circumstances. + return null; + } + + // Make sure item is string, then cast to primitive type + // Add also if item.isNumeric + if (item.isInt()) { + return checkFacetsInteger(item, targetType); + } + + if (item.isInteger()) { + return checkFacetsInteger(item, targetType); + } + + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.intItem)) { + // If it is not an integer we need to cast it to an integer first (long's primitive type), and then + // annotate. + Item intItem = castItemToType(item, BuiltinTypesCatalogue.intItem, metadata); + if (intItem == null) { + return null; + } + // if (item.isInt()) { + return checkFacetsInt(intItem, targetType); + // } + } + + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { + // If it is not an integer we need to cast it to an integer first (long's primitive type), and then + // annotate as long. + Item integerItem = castItemToType(item, BuiltinTypesCatalogue.integerItem, metadata); + if (integerItem == null) { + // xs:positiveInteger("23.4") goes here + return null; + } + + // if (item.isInteger()) { removed to support casting decimals eg xs:positiveInteger(1.4) gives 1 + return checkFacetsInteger(integerItem, targetType); + } + + return ItemFactory.getInstance() + .createAnnotatedItem( + item, + targetType + ); + } + if (targetType.equals(BuiltinTypesCatalogue.dateItem)) { if (item.isString()) { return ItemFactory.getInstance().createDateItem(item.getStringValue().trim()); @@ -253,6 +302,14 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return ItemFactory.getInstance().createDateTimeItem(item.getDateTimeValue(), item.hasTimeZone()); } } + if (targetType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); + } + if (item.isDate()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue()); + } + } if (targetType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { if (item.isString()) { return ItemFactory.getInstance() @@ -310,4 +367,44 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return null; } } + + public static Item checkFacetsInt(Item item, ItemType targetType) { + // Use castToInt rather than getInt so it supports String item + // compare returns -1 if less, 0 if eq, 1 if greater so <= 0 tests for less or equal + + if ( + (targetType.getMinInclusiveFacet() != null + && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntValue() > targetType.getMaxInclusiveFacet().getIntValue()) + // || (targetType.getMinExclusiveFacet() != null && item.getIntValue() <= + // targetType.getMinExclusiveFacet().getIntValue()) + // || (targetType.getMaxExclusiveFacet() != null && item.getIntValue() >= + // targetType.getMaxExclusiveFacet().getIntValue()) + ) { + return null; + } + return ItemFactory.getInstance().createAnnotatedItem(item, targetType); + } + + public static Item checkFacetsInteger(Item item, ItemType targetType) { + // Use castToInt rather than getInt so it supports String item + // compare returns -1 if less, 0 if eq, 1 if greater so <= 0 tests for less or equal + + if ( + (targetType.getMinInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMaxInclusiveFacet().getIntegerValue()) == 1) + // || (targetType.getMinExclusiveFacet() != null && + // item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) + // || (targetType.getMaxExclusiveFacet() != null && + // item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) + ) { + return null; + } + + return ItemFactory.getInstance().createAnnotatedItem(item, targetType); + } } + diff --git a/src/main/java/org/rumbledb/types/AtomicItemType.java b/src/main/java/org/rumbledb/types/AtomicItemType.java index 7f947a4676..2d8ad9dd91 100644 --- a/src/main/java/org/rumbledb/types/AtomicItemType.java +++ b/src/main/java/org/rumbledb/types/AtomicItemType.java @@ -154,6 +154,21 @@ public class AtomicItemType implements ItemType { ), DataTypes.DateType ); + static final AtomicItemType dateTimeStampItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "dateTimeStamp"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); static final AtomicItemType dateItem = new AtomicItemType( new Name(Name.XS_NS, "xs", "date"), new HashSet<>( diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 954ccef642..21fce83ce0 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.List; + public class BuiltinTypesCatalogue { public static final ItemType item = new ItemItemType(Name.createVariableInDefaultTypeNamespace("item")); @@ -154,6 +155,21 @@ public class BuiltinTypesCatalogue { ), DataTypes.DateType ); + public static final ItemType dateTimeStampItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "dateTimeStamp"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); public static final ItemType dateItem = new AtomicItemType( new Name(Name.XS_NS, "xs", "date"), new HashSet<>( @@ -264,6 +280,111 @@ public class BuiltinTypesCatalogue { DataTypes.ShortType // TODO : how to support arbitrary-sized integer ); + static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "byte"), + intItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(-128), new IntItem(127), true), + false, + DataTypes.ByteType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType nonNegativeIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "nonNegativeInteger"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("9223372036854775808")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType nonPositiveIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "nonPositiveInteger"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("-9223372036854775808")), + new IntegerItem(new BigInteger("0")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType negativeIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "negativeInteger"), + nonPositiveIntegerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("-9223372036854775808")), + new IntegerItem(new BigInteger("-1")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType positiveIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "positiveInteger"), + nonNegativeIntegerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("1")), + new IntegerItem(new BigInteger("9223372036854775807")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedInt"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("4294967295")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedLong"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("18446744073709551615")), + true + ), + false, + DataTypes.LongType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedShort"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(0), new IntItem(65535), true), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedByte"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(0), new IntItem(255), true), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + public static final ItemType JSONItem = new JsonItemType(); public static final ItemType objectItem = new ObjectItemType( new Name(Name.JS_NS, "js", "object"), @@ -316,6 +437,7 @@ public static boolean typeExists(Name name) { yearMonthDurationItem, dayTimeDurationItem, dateTimeItem, + dateTimeStampItem, dateItem, timeItem, hexBinaryItem, @@ -323,7 +445,16 @@ public static boolean typeExists(Name name) { base64BinaryItem, item, longItem, - shortItem + shortItem, + byteItem, + positiveIntegerItem, + negativeIntegerItem, + nonPositiveIntegerItem, + nonNegativeIntegerItem, + unsignedIntItem, + unsignedLongItem, + unsignedShortItem, + unsignedByteItem ); public static ItemType getItemTypeByName(Name name) { @@ -341,3 +472,4 @@ public static ItemType getItemTypeByName(Name name) { throw new OurBadException("Type unrecognized: " + name + "(namespace: " + name.getNamespace() + ")"); } } + diff --git a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java index ac40cfd644..e943723676 100644 --- a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java +++ b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java @@ -38,6 +38,58 @@ public class DerivedAtomicItemType implements ItemType { DataTypes.LongType // TODO : how to support arbitrary-sized integer ); + static final DerivedAtomicItemType nonNegativeIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "nonNegativeInteger"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("9223372036854775808")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType nonPositiveIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "nonPositiveInteger"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("-9223372036854775808")), + new IntegerItem(new BigInteger("0")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType negativeIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "negativeInteger"), + nonPositiveIntegerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("-9223372036854775808")), + new IntegerItem(new BigInteger("-1")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType positiveIntegerItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "positiveInteger"), + nonNegativeIntegerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("1")), + new IntegerItem(new BigInteger("9223372036854775807")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + static final DerivedAtomicItemType intItem = new DerivedAtomicItemType( Name.createVariableInDefaultTypeNamespace("int"), longItem, @@ -56,6 +108,59 @@ public class DerivedAtomicItemType implements ItemType { DataTypes.ShortType // TODO : how to support arbitrary-sized integer ); + static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "byte"), + intItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(-128), new IntItem(127), true), + false, + DataTypes.ByteType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedInt"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("4294967295")), + true + ), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedLong"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets( + new IntegerItem(new BigInteger("0")), + new IntegerItem(new BigInteger("18446744073709551615")), + true + ), + false, + DataTypes.LongType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedShort"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(0), new IntItem(65535), true), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + + static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedByte"), + integerItem, + AtomicItemType.decimalItem, + Facets.createMinMaxFacets(new IntItem(0), new IntItem(255), true), + false, + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + ); + private final ItemType baseType, primitiveType; private final int typeTreeDepth; private final boolean isUserDefined; diff --git a/src/main/java/org/rumbledb/types/JsonItemType.java b/src/main/java/org/rumbledb/types/JsonItemType.java index 17017aeb17..37aa427ddb 100644 --- a/src/main/java/org/rumbledb/types/JsonItemType.java +++ b/src/main/java/org/rumbledb/types/JsonItemType.java @@ -20,6 +20,7 @@ public class JsonItemType implements ItemType { this.name = new Name(Name.JS_NS, "js", "json-item"); } + @Override public boolean equals(Object other) { if (!(other instanceof ItemType)) { diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index 28492073f9..209c3be71f 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -410,6 +410,11 @@ public String toString() { new SequenceType(BuiltinTypesCatalogue.dateTimeItem, SequenceType.Arity.OneOrZero) ); + sequenceTypes.put( + "dateTimeStamp?", + new SequenceType(BuiltinTypesCatalogue.dateTimeStampItem, SequenceType.Arity.OneOrZero) + ); + sequenceTypes.put("date?", new SequenceType(BuiltinTypesCatalogue.dateItem, SequenceType.Arity.OneOrZero)); sequenceTypes.put("time?", new SequenceType(BuiltinTypesCatalogue.timeItem, SequenceType.Arity.OneOrZero)); @@ -428,6 +433,7 @@ public String toString() { ); sequenceTypes.put("null?", new SequenceType(BuiltinTypesCatalogue.nullItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put( "function(object*, object) as object*", new SequenceType( @@ -442,6 +448,7 @@ public String toString() { ) ) ); + sequenceTypes.put( "function(object*, object) as function(object*, object) as object*", new SequenceType( @@ -472,6 +479,66 @@ public String toString() { ) ) ); + + sequenceTypes.put( + "int?", + new SequenceType(BuiltinTypesCatalogue.intItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "long?", + new SequenceType(BuiltinTypesCatalogue.longItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "short?", + new SequenceType(BuiltinTypesCatalogue.shortItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "byte?", + new SequenceType(BuiltinTypesCatalogue.byteItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "positiveInteger?", + new SequenceType(BuiltinTypesCatalogue.positiveIntegerItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "negativeInteger?", + new SequenceType(BuiltinTypesCatalogue.negativeIntegerItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "nonPositiveInteger?", + new SequenceType(BuiltinTypesCatalogue.nonPositiveIntegerItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "nonNegativeInteger?", + new SequenceType(BuiltinTypesCatalogue.nonNegativeIntegerItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "unsignedInt?", + new SequenceType(BuiltinTypesCatalogue.unsignedIntItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "unsignedLong?", + new SequenceType(BuiltinTypesCatalogue.unsignedLongItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "unsignedShort?", + new SequenceType(BuiltinTypesCatalogue.unsignedShortItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "unsignedByte?", + new SequenceType(BuiltinTypesCatalogue.unsignedByteItem, SequenceType.Arity.OneOrZero) + ); } public static SequenceType createSequenceType(String userFriendlyName) { diff --git a/src/test/resources/test_files/runtime/CastAnnotated.jq b/src/test/resources/test_files/runtime/CastAnnotated.jq new file mode 100644 index 0000000000..32a782474b --- /dev/null +++ b/src/test/resources/test_files/runtime/CastAnnotated.jq @@ -0,0 +1,10 @@ +(:JIQS: ShouldRun; Output="(2, 10, -32, -21, 127, 3456, 0, -2, 1000)" :) +xs:positiveInteger("2"), +xs:positiveInteger(10), +xs:long(-32), +xs:nonPositiveInteger(-21), +xs:byte(127), +xs:unsignedShort(3456), +unsignedInt(0), +xs:negativeInteger(-2.8), +xs:short(1000.99) diff --git a/src/test/resources/test_files/runtime/CastAnnotatedError1.jq b/src/test/resources/test_files/runtime/CastAnnotatedError1.jq new file mode 100644 index 0000000000..8b7bdbf2ed --- /dev/null +++ b/src/test/resources/test_files/runtime/CastAnnotatedError1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldCrash; ErrorCode="FORG0001"; ErrorMetadata="LINE:2:COLUMN:1:" :) + xs:positiveInteger("2.5") + +(: Cannot convert a decimal string into an integer :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/CastAnnotatedError2.jq b/src/test/resources/test_files/runtime/CastAnnotatedError2.jq new file mode 100644 index 0000000000..52cece4c6b --- /dev/null +++ b/src/test/resources/test_files/runtime/CastAnnotatedError2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldCrash; ErrorCode="FORG0001"; ErrorMetadata="LINE:2:COLUMN:0:" :) +xs:byte(256) + +(: Out of bounds for byte's facets :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStamp.jq b/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStamp.jq new file mode 100644 index 0000000000..e6506a8236 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStamp.jq @@ -0,0 +1,7 @@ +(:JIQS: ShouldRun; Output="(2004-04-12T13:20:00-05:00, 2004-04-12T13:20:00Z, 2004-04-12T13:20:00+14:00)" :) +dateTimeStamp("2004-04-12T13:20:00-05:00"), +dateTimeStamp("2004-04-12T13:20:00Z"), +dateTimeStamp("2004-04-12T13:20:00+14:00"), +dateTimeStamp(()) + +(: general tests :) diff --git a/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStampError1.jq b/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStampError1.jq new file mode 100644 index 0000000000..e1b3f55da7 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionDateTimes/FunctionDateTimeStampError1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldCrash; ErrorCode="FORG0001"; ErrorMetadata="LINE:2:COLUMN:0:" :) +dateTimeStamp("2004-04-12T13:20:00") + +(: not castable to type dateTimeStamp because missing timeZone :) diff --git a/src/test/resources/test_files/runtime/FunctionString/String.jq b/src/test/resources/test_files/runtime/FunctionString/String.jq new file mode 100644 index 0000000000..1d35a178d9 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionString/String.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="(foo, f, )" :) +string("foo"), +string("f"), +string(""), +string(()) + From c9b81edb8af43c9ce2d487662e17c341ac3c16f5 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 2 Jul 2021 18:53:36 +0200 Subject: [PATCH 051/142] mantissa for large floats, satisfy spec --- src/main/java/org/rumbledb/items/FloatItem.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 0473fbb4ca..6867048e4f 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -34,6 +34,7 @@ import org.rumbledb.types.ItemType; import java.math.BigDecimal; import java.math.BigInteger; +import java.text.DecimalFormat; public class FloatItem implements Item { @@ -124,9 +125,18 @@ public String serialize() { return "-0"; } double abs = Math.abs(this.value); - if (abs >= 0.000001 && abs <= 1000000) { - return this.castToDecimalValue().stripTrailingZeros().toPlainString(); + //Mantissa starts from less or equal than 1.0E-7 + if (abs >= 0.000001 && abs < 1000000) { + return new BigDecimal(this.value).toString(); + //return this.castToDecimalValue().stripTrailingZeros().toPlainString(); } + // Force mantissa already from 1.0E6, then let Float.toString take care from 1.0E7 + if (abs >= 1000000 && abs < 10000000) { + return new DecimalFormat("0.0#######E0").format(this.value); + //return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); + } + // If less than 0.000001 must use mantissa, so from 0.0000001 = 1.0E-7 + // If more or = than 1.0E6 // When use float.toString or not return Float.toString(this.value); } From 5683e8e76793e7250f0056ad000ca181d49b2a14 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 2 Jul 2021 23:26:01 +0200 Subject: [PATCH 052/142] fix test suite for DateTimeStamp type. --- .../org/rumbledb/items/DateTimeStampItem.java | 25 ++++++++++++------- .../java/org/rumbledb/items/FloatItem.java | 6 ++--- .../java/org/rumbledb/items/ItemFactory.java | 4 +-- .../rumbledb/runtime/typing/CastIterator.java | 5 +++- .../org/rumbledb/types/AtomicItemType.java | 15 ++++++++--- .../rumbledb/types/BuiltinTypesCatalogue.java | 17 ++++--------- 6 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/rumbledb/items/DateTimeStampItem.java b/src/main/java/org/rumbledb/items/DateTimeStampItem.java index f3af8b6687..bba57568f0 100644 --- a/src/main/java/org/rumbledb/items/DateTimeStampItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeStampItem.java @@ -42,7 +42,7 @@ public class DateTimeStampItem implements Item { + "))"; private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; - private static final String dateTimeStampLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")"; + private static final String dateTimeStampLexicalRep = dateFrag + "T" + timeFrag + timezoneFrag; private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; private static final String timeLexicalRep = "(" + timeFrag + "(" + timezoneFrag + ")?)"; @@ -59,17 +59,18 @@ public DateTimeStampItem() { super(); } - DateTimeStampItem(DateTime value) { + DateTimeStampItem(DateTime value, boolean checkTimezone) { super(); - this.value = value; + if (checkTimezone) { + this.value = parseDateTimeStamp(this.value.toString(), BuiltinTypesCatalogue.dateTimeStampItem); + } else { + this.value = value; + } + } DateTimeStampItem(String dateTimeStampString) { - this.value = parseDateTime(dateTimeStampString, BuiltinTypesCatalogue.dateTimeStampItem); - // DateTimeStamp requires the time zone expression at the end of the value - if (!dateTimeStampString.endsWith("Z") && this.value.getZone() == DateTimeZone.getDefault()) { - return; - } + this.value = parseDateTimeStamp(dateTimeStampString, BuiltinTypesCatalogue.dateTimeStampItem); } @Override @@ -110,6 +111,11 @@ public boolean hasDateTime() { return true; } + @Override + public boolean hasTimeZone() { + return true; + } + @Override public boolean getEffectiveBooleanValue() { return false; @@ -216,7 +222,8 @@ private static String fixEndOfDay(String dateTimeStamp) { return dateTimeStamp; } - static DateTime parseDateTime(String dateTimeStamp, ItemType dateTimeStampType) throws IllegalArgumentException { + static DateTime parseDateTimeStamp(String dateTimeStamp, ItemType dateTimeStampType) + throws IllegalArgumentException { if (!checkInvalidDateTimeFormat(dateTimeStamp, dateTimeStampType)) { throw new IllegalArgumentException(); } diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 6867048e4f..6b390d8db4 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -125,15 +125,15 @@ public String serialize() { return "-0"; } double abs = Math.abs(this.value); - //Mantissa starts from less or equal than 1.0E-7 + // Mantissa starts from less or equal than 1.0E-7 if (abs >= 0.000001 && abs < 1000000) { return new BigDecimal(this.value).toString(); - //return this.castToDecimalValue().stripTrailingZeros().toPlainString(); + // return this.castToDecimalValue().stripTrailingZeros().toPlainString(); } // Force mantissa already from 1.0E6, then let Float.toString take care from 1.0E7 if (abs >= 1000000 && abs < 10000000) { return new DecimalFormat("0.0#######E0").format(this.value); - //return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); + // return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); } // If less than 0.000001 must use mantissa, so from 0.0000001 = 1.0E-7 // If more or = than 1.0E6 diff --git a/src/main/java/org/rumbledb/items/ItemFactory.java b/src/main/java/org/rumbledb/items/ItemFactory.java index 76968875d3..9aa41c26ac 100644 --- a/src/main/java/org/rumbledb/items/ItemFactory.java +++ b/src/main/java/org/rumbledb/items/ItemFactory.java @@ -121,8 +121,8 @@ public Item createDateTimeItem(String s) { return new DateTimeItem(s); } - public Item createDateTimeStampItem(DateTime value) { - return new DateTimeStampItem(value); + public Item createDateTimeStampItem(DateTime dt, boolean checkTimezone) { + return new DateTimeStampItem(dt, checkTimezone); } public Item createDateTimeStampItem(String s) { diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 591f92af38..d43902098a 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -307,7 +307,10 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); } if (item.isDate()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue()); + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); + } + if (item.isDateTime()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); } } if (targetType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { diff --git a/src/main/java/org/rumbledb/types/AtomicItemType.java b/src/main/java/org/rumbledb/types/AtomicItemType.java index 2d8ad9dd91..73a3aa4106 100644 --- a/src/main/java/org/rumbledb/types/AtomicItemType.java +++ b/src/main/java/org/rumbledb/types/AtomicItemType.java @@ -351,16 +351,23 @@ public boolean isStaticallyCastableAs(ItemType other) { else return false; } - // DateTime can be cast also to Date or Time + // DateTime can be cast also to Date or Time or DateTimeStamp if (this.equals(dateTimeItem)) { - if (other.equals(dateItem) || other.equals(timeItem)) + if (other.equals(dateItem) || other.equals(timeItem) || other.equals(dateTimeStampItem)) return true; else return false; } - // Date can be cast also to DateTime + // DateTimeStamp can be cast also to Date or Time or DateTime + if (this.equals(dateTimeStampItem)) { + if (other.equals(dateItem) || other.equals(timeItem) || other.equals(dateTimeItem)) + return true; + else + return false; + } + // Date can be cast also to DateTime or DateTimeStamp if (this.equals(dateItem)) { - if (other.equals(dateTimeItem)) + if (other.equals(dateTimeItem) || other.equals(dateTimeStampItem)) return true; else return false; diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 21fce83ce0..7625b02ab4 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -155,19 +155,12 @@ public class BuiltinTypesCatalogue { ), DataTypes.DateType ); - public static final ItemType dateTimeStampItem = new AtomicItemType( + public static final ItemType dateTimeStampItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "dateTimeStamp"), - new HashSet<>( - Arrays.asList( - FacetTypes.ENUMERATION, - FacetTypes.CONSTRAINTS, - FacetTypes.MININCLUSIVE, - FacetTypes.MAXINCLUSIVE, - FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, - FacetTypes.EXPLICITTIMEZONE - ) - ), + dateTimeItem, + AtomicItemType.dateTimeItem, + new Facets(), + false, DataTypes.DateType ); public static final ItemType dateItem = new AtomicItemType( From 36d05160a3572bde9c8cc11bd2dbc3931ddbd347 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 3 Jul 2021 13:00:48 +0200 Subject: [PATCH 053/142] fn:resolve-uri, adapt multiplicative tests float --- .../context/BuiltinFunctionCatalogue.java | 28 ++++++++++ .../java/org/rumbledb/items/FloatItem.java | 5 +- .../strings/ResolveURIFunctionIterator.java | 55 +++++++++++++++++++ .../runtime/FunctionString/ResolveURI1.jq | 5 ++ .../runtime/Operational/MultiplicativeOp11.jq | 2 +- 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java create mode 100644 src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 3b57c0701a..bf3d86bae5 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1455,6 +1455,32 @@ private static BuiltinFunction createBuiltinFunction( EncodeForURIFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that resolves IRI reference against an absolute IRI + */ + static final BuiltinFunction resolve_uri1 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "resolve-uri" + ), + "string?", + "anyURI?", + ResolveURIFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction resolve_uri2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "resolve-uri" + ), + "string?", + "string", + "anyURI?", + ResolveURIFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that checks whether a string ends with a substring */ @@ -2497,6 +2523,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(number0.getIdentifier(), number0); builtinFunctions.put(number1.getIdentifier(), number1); builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); + builtinFunctions.put(resolve_uri1.getIdentifier(), resolve_uri1); + builtinFunctions.put(resolve_uri2.getIdentifier(), resolve_uri2); builtinFunctions.put(years_from_duration.getIdentifier(), years_from_duration); builtinFunctions.put(months_from_duration.getIdentifier(), months_from_duration); diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 6b390d8db4..d80732c6e1 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -125,12 +125,11 @@ public String serialize() { return "-0"; } double abs = Math.abs(this.value); - // Mantissa starts from less or equal than 1.0E-7 + // Mantissa from less or equal than 1.0E-7 if (abs >= 0.000001 && abs < 1000000) { return new BigDecimal(this.value).toString(); - // return this.castToDecimalValue().stripTrailingZeros().toPlainString(); } - // Force mantissa already from 1.0E6, then let Float.toString take care from 1.0E7 + // Mantissa already from 1.0E6, then let Float.toString take care of mantissa from 1.0E7 if (abs >= 1000000 && abs < 10000000) { return new DecimalFormat("0.0#######E0").format(this.value); // return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java new file mode 100644 index 0000000000..a67ef992d2 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java @@ -0,0 +1,55 @@ +package org.rumbledb.runtime.functions.strings; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.functions.input.FileSystemUtil; + +import java.net.URI; +import java.util.List; + +public class ResolveURIFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public ResolveURIFunctionIterator( + List children, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(children, executionMode, iteratorMetadata); + } + + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + // StaticContext sc = this.children.get(0).sta + Item relative = this.children.get(0).materializeFirstItemOrNull(context); + if (relative == null) { + return null; + } + Item base; + if (this.children.size() == 2) { + base = this.children.get(1).materializeFirstItemOrNull(context); + } else { + // Item base = fn-static-context + base = null; + } + if (base == null) { + return null; + } + String stringRelative = relative.getStringValue(); + if (URI.create(stringRelative).isAbsolute()) { + return ItemFactory.getInstance().createAnyURIItem(stringRelative); + } + + URI uri = URI.create(base.getStringValue()); + String stringURI = FileSystemUtil.resolveURI(uri, stringRelative, getMetadata()).toString(); + + return ItemFactory.getInstance().createAnyURIItem(stringURI); + } +} diff --git a/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq b/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq new file mode 100644 index 0000000000..fee07b0acf --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="(http://www.base-uri.com/test, true)" :) +resolve-uri("test", "http://www.base-uri.com/"), +resolve-uri("relative/uri.ext", "http://www.base-uri.com/") eq xs:anyURI("http://www.base-uri.com/relative/uri.ext"), +resolve-uri(()) +(: base uri and empty sequence :) diff --git a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq index 68367fef13..87c32b0b71 100644 --- a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq +++ b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(1, 0.0000000003, 0.297029703, 0.00024390243902439024, 0.0002439024392515421, 3333333333.3333333333, 1, 990099009.900990099, 813008.1300813009, 813008.125, 3.3666666667, 0.000000001, 1, 0.0008211382113821138, 0.0008211382664740086, 4100, 0.00000123, 1217.821782178218, 1, 1, 4100, 0.0000012299999525566818, 1217.82177734375, 1, 1)" :) +(:JIQS: ShouldRun; Output="(1, 0.0000000003, 0.297029703, 0.00024390243902439024, 0.00024390243925154209136962890625, 3333333333.3333333333, 1, 990099009.900990099, 813008.1300813009, 813008.125, 3.3666666667, 0.000000001, 1, 0.0008211382113821138, 0.0008211382664740085601806640625, 4100, 0.00000123, 1217.821782178218, 1, 1, 4100, 0.000001229999952556681819260120391845703125, 1217.82177734375, 1, 1)" :) 3 div 3, 3 div 10000000000, 3 div 10.1, From ce7420439ad3e999fa1072f3e6d8af4d8949e2a8 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 3 Jul 2021 13:00:48 +0200 Subject: [PATCH 054/142] fn:resolve-uri, adapt multiplicative tests float --- .../context/BuiltinFunctionCatalogue.java | 28 ++++++++++ .../java/org/rumbledb/items/FloatItem.java | 5 +- .../strings/ResolveURIFunctionIterator.java | 55 +++++++++++++++++++ .../runtime/FunctionString/ResolveURI1.jq | 5 ++ .../runtime/Operational/MultiplicativeOp11.jq | 2 +- .../runtime/Operational/MultiplicativeOp13.jq | 2 +- 6 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java create mode 100644 src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 3b57c0701a..bf3d86bae5 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1455,6 +1455,32 @@ private static BuiltinFunction createBuiltinFunction( EncodeForURIFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that resolves IRI reference against an absolute IRI + */ + static final BuiltinFunction resolve_uri1 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "resolve-uri" + ), + "string?", + "anyURI?", + ResolveURIFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + static final BuiltinFunction resolve_uri2 = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "resolve-uri" + ), + "string?", + "string", + "anyURI?", + ResolveURIFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that checks whether a string ends with a substring */ @@ -2497,6 +2523,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(number0.getIdentifier(), number0); builtinFunctions.put(number1.getIdentifier(), number1); builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); + builtinFunctions.put(resolve_uri1.getIdentifier(), resolve_uri1); + builtinFunctions.put(resolve_uri2.getIdentifier(), resolve_uri2); builtinFunctions.put(years_from_duration.getIdentifier(), years_from_duration); builtinFunctions.put(months_from_duration.getIdentifier(), months_from_duration); diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 6b390d8db4..d80732c6e1 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -125,12 +125,11 @@ public String serialize() { return "-0"; } double abs = Math.abs(this.value); - // Mantissa starts from less or equal than 1.0E-7 + // Mantissa from less or equal than 1.0E-7 if (abs >= 0.000001 && abs < 1000000) { return new BigDecimal(this.value).toString(); - // return this.castToDecimalValue().stripTrailingZeros().toPlainString(); } - // Force mantissa already from 1.0E6, then let Float.toString take care from 1.0E7 + // Mantissa already from 1.0E6, then let Float.toString take care of mantissa from 1.0E7 if (abs >= 1000000 && abs < 10000000) { return new DecimalFormat("0.0#######E0").format(this.value); // return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java new file mode 100644 index 0000000000..a67ef992d2 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java @@ -0,0 +1,55 @@ +package org.rumbledb.runtime.functions.strings; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.functions.input.FileSystemUtil; + +import java.net.URI; +import java.util.List; + +public class ResolveURIFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public ResolveURIFunctionIterator( + List children, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(children, executionMode, iteratorMetadata); + } + + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + // StaticContext sc = this.children.get(0).sta + Item relative = this.children.get(0).materializeFirstItemOrNull(context); + if (relative == null) { + return null; + } + Item base; + if (this.children.size() == 2) { + base = this.children.get(1).materializeFirstItemOrNull(context); + } else { + // Item base = fn-static-context + base = null; + } + if (base == null) { + return null; + } + String stringRelative = relative.getStringValue(); + if (URI.create(stringRelative).isAbsolute()) { + return ItemFactory.getInstance().createAnyURIItem(stringRelative); + } + + URI uri = URI.create(base.getStringValue()); + String stringURI = FileSystemUtil.resolveURI(uri, stringRelative, getMetadata()).toString(); + + return ItemFactory.getInstance().createAnyURIItem(stringURI); + } +} diff --git a/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq b/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq new file mode 100644 index 0000000000..fee07b0acf --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionString/ResolveURI1.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="(http://www.base-uri.com/test, true)" :) +resolve-uri("test", "http://www.base-uri.com/"), +resolve-uri("relative/uri.ext", "http://www.base-uri.com/") eq xs:anyURI("http://www.base-uri.com/relative/uri.ext"), +resolve-uri(()) +(: base uri and empty sequence :) diff --git a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq index 68367fef13..87c32b0b71 100644 --- a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq +++ b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp11.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(1, 0.0000000003, 0.297029703, 0.00024390243902439024, 0.0002439024392515421, 3333333333.3333333333, 1, 990099009.900990099, 813008.1300813009, 813008.125, 3.3666666667, 0.000000001, 1, 0.0008211382113821138, 0.0008211382664740086, 4100, 0.00000123, 1217.821782178218, 1, 1, 4100, 0.0000012299999525566818, 1217.82177734375, 1, 1)" :) +(:JIQS: ShouldRun; Output="(1, 0.0000000003, 0.297029703, 0.00024390243902439024, 0.00024390243925154209136962890625, 3333333333.3333333333, 1, 990099009.900990099, 813008.1300813009, 813008.125, 3.3666666667, 0.000000001, 1, 0.0008211382113821138, 0.0008211382664740085601806640625, 4100, 0.00000123, 1217.821782178218, 1, 1, 4100, 0.000001229999952556681819260120391845703125, 1217.82177734375, 1, 1)" :) 3 div 3, 3 div 10000000000, 3 div 10.1, diff --git a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp13.jq b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp13.jq index 9659809f49..1913c591b6 100644 --- a/src/test/resources/test_files/runtime/Operational/MultiplicativeOp13.jq +++ b/src/test/resources/test_files/runtime/Operational/MultiplicativeOp13.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(0, 3, 3, 3, 3, 1, 0, 9.1, 1600, 1600, 1.1, 10.1, 0, 10.1, 10.100000381469727, 0, 12300, 8.300000000000432, 0, 0, 0, 12300, 8.299535751342773, 0, 0)" :) +(:JIQS: ShouldRun; Output="(0, 3, 3, 3, 3, 1, 0, 9.1, 1600, 1600, 1.1, 10.1, 0, 10.1, 10.1000003814697265625, 0, 12300, 8.300000000000432, 0, 0, 0, 12300, 8.2995357513427734375, 0, 0)" :) 3 mod 3, 3 mod 10000000000, 3 mod 10.1, From d9a864b779d7bdfd0524b74850f661bb91058e22 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 14:42:35 +0200 Subject: [PATCH 055/142] fn:unorder (unordered -> parser failed) --- .../context/BuiltinFunctionCatalogue.java | 26 ++-- .../general/UnorderedFunctionIterator.java | 125 ++++++++++++++++++ 2 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index bf3d86bae5..299d2d0037 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -71,14 +71,7 @@ import org.rumbledb.runtime.functions.sequences.cardinality.ExactlyOneIterator; import org.rumbledb.runtime.functions.sequences.cardinality.OneOrMoreIterator; import org.rumbledb.runtime.functions.sequences.cardinality.ZeroOrOneIterator; -import org.rumbledb.runtime.functions.sequences.general.EmptyFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.ExistsFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.HeadFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.InsertBeforeFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.RemoveFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.ReverseFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.SubsequenceFunctionIterator; -import org.rumbledb.runtime.functions.sequences.general.TailFunctionIterator; +import org.rumbledb.runtime.functions.sequences.general.*; import org.rumbledb.runtime.functions.sequences.value.DeepEqualFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.DistinctValuesFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.IndexOfFunctionIterator; @@ -609,6 +602,20 @@ private static BuiltinFunction createBuiltinFunction( TailFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); + /** + * function that returns the items of a given sequence + */ + static final BuiltinFunction unordered = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "unorder" + ), + "item*", + "item*", + UnorderedFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + ); /** * function that returns a sequence constructed by inserting an item or a sequence of items at a given position * within an existing sequence @@ -756,6 +763,7 @@ private static BuiltinFunction createBuiltinFunction( DistinctValuesFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); + /** * function that returns indices of items that are equal to the search parameter */ @@ -2442,6 +2450,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(exists.getIdentifier(), exists); builtinFunctions.put(head.getIdentifier(), head); builtinFunctions.put(tail.getIdentifier(), tail); + builtinFunctions.put(unordered.getIdentifier(), unordered); builtinFunctions.put(insert_before.getIdentifier(), insert_before); builtinFunctions.put(remove.getIdentifier(), remove); builtinFunctions.put(reverse.getIdentifier(), reverse); @@ -2454,6 +2463,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(distinct_values1.getIdentifier(), distinct_values1); builtinFunctions.put(distinct_values2.getIdentifier(), distinct_values2); + builtinFunctions.put(index_of1.getIdentifier(), index_of1); builtinFunctions.put(index_of2.getIdentifier(), index_of2); builtinFunctions.put(deep_equal1.getIdentifier(), deep_equal1); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java new file mode 100644 index 0000000000..c2245b09cb --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.runtime.functions.sequences.general; + +import org.apache.spark.api.java.JavaPairRDD; +import org.apache.spark.api.java.JavaRDD; +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.IteratorFlowException; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class UnorderedFunctionIterator extends HybridRuntimeIterator { + + + private static final long serialVersionUID = 1L; + private RuntimeIterator iterator; + private Item nextResult; + + public UnorderedFunctionIterator( + List parameters, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(parameters, executionMode, iteratorMetadata); + this.iterator = this.children.get(0); + } + + @Override + public Item nextLocal() { + if (this.hasNext()) { + Item result = this.nextResult; // save the result to be returned + setNextResult(); // calculate and store the next result + return result; + } + throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "unordered function", getMetadata()); + } + + @Override + public void openLocal() { + this.iterator.open(this.currentDynamicContextForLocalExecution); + + if (!this.iterator.hasNext()) { + this.hasNext = false; + } else { + setNextResult(); + } + } + + @Override + protected void closeLocal() { + this.iterator.close(); + } + + @Override + protected void resetLocal() { + this.iterator.reset(this.currentDynamicContextForLocalExecution); + + if (!this.iterator.hasNext()) { + this.hasNext = false; + } else { + setNextResult(); + } + } + + @Override + protected boolean hasNextLocal() { + return this.hasNext; + } + + public void setNextResult() { + this.nextResult = null; + + if (this.iterator.hasNext()) { + this.nextResult = this.iterator.next(); + } + + if (this.nextResult == null) { + this.hasNext = false; + } else { + this.hasNext = true; + } + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + JavaRDD childRDD = this.iterator.getRDD(context); + return childRDD; + } + + @Override + protected boolean implementsDataFrames() { + return true; + } + + @Override + public JSoundDataFrame getDataFrame(DynamicContext context) { + JSoundDataFrame df = this.iterator.getDataFrame(context); + return df; + } + +} From a299a70b8c9fae99377f50a88376db45bda4eb0a Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 14:51:00 +0200 Subject: [PATCH 056/142] Fix cast string to boolean --- src/main/java/org/rumbledb/runtime/typing/CastIterator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index d43902098a..3a3684affa 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -122,6 +122,9 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (targetType.equals(BuiltinTypesCatalogue.booleanItem)) { if (item.isString()) { + if (item.getDynamicType().isStaticallyCastableAs(BuiltinTypesCatalogue.intItem)) { + return ItemFactory.getInstance().createBooleanItem(item.castToIntValue() != 0); + } return ItemFactory.getInstance() .createBooleanItem(Boolean.parseBoolean(item.getStringValue().trim())); } From 217f4905c8e5b2466219940abc11ddf6a7fc6e26 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 15:04:18 +0200 Subject: [PATCH 057/142] small fix serialize. --- .../runtime/functions/strings/SerializeFunctionIterator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/SerializeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/SerializeFunctionIterator.java index b8f5a26aa4..be4c993ed4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/SerializeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/SerializeFunctionIterator.java @@ -61,7 +61,7 @@ public Item next() { return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); } else { throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " string-join function", + RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " serialize function", getMetadata() ); } From 9adf7db734fd52b8ba0d67f4de80ee3a1b741dd7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 15:09:15 +0200 Subject: [PATCH 058/142] fn:default-collation --- .../context/BuiltinFunctionCatalogue.java | 17 +++++++++++++ .../DefaultCollationFunctionIterator.java | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 299d2d0037..1bca2faf05 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1628,6 +1628,22 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns the value of the default collation property + */ + static final BuiltinFunction default_collation = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "default-collation" + ), + "string", + DefaultCollationFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + + + /** * function that that returns the double representation of the input string or number */ @@ -2530,6 +2546,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(normalize_unicode1.getIdentifier(), normalize_unicode1); builtinFunctions.put(normalize_unicode2.getIdentifier(), normalize_unicode2); builtinFunctions.put(serialize.getIdentifier(), serialize); + builtinFunctions.put(default_collation.getIdentifier(), default_collation); builtinFunctions.put(number0.getIdentifier(), number0); builtinFunctions.put(number1.getIdentifier(), number1); builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java new file mode 100644 index 0000000000..441efecba8 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java @@ -0,0 +1,25 @@ +package org.rumbledb.runtime.functions.strings; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class DefaultCollationFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + public DefaultCollationFunctionIterator( + List children, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createStringItem("http://www.w3.org/2005/xpath-functions/collation/codepoint"); + } +} From 0dd17157bc5ad2b6dfc2c7a1f4ac4c15e8a50ef7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 18:30:57 +0200 Subject: [PATCH 059/142] spotless. ArrayMembers RDD with closure --- .../context/BuiltinFunctionCatalogue.java | 36 ++++++++-------- .../arrays/ArrayMembersFunctionIterator.java | 43 ++++++++++++++----- .../general/UnorderedFunctionIterator.java | 1 - .../DefaultCollationFunctionIterator.java | 3 +- .../navigation/ArrayMembersClosure.java | 32 ++++++++++++++ 5 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 1bca2faf05..ba454aad60 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -606,15 +606,15 @@ private static BuiltinFunction createBuiltinFunction( * function that returns the items of a given sequence */ static final BuiltinFunction unordered = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "unorder" - ), - "item*", - "item*", - UnorderedFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + new Name( + Name.FN_NS, + "fn", + "unorder" + ), + "item*", + "item*", + UnorderedFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that returns a sequence constructed by inserting an item or a sequence of items at a given position @@ -1632,14 +1632,14 @@ private static BuiltinFunction createBuiltinFunction( * function that returns the value of the default collation property */ static final BuiltinFunction default_collation = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "default-collation" - ), - "string", - DefaultCollationFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + new Name( + Name.FN_NS, + "fn", + "default-collation" + ), + "string", + DefaultCollationFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); @@ -2174,7 +2174,7 @@ private static BuiltinFunction createBuiltinFunction( "item*", "item*", ArrayMembersFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that returns the JSON null diff --git a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java index f02c715f5f..e0195116cd 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java @@ -20,19 +20,22 @@ package org.rumbledb.runtime.functions.arrays; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.function.FlatMapFunction; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; +import org.rumbledb.runtime.navigation.ArrayMembersClosure; import java.util.LinkedList; import java.util.List; import java.util.Queue; -public class ArrayMembersFunctionIterator extends LocalFunctionCallIterator { +public class ArrayMembersFunctionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; @@ -45,27 +48,35 @@ public ArrayMembersFunctionIterator( ExceptionMetadata iteratorMetadata ) { super(arguments, executionMode, iteratorMetadata); + this.iterator = this.children.get(0); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); + @Override + protected void openLocal() { this.iterator.open(this.currentDynamicContextForLocalExecution); this.nextResults = new LinkedList<>(); - setNextResult(); } @Override - public void close() { - super.close(); + protected void closeLocal() { this.iterator.close(); } @Override - public Item next() { + protected void resetLocal() { + this.iterator.reset(this.currentDynamicContextForLocalExecution); + setNextResult(); + } + + @Override + protected boolean hasNextLocal() { + return this.hasNext; + } + + @Override + protected Item nextLocal() { if (this.hasNext) { Item result = this.nextResults.remove(); // save the result to be returned if (this.nextResults.isEmpty()) { @@ -94,4 +105,16 @@ public void setNextResult() { this.hasNext = true; } } + + + @Override + public JavaRDD getRDDAux(DynamicContext context) { + JavaRDD childRDD = this.iterator.getRDD(context); + FlatMapFunction transformation = new ArrayMembersClosure(); + JavaRDD resultRDD = childRDD.flatMap(transformation); + return resultRDD; + } + + + } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java index c2245b09cb..d548a16e64 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java @@ -20,7 +20,6 @@ package org.rumbledb.runtime.functions.sequences.general; -import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java index 441efecba8..bb6a12adad 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java @@ -14,7 +14,8 @@ public class DefaultCollationFunctionIterator extends AtMostOneItemLocalRuntimeI public DefaultCollationFunctionIterator( List children, ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata) { + ExceptionMetadata iteratorMetadata + ) { super(children, executionMode, iteratorMetadata); } diff --git a/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java b/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java new file mode 100644 index 0000000000..a35f8f888e --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java @@ -0,0 +1,32 @@ +package org.rumbledb.runtime.navigation; + +import org.apache.spark.api.java.function.FlatMapFunction; +import org.rumbledb.api.Item; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ArrayMembersClosure implements FlatMapFunction { + + private static final long serialVersionUID = 1L; + + public ArrayMembersClosure() { + } + + public Iterator call(Item arg0) throws Exception { + List results = new ArrayList(); + + if (!(arg0.isArray())) { + return results.iterator(); + } else { + for (Item item : arg0.getItems()) { + if (item != null) { + results.add(item); + } + } + } + + return results.iterator(); + } +}; From 8fa3bbb93adb2fbb451f8049b2f9e44ba5088ef8 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 19:55:03 +0200 Subject: [PATCH 060/142] add test members RDD. --- .../runtime/FunctionArray/FunctionArrayMembersRDD1.jq | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq diff --git a/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq b/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq new file mode 100644 index 0000000000..d67c8c81b0 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq @@ -0,0 +1,2 @@ +(:JIQS: ShouldRun; Output="(mercury, venus, earth, mars, 1, 2, 3)" :) +members(parallelize(( "foo", { "foo" : "bar "}, [ "mercury", "venus", "earth", "mars" ], [ 1, 2, 3 ]))) From 6698d3a2c85b22f8d510a30755f77c30100c241d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 4 Jul 2021 21:44:31 +0200 Subject: [PATCH 061/142] spotless. fix cast string to boolean. --- .../context/BuiltinFunctionCatalogue.java | 34 +++++++++---------- .../general/UnorderedFunctionIterator.java | 1 - .../DefaultCollationFunctionIterator.java | 3 +- .../rumbledb/runtime/typing/CastIterator.java | 8 +++-- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 1bca2faf05..785290ac68 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -606,15 +606,15 @@ private static BuiltinFunction createBuiltinFunction( * function that returns the items of a given sequence */ static final BuiltinFunction unordered = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "unorder" - ), - "item*", - "item*", - UnorderedFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT + new Name( + Name.FN_NS, + "fn", + "unorder" + ), + "item*", + "item*", + UnorderedFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that returns a sequence constructed by inserting an item or a sequence of items at a given position @@ -1632,14 +1632,14 @@ private static BuiltinFunction createBuiltinFunction( * function that returns the value of the default collation property */ static final BuiltinFunction default_collation = createBuiltinFunction( - new Name( - Name.FN_NS, - "fn", - "default-collation" - ), - "string", - DefaultCollationFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + new Name( + Name.FN_NS, + "fn", + "default-collation" + ), + "string", + DefaultCollationFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java index c2245b09cb..d548a16e64 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/general/UnorderedFunctionIterator.java @@ -20,7 +20,6 @@ package org.rumbledb.runtime.functions.sequences.general; -import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java index 441efecba8..bb6a12adad 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/DefaultCollationFunctionIterator.java @@ -14,7 +14,8 @@ public class DefaultCollationFunctionIterator extends AtMostOneItemLocalRuntimeI public DefaultCollationFunctionIterator( List children, ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata) { + ExceptionMetadata iteratorMetadata + ) { super(children, executionMode, iteratorMetadata); } diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 3a3684affa..52179ad049 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -2,6 +2,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.CastException; @@ -122,11 +123,12 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (targetType.equals(BuiltinTypesCatalogue.booleanItem)) { if (item.isString()) { - if (item.getDynamicType().isStaticallyCastableAs(BuiltinTypesCatalogue.intItem)) { + if (StringUtils.isNumeric(item.getStringValue())) { return ItemFactory.getInstance().createBooleanItem(item.castToIntValue() != 0); + } else { + return ItemFactory.getInstance() + .createBooleanItem(Boolean.parseBoolean(item.getStringValue().trim())); } - return ItemFactory.getInstance() - .createBooleanItem(Boolean.parseBoolean(item.getStringValue().trim())); } if (item.isInt()) { return ItemFactory.getInstance().createBooleanItem(item.getIntValue() != 0); From 10bac126f715528744e13a5c9d4566ff655a6fab Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 5 Jul 2021 22:39:00 +0200 Subject: [PATCH 062/142] Accumulate AtMostOne with RDD. RDD tests. --- .../ObjectAccumulateFunctionIterator.java | 72 +++++++++++-------- .../Pushdown/ObjectAccumulate1.jq | 5 ++ .../Pushdown/ObjectAccumulate2.jq | 5 ++ .../Pushdown/ObjectAccumulate3.jq | 5 ++ 4 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java index 60e141f292..754fe99f36 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java @@ -20,19 +20,22 @@ package org.rumbledb.runtime.functions.object; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.function.Function; +import org.apache.spark.api.java.function.Function2; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -public class ObjectAccumulateFunctionIterator extends LocalFunctionCallIterator { +public class ObjectAccumulateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { /** * */ @@ -47,37 +50,48 @@ public ObjectAccumulateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - RuntimeIterator sequenceIterator = this.children.get(0); - List items = sequenceIterator.materialize(this.currentDynamicContextForLocalExecution); - LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); - for (Item item : items) { - // ignore non-object items - if (item.isObject()) { - for (String key : item.getKeys()) { - Item value = item.getItemByKey(key); - if (!keyValuePairs.containsKey(key)) { - List valueList = new ArrayList<>(); - valueList.add(value); - keyValuePairs.put(key, valueList); - } - // store values for key collisions in a list - else { - keyValuePairs.get(key).add(value); + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator iterator = this.children.get(0); + + if (!iterator.isDataFrame()) { + if (this.hasNext) { + List items = iterator.materialize(context); + LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); + for (Item item : items) { + // ignore non-object items + if (item.isObject()) { + for (String key : item.getKeys()) { + Item value = item.getItemByKey(key); + if (!keyValuePairs.containsKey(key)) { + List valueList = new ArrayList<>(); + valueList.add(value); + keyValuePairs.put(key, valueList); + } + // store values for key collisions in a list + else { + keyValuePairs.get(key).add(value); + } } } } - } - Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); + Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); - this.hasNext = false; - return result; + this.hasNext = false; + return result; + } } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " ACCUMULATE function", - getMetadata() - ); + + JavaRDD childRDD = iterator.getRDD(context); + Function mapTransformation = new ObjectIntersectMapClosure(); + JavaRDD mapResult = childRDD.map(mapTransformation); + + Function2 reductionTransformation = new ObjectIntersectReduceClosure(); + Item result = mapResult.reduce(reductionTransformation); + + return result; + + } + } diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq new file mode 100644 index 0000000000..68bd65091c --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ "b" : [ 2, [ 2, "xyz" ] ], "c" : [ 3, { "d" : 200 } ] }" :) +accumulate(parallelize(({ "b" : 2 }, { "c" : 3 }, { "b" : [2,"xyz"] }, {"c" : {"d" : 2e+2}}))) + +(: general functionality :) + diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq new file mode 100644 index 0000000000..ae9e67daed --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3 }" :) +accumulate(parallelize(({ "b" : 2 }, { "c" : 3 }))) + +(: no matching keys :) + diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq new file mode 100644 index 0000000000..3f35d191ef --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ }" :) +accumulate(parallelize({})) + +(: empty object :) + From 85e2b8cebed9b79e1c860bcdf6f573133311fa4d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 6 Jul 2021 07:11:20 +0000 Subject: [PATCH 063/142] Members pierre into master-pierre --- .../context/BuiltinFunctionCatalogue.java | 2 +- .../arrays/ArrayMembersFunctionIterator.java | 43 ++++++++++++++----- .../navigation/ArrayMembersClosure.java | 32 ++++++++++++++ .../FunctionArray/FunctionArrayMembersRDD1.jq | 2 + 4 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java create mode 100644 src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 785290ac68..ba454aad60 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -2174,7 +2174,7 @@ private static BuiltinFunction createBuiltinFunction( "item*", "item*", ArrayMembersFunctionIterator.class, - BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + BuiltinFunction.BuiltinFunctionExecutionMode.INHERIT_FROM_FIRST_ARGUMENT ); /** * function that returns the JSON null diff --git a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java index f02c715f5f..e0195116cd 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayMembersFunctionIterator.java @@ -20,19 +20,22 @@ package org.rumbledb.runtime.functions.arrays; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.function.FlatMapFunction; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; +import org.rumbledb.runtime.navigation.ArrayMembersClosure; import java.util.LinkedList; import java.util.List; import java.util.Queue; -public class ArrayMembersFunctionIterator extends LocalFunctionCallIterator { +public class ArrayMembersFunctionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; @@ -45,27 +48,35 @@ public ArrayMembersFunctionIterator( ExceptionMetadata iteratorMetadata ) { super(arguments, executionMode, iteratorMetadata); + this.iterator = this.children.get(0); } - @Override - public void open(DynamicContext context) { - super.open(context); - this.iterator = this.children.get(0); + @Override + protected void openLocal() { this.iterator.open(this.currentDynamicContextForLocalExecution); this.nextResults = new LinkedList<>(); - setNextResult(); } @Override - public void close() { - super.close(); + protected void closeLocal() { this.iterator.close(); } @Override - public Item next() { + protected void resetLocal() { + this.iterator.reset(this.currentDynamicContextForLocalExecution); + setNextResult(); + } + + @Override + protected boolean hasNextLocal() { + return this.hasNext; + } + + @Override + protected Item nextLocal() { if (this.hasNext) { Item result = this.nextResults.remove(); // save the result to be returned if (this.nextResults.isEmpty()) { @@ -94,4 +105,16 @@ public void setNextResult() { this.hasNext = true; } } + + + @Override + public JavaRDD getRDDAux(DynamicContext context) { + JavaRDD childRDD = this.iterator.getRDD(context); + FlatMapFunction transformation = new ArrayMembersClosure(); + JavaRDD resultRDD = childRDD.flatMap(transformation); + return resultRDD; + } + + + } diff --git a/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java b/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java new file mode 100644 index 0000000000..a35f8f888e --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/navigation/ArrayMembersClosure.java @@ -0,0 +1,32 @@ +package org.rumbledb.runtime.navigation; + +import org.apache.spark.api.java.function.FlatMapFunction; +import org.rumbledb.api.Item; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ArrayMembersClosure implements FlatMapFunction { + + private static final long serialVersionUID = 1L; + + public ArrayMembersClosure() { + } + + public Iterator call(Item arg0) throws Exception { + List results = new ArrayList(); + + if (!(arg0.isArray())) { + return results.iterator(); + } else { + for (Item item : arg0.getItems()) { + if (item != null) { + results.add(item); + } + } + } + + return results.iterator(); + } +}; diff --git a/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq b/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq new file mode 100644 index 0000000000..d67c8c81b0 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionArray/FunctionArrayMembersRDD1.jq @@ -0,0 +1,2 @@ +(:JIQS: ShouldRun; Output="(mercury, venus, earth, mars, 1, 2, 3)" :) +members(parallelize(( "foo", { "foo" : "bar "}, [ "mercury", "venus", "earth", "mars" ], [ 1, 2, 3 ]))) From 7c8489afd69a49acece5c7f19b15a282b3412544 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 6 Jul 2021 07:14:56 +0000 Subject: [PATCH 064/142] Accumulate pierre motard into master pierre --- .../ObjectAccumulateFunctionIterator.java | 72 +++++++++++-------- .../Pushdown/ObjectAccumulate1.jq | 5 ++ .../Pushdown/ObjectAccumulate2.jq | 5 ++ .../Pushdown/ObjectAccumulate3.jq | 5 ++ 4 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq create mode 100644 src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq diff --git a/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java index 60e141f292..754fe99f36 100644 --- a/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/object/ObjectAccumulateFunctionIterator.java @@ -20,19 +20,22 @@ package org.rumbledb.runtime.functions.object; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.function.Function; +import org.apache.spark.api.java.function.Function2; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -public class ObjectAccumulateFunctionIterator extends LocalFunctionCallIterator { +public class ObjectAccumulateFunctionIterator extends AtMostOneItemLocalRuntimeIterator { /** * */ @@ -47,37 +50,48 @@ public ObjectAccumulateFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - RuntimeIterator sequenceIterator = this.children.get(0); - List items = sequenceIterator.materialize(this.currentDynamicContextForLocalExecution); - LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); - for (Item item : items) { - // ignore non-object items - if (item.isObject()) { - for (String key : item.getKeys()) { - Item value = item.getItemByKey(key); - if (!keyValuePairs.containsKey(key)) { - List valueList = new ArrayList<>(); - valueList.add(value); - keyValuePairs.put(key, valueList); - } - // store values for key collisions in a list - else { - keyValuePairs.get(key).add(value); + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator iterator = this.children.get(0); + + if (!iterator.isDataFrame()) { + if (this.hasNext) { + List items = iterator.materialize(context); + LinkedHashMap> keyValuePairs = new LinkedHashMap<>(); + for (Item item : items) { + // ignore non-object items + if (item.isObject()) { + for (String key : item.getKeys()) { + Item value = item.getItemByKey(key); + if (!keyValuePairs.containsKey(key)) { + List valueList = new ArrayList<>(); + valueList.add(value); + keyValuePairs.put(key, valueList); + } + // store values for key collisions in a list + else { + keyValuePairs.get(key).add(value); + } } } } - } - Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); + Item result = ItemFactory.getInstance().createObjectItem(keyValuePairs); - this.hasNext = false; - return result; + this.hasNext = false; + return result; + } } - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " ACCUMULATE function", - getMetadata() - ); + + JavaRDD childRDD = iterator.getRDD(context); + Function mapTransformation = new ObjectIntersectMapClosure(); + JavaRDD mapResult = childRDD.map(mapTransformation); + + Function2 reductionTransformation = new ObjectIntersectReduceClosure(); + Item result = mapResult.reduce(reductionTransformation); + + return result; + + } + } diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq new file mode 100644 index 0000000000..68bd65091c --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate1.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ "b" : [ 2, [ 2, "xyz" ] ], "c" : [ 3, { "d" : 200 } ] }" :) +accumulate(parallelize(({ "b" : 2 }, { "c" : 3 }, { "b" : [2,"xyz"] }, {"c" : {"d" : 2e+2}}))) + +(: general functionality :) + diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq new file mode 100644 index 0000000000..ae9e67daed --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate2.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3 }" :) +accumulate(parallelize(({ "b" : 2 }, { "c" : 3 }))) + +(: no matching keys :) + diff --git a/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq new file mode 100644 index 0000000000..3f35d191ef --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/Pushdown/ObjectAccumulate3.jq @@ -0,0 +1,5 @@ +(:JIQS: ShouldRun; Output="{ }" :) +accumulate(parallelize({})) + +(: empty object :) + From 103db13342e820ac5f5b09e22d95721e03a744a7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 6 Jul 2021 16:45:03 +0200 Subject: [PATCH 065/142] fix resolve-uri#0 and add static-base-uri. --- .../context/BuiltinFunctionCatalogue.java | 14 +++++++++ .../strings/ResolveURIFunctionIterator.java | 4 +-- .../StaticBaseURIFunctionIterator.java | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/functions/strings/StaticBaseURIFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index ba454aad60..b14bd9d306 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1489,6 +1489,19 @@ private static BuiltinFunction createBuiltinFunction( ResolveURIFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns the value of the Static Base URI property from the static context. + */ + static final BuiltinFunction static_base_uri = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "static-base-uri" + ), + "anyURI?", + StaticBaseURIFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that checks whether a string ends with a substring */ @@ -2552,6 +2565,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(encode_for_uri.getIdentifier(), encode_for_uri); builtinFunctions.put(resolve_uri1.getIdentifier(), resolve_uri1); builtinFunctions.put(resolve_uri2.getIdentifier(), resolve_uri2); + builtinFunctions.put(static_base_uri.getIdentifier(), static_base_uri); builtinFunctions.put(years_from_duration.getIdentifier(), years_from_duration); builtinFunctions.put(months_from_duration.getIdentifier(), months_from_duration); diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java index a67ef992d2..5bddc2597c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/ResolveURIFunctionIterator.java @@ -27,7 +27,6 @@ public ResolveURIFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { - // StaticContext sc = this.children.get(0).sta Item relative = this.children.get(0).materializeFirstItemOrNull(context); if (relative == null) { return null; @@ -36,8 +35,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (this.children.size() == 2) { base = this.children.get(1).materializeFirstItemOrNull(context); } else { - // Item base = fn-static-context - base = null; + base = ItemFactory.getInstance().createAnyURIItem(this.staticURI.toString()); } if (base == null) { return null; diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StaticBaseURIFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StaticBaseURIFunctionIterator.java new file mode 100644 index 0000000000..d9d30bbde4 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StaticBaseURIFunctionIterator.java @@ -0,0 +1,30 @@ +package org.rumbledb.runtime.functions.strings; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class StaticBaseURIFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public StaticBaseURIFunctionIterator( + List children, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(children, executionMode, iteratorMetadata); + } + + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createAnyURIItem(this.staticURI.toString()); + } +} From 653176f3039d8fa0a2972256142af78149322aff Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 7 Jul 2021 10:53:40 +0200 Subject: [PATCH 066/142] Override. --- src/main/java/org/rumbledb/api/Item.java | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 02ea233d6f..ed8cdbc630 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -160,15 +160,6 @@ default boolean isFloat() { return false; } - /** - * Tests whether the item is an atomic item of type annotatedItem. - * - * @return true if it is an atomic item of type annotatedItem, false otherwise. - */ - default boolean isAnnotatedItemType() { - return false; - } - /** * Tests whether the item is an atomic item of type duration. * @@ -316,7 +307,7 @@ default int getSize() { } /** - * Returns the string value of the item, if it is an atomic type. + * Returns the string value of the item, if it is an atomic item. * * @return the string value. */ @@ -378,15 +369,6 @@ default BigDecimal getDecimalValue() { throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); } - /** - * Returns the AnnotatedItem value of the item, if it is a AnnotatedItem. - * - * @return the AnnotatedItem value. - */ - default long getAnnotatedItemValue() { - throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); - } - /** * Returns the period value of the item, if it is a duration. * From 105db823ccf89895ad64604293544d1970473df5 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 7 Jul 2021 10:54:19 +0200 Subject: [PATCH 067/142] Override. --- src/main/java/org/rumbledb/context/StaticContext.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/rumbledb/context/StaticContext.java b/src/main/java/org/rumbledb/context/StaticContext.java index c02c9a1196..aefd4ee86b 100644 --- a/src/main/java/org/rumbledb/context/StaticContext.java +++ b/src/main/java/org/rumbledb/context/StaticContext.java @@ -391,7 +391,6 @@ public void incrementArities(StaticContext stopContext, Set varToExclude) ); StaticContext current = this.parent; while (current != null && current != stopContext) { - System.err.println("Next loop: " + current); for (Map.Entry entry : current.inScopeVariables.entrySet()) { if (!this.inScopeVariables.containsKey(entry.getKey())) { this.addVariable( From bbb369ac7c385f0fea6c546057715934f2aeac59 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 7 Jul 2021 11:26:49 +0200 Subject: [PATCH 068/142] Fix compilation. --- src/main/java/org/rumbledb/items/DateTimeItem.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/rumbledb/items/DateTimeItem.java b/src/main/java/org/rumbledb/items/DateTimeItem.java index 95443eccb2..8fd0dfa70b 100644 --- a/src/main/java/org/rumbledb/items/DateTimeItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeItem.java @@ -96,11 +96,6 @@ public String getStringValue() { return this.value.toString(); } - @Override - public String getStringValue() { - return this.value.toString(); - } - @Override public boolean hasTimeZone() { return this.hasTimeZone; From 557fbfe05358ffc944e6619cfcca7b2bedc8f837 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 7 Jul 2021 11:27:08 +0200 Subject: [PATCH 069/142] Fix compilation. --- src/main/java/org/rumbledb/items/DateTimeStampItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/items/DateTimeStampItem.java b/src/main/java/org/rumbledb/items/DateTimeStampItem.java index 8338868112..423e678b6c 100644 --- a/src/main/java/org/rumbledb/items/DateTimeStampItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeStampItem.java @@ -36,7 +36,7 @@ public DateTimeStampItem() { } DateTimeStampItem(String dateTimeStampString) { - this.value = parseDateTimeStamp(dateTimeStampString, BuiltinTypesCatalogue.dateTimeStampItem); + this.value = DateTimeItem.parseDateTime(dateTimeStampString, BuiltinTypesCatalogue.dateTimeStampItem); } @Override From 3526e9ff8bfb94e3529a89da78bef34e1d610dde Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 7 Jul 2021 11:27:26 +0200 Subject: [PATCH 070/142] Remove remark. --- .../functions/arrays/ArrayDescendantFunctionIterator.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java index 1797ca247d..86452a2e27 100644 --- a/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/arrays/ArrayDescendantFunctionIterator.java @@ -133,6 +133,4 @@ public JavaRDD getRDDAux(DynamicContext dynamicContext) { FlatMapFunction transformation = new ArrayDescendantClosure(); return childRDD.flatMap(transformation); } - - // can extend dataframe support } From 78543c12ffd661ec3f3c5b5ed4dde57663f38d93 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 7 Jul 2021 19:41:53 +0000 Subject: [PATCH 071/142] annotatedTypes finished. facets solved. --- .../rumbledb/runtime/typing/CastIterator.java | 85 ++++++-------- .../org/rumbledb/types/AtomicItemType.java | 20 ++-- .../rumbledb/types/BuiltinTypesCatalogue.java | 12 +- .../rumbledb/types/DerivedAtomicItemType.java | 104 ------------------ src/main/java/org/rumbledb/types/Facets.java | 24 +++- 5 files changed, 72 insertions(+), 173 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 52179ad049..ea664db765 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -115,6 +115,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isString() && item.getStringValue().trim().equals("null")) { return ItemFactory.getInstance().createNullItem(); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.stringItem)) { @@ -145,6 +146,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isFloat()) { return ItemFactory.getInstance().createBooleanItem(item.getFloatValue() != 0); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.doubleItem)) { @@ -157,6 +159,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.floatItem)) { if (item.isString()) { @@ -168,6 +171,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createFloatItem(item.castToFloatValue()); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.decimalItem)) { @@ -181,6 +185,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createDecimalItem(item.castToDecimalValue()); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.integerItem)) { @@ -194,6 +199,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.intItem)) { @@ -207,6 +213,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createIntItem(item.castToIntValue()); } + return null; } if (targetType.equals(BuiltinTypesCatalogue.anyURIItem)) { @@ -234,53 +241,34 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } - if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.intItem)) { if (!item.isString() && !item.isNumeric()) { - // If it is not a number, we fail (in this method, this is done with a null as the exception will - // only be thrown if the attempt to cast is made in particular circumstances. return null; } - - // Make sure item is string, then cast to primitive type - // Add also if item.isNumeric if (item.isInt()) { - return checkFacetsInteger(item, targetType); + return checkFacetsInt(item, targetType); } - if (item.isInteger()) { - return checkFacetsInteger(item, targetType); + Item intItem = castItemToType(item, BuiltinTypesCatalogue.intItem, metadata); + if (intItem == null) { + return null; } + return checkFacetsInt(intItem, targetType); + } - if (targetType.isSubtypeOf(BuiltinTypesCatalogue.intItem)) { - // If it is not an integer we need to cast it to an integer first (long's primitive type), and then - // annotate. - Item intItem = castItemToType(item, BuiltinTypesCatalogue.intItem, metadata); - if (intItem == null) { - return null; - } - // if (item.isInt()) { - return checkFacetsInt(intItem, targetType); - // } + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { + if (!item.isString() && !item.isNumeric()) { + return null; } - - if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { - // If it is not an integer we need to cast it to an integer first (long's primitive type), and then - // annotate as long. - Item integerItem = castItemToType(item, BuiltinTypesCatalogue.integerItem, metadata); - if (integerItem == null) { - // xs:positiveInteger("23.4") goes here - return null; - } - - // if (item.isInteger()) { removed to support casting decimals eg xs:positiveInteger(1.4) gives 1 - return checkFacetsInteger(integerItem, targetType); + if (item.isInteger()) { + return checkFacetsInteger(item, targetType); } - return ItemFactory.getInstance() - .createAnnotatedItem( - item, - targetType - ); + Item integerItem = castItemToType(item, BuiltinTypesCatalogue.integerItem, metadata); + if (integerItem == null) { + return null; + } + return checkFacetsInteger(integerItem, targetType); } if (targetType.equals(BuiltinTypesCatalogue.dateItem)) { @@ -377,37 +365,34 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } public static Item checkFacetsInt(Item item, ItemType targetType) { - // Use castToInt rather than getInt so it supports String item - // compare returns -1 if less, 0 if eq, 1 if greater so <= 0 tests for less or equal - if ( (targetType.getMinInclusiveFacet() != null && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) || (targetType.getMaxInclusiveFacet() != null && item.getIntValue() > targetType.getMaxInclusiveFacet().getIntValue()) - // || (targetType.getMinExclusiveFacet() != null && item.getIntValue() <= - // targetType.getMinExclusiveFacet().getIntValue()) - // || (targetType.getMaxExclusiveFacet() != null && item.getIntValue() >= - // targetType.getMaxExclusiveFacet().getIntValue()) + || (targetType.getMinExclusiveFacet() != null + && item.getIntValue() <= targetType.getMinExclusiveFacet().getIntValue()) + || (targetType.getMaxExclusiveFacet() != null + && item.getIntValue() <= targetType.getMaxExclusiveFacet().getIntValue()) ) { return null; } + return ItemFactory.getInstance().createAnnotatedItem(item, targetType); } public static Item checkFacetsInteger(Item item, ItemType targetType) { - // Use castToInt rather than getInt so it supports String item - // compare returns -1 if less, 0 if eq, 1 if greater so <= 0 tests for less or equal - if ( (targetType.getMinInclusiveFacet() != null && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) || (targetType.getMaxInclusiveFacet() != null && item.getIntegerValue().compareTo(targetType.getMaxInclusiveFacet().getIntegerValue()) == 1) - // || (targetType.getMinExclusiveFacet() != null && - // item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) - // || (targetType.getMaxExclusiveFacet() != null && - // item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) + || (targetType.getMinExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) + || (targetType.getMaxExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) ) { return null; } diff --git a/src/main/java/org/rumbledb/types/AtomicItemType.java b/src/main/java/org/rumbledb/types/AtomicItemType.java index 73a3aa4106..b887c6fe04 100644 --- a/src/main/java/org/rumbledb/types/AtomicItemType.java +++ b/src/main/java/org/rumbledb/types/AtomicItemType.java @@ -51,7 +51,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, + FacetTypes.MAXEXCLUSIVE, FacetTypes.TOTALDIGITS, FacetTypes.FRACTIONDIGITS ) @@ -67,7 +67,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE + FacetTypes.MAXEXCLUSIVE ) ), DataTypes.DoubleType @@ -81,7 +81,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE + FacetTypes.MAXEXCLUSIVE ) ), DataTypes.FloatType @@ -106,7 +106,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE + FacetTypes.MAXEXCLUSIVE ) ), DataTypes.BinaryType // TODO : appropriate datatype @@ -120,7 +120,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE + FacetTypes.MAXEXCLUSIVE ) ), DataTypes.BinaryType // TODO : appropriate datatype @@ -134,7 +134,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE + FacetTypes.MAXEXCLUSIVE ) ), DataTypes.BinaryType // TODO : appropriate datatype @@ -148,7 +148,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, + FacetTypes.MAXEXCLUSIVE, FacetTypes.EXPLICITTIMEZONE ) ), @@ -163,7 +163,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, + FacetTypes.MAXEXCLUSIVE, FacetTypes.EXPLICITTIMEZONE ) ), @@ -178,7 +178,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, + FacetTypes.MAXEXCLUSIVE, FacetTypes.EXPLICITTIMEZONE ) ), @@ -193,7 +193,7 @@ public class AtomicItemType implements ItemType { FacetTypes.MININCLUSIVE, FacetTypes.MAXINCLUSIVE, FacetTypes.MINEXCLUSIVE, - FacetTypes.MAXINCLUSIVE, + FacetTypes.MAXEXCLUSIVE, FacetTypes.EXPLICITTIMEZONE ) ), diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 7625b02ab4..7aab6e6c99 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -286,9 +286,8 @@ public class BuiltinTypesCatalogue { new Name(Name.XS_NS, "xs", "nonNegativeInteger"), integerItem, AtomicItemType.decimalItem, - Facets.createMinMaxFacets( + Facets.createMinFacets( new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("9223372036854775808")), true ), false, @@ -299,8 +298,7 @@ public class BuiltinTypesCatalogue { new Name(Name.XS_NS, "xs", "nonPositiveInteger"), integerItem, AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("-9223372036854775808")), + Facets.createMaxFacets( new IntegerItem(new BigInteger("0")), true ), @@ -312,8 +310,7 @@ public class BuiltinTypesCatalogue { new Name(Name.XS_NS, "xs", "negativeInteger"), nonPositiveIntegerItem, AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("-9223372036854775808")), + Facets.createMaxFacets( new IntegerItem(new BigInteger("-1")), true ), @@ -325,9 +322,8 @@ public class BuiltinTypesCatalogue { new Name(Name.XS_NS, "xs", "positiveInteger"), nonNegativeIntegerItem, AtomicItemType.decimalItem, - Facets.createMinMaxFacets( + Facets.createMinFacets( new IntegerItem(new BigInteger("1")), - new IntegerItem(new BigInteger("9223372036854775807")), true ), false, diff --git a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java index e943723676..c8ab7bc43f 100644 --- a/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java +++ b/src/main/java/org/rumbledb/types/DerivedAtomicItemType.java @@ -38,58 +38,6 @@ public class DerivedAtomicItemType implements ItemType { DataTypes.LongType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType nonNegativeIntegerItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "nonNegativeInteger"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("9223372036854775808")), - true - ), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType nonPositiveIntegerItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "nonPositiveInteger"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("-9223372036854775808")), - new IntegerItem(new BigInteger("0")), - true - ), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType negativeIntegerItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "negativeInteger"), - nonPositiveIntegerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("-9223372036854775808")), - new IntegerItem(new BigInteger("-1")), - true - ), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType positiveIntegerItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "positiveInteger"), - nonNegativeIntegerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("1")), - new IntegerItem(new BigInteger("9223372036854775807")), - true - ), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - static final DerivedAtomicItemType intItem = new DerivedAtomicItemType( Name.createVariableInDefaultTypeNamespace("int"), longItem, @@ -108,58 +56,6 @@ public class DerivedAtomicItemType implements ItemType { DataTypes.ShortType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "byte"), - intItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets(new IntItem(-128), new IntItem(127), true), - false, - DataTypes.ByteType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedInt"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("4294967295")), - true - ), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedLong"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets( - new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("18446744073709551615")), - true - ), - false, - DataTypes.LongType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedShort"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets(new IntItem(0), new IntItem(65535), true), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); - - static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedByte"), - integerItem, - AtomicItemType.decimalItem, - Facets.createMinMaxFacets(new IntItem(0), new IntItem(255), true), - false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer - ); private final ItemType baseType, primitiveType; private final int typeTreeDepth; diff --git a/src/main/java/org/rumbledb/types/Facets.java b/src/main/java/org/rumbledb/types/Facets.java index 964e092e2c..29596689a8 100644 --- a/src/main/java/org/rumbledb/types/Facets.java +++ b/src/main/java/org/rumbledb/types/Facets.java @@ -32,7 +32,28 @@ public static Facets createMinMaxFacets(Item min, Item max, boolean isInclusive) return facets; } - private Item minInclusive, maxInclusive, minExclusive, maxExclusive; + public static Facets createMinFacets(Item min, boolean isInclusive) { + Facets facets = new Facets(); + if (isInclusive) { + facets.setMinInclusive(min); + } else { + facets.setMinExclusive(min); + } + return facets; + } + + public static Facets createMaxFacets(Item max, boolean isInclusive) { + Facets facets = new Facets(); + if (isInclusive) { + facets.setMaxInclusive(max); + } else { + facets.setMaxExclusive(max); + } + return facets; + } + + private Item minInclusive, maxInclusive; + private Item minExclusive, maxExclusive; private Integer minLength, length, maxLength, totalDigits, fractionDigits; private List constraints = Collections.emptyList(); private List enumeration; @@ -74,6 +95,7 @@ public void setMaxExclusive(Item maxExclusive) { this.maxExclusive = maxExclusive; } + public Integer getMinLength() { return this.minLength; } From 9d7a3b9020a65f661894db523288bce5c29e8435 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 9 Jul 2021 18:31:04 +0000 Subject: [PATCH 072/142] Gregorian dateTypes --- src/main/java/org/rumbledb/api/Item.java | 46 ++++ .../context/BuiltinFunctionCatalogue.java | 14 ++ .../java/org/rumbledb/items/ItemFactory.java | 20 ++ .../java/org/rumbledb/items/gDayItem.java | 186 ++++++++++++++++ .../org/rumbledb/items/gMonthDayItem.java | 190 ++++++++++++++++ .../java/org/rumbledb/items/gMonthItem.java | 190 ++++++++++++++++ .../java/org/rumbledb/items/gYearItem.java | 200 +++++++++++++++++ .../org/rumbledb/items/gYearMonthItem.java | 208 ++++++++++++++++++ .../booleans/NotFunctionIterator.java | 54 +++++ .../runtime/misc/ComparisonIterator.java | 25 +++ .../rumbledb/runtime/typing/CastIterator.java | 31 +++ .../rumbledb/types/BuiltinTypesCatalogue.java | 80 +++++++ .../java/org/rumbledb/types/SequenceType.java | 16 ++ 13 files changed, 1260 insertions(+) create mode 100644 src/main/java/org/rumbledb/items/gDayItem.java create mode 100644 src/main/java/org/rumbledb/items/gMonthDayItem.java create mode 100644 src/main/java/org/rumbledb/items/gMonthItem.java create mode 100644 src/main/java/org/rumbledb/items/gYearItem.java create mode 100644 src/main/java/org/rumbledb/items/gYearMonthItem.java create mode 100644 src/main/java/org/rumbledb/runtime/functions/booleans/NotFunctionIterator.java diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 02ea233d6f..66232f17e1 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -223,6 +223,52 @@ default boolean isTime() { return false; } + /** + * Tests whether the item is an atomic item of type gDay. + * + * @return true if it is an atomic item of type gDay, false otherwise. + */ + default boolean isGDay() { + return false; + } + + /** + * Tests whether the item is an atomic item of type gMonth. + * + * @return true if it is an atomic item of type gMonth, false otherwise. + */ + default boolean isGMonth() { + return false; + } + + /** + * Tests whether the item is an atomic item of type gYear. + * + * @return true if it is an atomic item of type gYear, false otherwise. + */ + default boolean isGYear() { + return false; + } + + /** + * Tests whether the item is an atomic item of type gMonthDay. + * + * @return true if it is an atomic item of type gMonthDay, false otherwise. + */ + default boolean isGMonthDay() { + return false; + } + + /** + * Tests whether the item is an atomic item of type gMonthDay. + * + * @return true if it is an atomic item of type gMonthDay, false otherwise. + */ + default boolean isGYearMonth() { + return false; + } + + /** * Tests whether the item is an atomic item of type anyURI. * diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index b14bd9d306..8bea5ce37d 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -11,6 +11,7 @@ import org.rumbledb.runtime.functions.arrays.ArrayMembersFunctionIterator; import org.rumbledb.runtime.functions.arrays.ArraySizeFunctionIterator; import org.rumbledb.runtime.functions.booleans.BooleanFunctionIterator; +import org.rumbledb.runtime.functions.booleans.NotFunctionIterator; import org.rumbledb.runtime.functions.context.LastFunctionIterator; import org.rumbledb.runtime.functions.context.PositionFunctionIterator; import org.rumbledb.runtime.functions.datetime.CurrentDateFunctionIterator; @@ -492,6 +493,18 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns true if the effective boolean value of the given parameter is false, and false if it is + * true. + */ + static final BuiltinFunction not_function = createBuiltinFunction( + new Name(Name.FN_NS, "fn", "not"), + "item*", + "boolean", + NotFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + /** * function that returns the minimum of a sequence */ @@ -2466,6 +2479,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(count.getIdentifier(), count); builtinFunctions.put(boolean_function.getIdentifier(), boolean_function); + builtinFunctions.put(not_function.getIdentifier(), not_function); builtinFunctions.put(min1.getIdentifier(), min1); builtinFunctions.put(min2.getIdentifier(), min2); diff --git a/src/main/java/org/rumbledb/items/ItemFactory.java b/src/main/java/org/rumbledb/items/ItemFactory.java index 9aa41c26ac..fd210d95b0 100644 --- a/src/main/java/org/rumbledb/items/ItemFactory.java +++ b/src/main/java/org/rumbledb/items/ItemFactory.java @@ -145,6 +145,26 @@ public Item createTimeItem(String s) { return new TimeItem(s); } + public Item createGDayItem(String s) { + return new gDayItem(s); + } + + public Item createGMonthItem(String s) { + return new gMonthItem(s); + } + + public Item createGYearItem(String s) { + return new gYearItem(s); + } + + public Item createGMonthDayItem(String s) { + return new gMonthDayItem(s); + } + + public Item createGYearMonthItem(String s) { + return new gYearMonthItem(s); + } + public Item createAnyURIItem(String s) { return new AnyURIItem(s); } diff --git a/src/main/java/org/rumbledb/items/gDayItem.java b/src/main/java/org/rumbledb/items/gDayItem.java new file mode 100644 index 0000000000..2798cacb92 --- /dev/null +++ b/src/main/java/org/rumbledb/items/gDayItem.java @@ -0,0 +1,186 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + + +public class gDayItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + + private static final String gDayLexicalRep = "---" + dayFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern gDayPattern = Pattern.compile(gDayLexicalRep); + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + + private static final long serialVersionUID = 1L; + private String value; + private DateTime dt; + private boolean hasTimeZone = true; + + public gDayItem() { + super(); + } + + gDayItem(String gDayString) { + this.value = gDayItem.parseGDay(gDayString, BuiltinTypesCatalogue.gDayItem); + String dayZone = this.value.substring(3); + if (dayZone.length() == 2) { + this.hasTimeZone = false; + } + String startingDate = "1972-01-".concat(dayZone); + startingDate = fixEndOfDay(startingDate); + this.dt = new DateItem(startingDate).getDateTimeValue(); + } + + + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public String getValue() { + return this.value; + } + + @Override + public String getStringValue() { + return this.serialize(); + } + + @Override + public DateTime getDateTimeValue() { + return this.dt; + } + + @Override + public boolean isGDay() { + return true; + } + + @Override + public String serialize() { + String zone = this.getDateTimeValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getDateTimeValue().getZone().toString(); + return this.value.substring(0, 5) + (this.hasTimeZone ? zone : ""); + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + this.hasTimeZone = input.readBoolean(); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.dt = new DateTime(millis, zone); + } + + private static boolean checkInvalidGDayFormat(String gDay, ItemType gDayType) { + if (gDayType.equals(BuiltinTypesCatalogue.gDayItem)) { + return gDayPattern.matcher(gDay).matches(); + } + if (gDayType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(gDay).matches(); + } + if (gDayType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(gDay).matches(); + } + return false; + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.gDayItem; + } + + @Override + public boolean isAtomic() { + return true; + } + + static String parseGDay(String gDay, ItemType gDayType) throws IllegalArgumentException { + if (!checkInvalidGDayFormat(gDay, gDayType)) { + throw new IllegalArgumentException(); + } + return gDay; + } + + private static String fixEndOfDay(String dateTime) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTime.contains(endOfDay)) { + if (dateTime.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTime.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTime.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTime.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTime.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTime.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTime.substring(indexOfT + endOfDay.length() + 1); + } + return dateTime; + } +} diff --git a/src/main/java/org/rumbledb/items/gMonthDayItem.java b/src/main/java/org/rumbledb/items/gMonthDayItem.java new file mode 100644 index 0000000000..83dfdd511c --- /dev/null +++ b/src/main/java/org/rumbledb/items/gMonthDayItem.java @@ -0,0 +1,190 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + +public class gMonthDayItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + + private static final String gMonthDayLexicalRep = "--" + monthFrag + "-" + dayFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern gMonthDayPattern = Pattern.compile(gMonthDayLexicalRep); + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + + private static final long serialVersionUID = 1L; + private String value; + private DateTime dt; + private boolean hasTimeZone = true; + + public gMonthDayItem() { + super(); + } + + gMonthDayItem(String gMonthDayString) { + this.value = gMonthDayItem.parseGMonthDay(gMonthDayString, BuiltinTypesCatalogue.gMonthDayItem); + String monthDay = this.value.substring(2, 7); + + String startingDate; + if (gMonthDayString.length() == 7) { + this.hasTimeZone = false; + startingDate = "1972-".concat(monthDay); + } else { + String zone = this.value.substring(7); + startingDate = "1972-".concat(monthDay).concat(zone); + } + startingDate = fixEndOfDay(startingDate); + this.dt = new DateItem(startingDate).getDateTimeValue(); + } + + + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public String getValue() { + return this.value; + } + + @Override + public String getStringValue() { + return this.serialize(); + } + + @Override + public DateTime getDateTimeValue() { + return this.dt; + } + + @Override + public boolean isGMonthDay() { + return true; + } + + @Override + public String serialize() { + String zone = this.getDateTimeValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getDateTimeValue().getZone().toString(); + return this.value.substring(0, 7) + (this.hasTimeZone ? zone : ""); + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + this.hasTimeZone = input.readBoolean(); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.dt = new DateTime(millis, zone); + } + + private static boolean checkInvalidGMonthDayFormat(String gMonthDay, ItemType gMonthDayType) { + if (gMonthDayType.equals(BuiltinTypesCatalogue.gMonthDayItem)) { + return gMonthDayPattern.matcher(gMonthDay).matches(); + } + if (gMonthDayType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(gMonthDay).matches(); + } + if (gMonthDayType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(gMonthDay).matches(); + } + return false; + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.gMonthDayItem; + } + + @Override + public boolean isAtomic() { + return true; + } + + static String parseGMonthDay(String gMonthDay, ItemType gMonthDayType) throws IllegalArgumentException { + if (!checkInvalidGMonthDayFormat(gMonthDay, gMonthDayType)) { + throw new IllegalArgumentException(); + } + return gMonthDay; + } + + private static String fixEndOfDay(String dateTime) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTime.contains(endOfDay)) { + if (dateTime.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTime.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTime.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTime.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTime.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTime.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTime.substring(indexOfT + endOfDay.length() + 1); + } + return dateTime; + } +} diff --git a/src/main/java/org/rumbledb/items/gMonthItem.java b/src/main/java/org/rumbledb/items/gMonthItem.java new file mode 100644 index 0000000000..9c6c760978 --- /dev/null +++ b/src/main/java/org/rumbledb/items/gMonthItem.java @@ -0,0 +1,190 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + +public class gMonthItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + + private static final String gMonthLexicalRep = "--" + monthFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern gMonthPattern = Pattern.compile(gMonthLexicalRep); + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + + private static final long serialVersionUID = 1L; + private String value; + private DateTime dt; + private boolean hasTimeZone = true; + + public gMonthItem() { + super(); + } + + gMonthItem(String gMonthString) { + this.value = gMonthItem.parseGMonth(gMonthString, BuiltinTypesCatalogue.gMonthItem); + + String month = this.value.substring(2, 4); + String startingDate; + if (gMonthString.length() <= 4) { + this.hasTimeZone = false; + startingDate = "1972-".concat(month).concat("-01"); + } else { + String zone = this.value.substring(4); + startingDate = "1972-".concat(month).concat("-01").concat(zone); + } + startingDate = fixEndOfDay(startingDate); + this.dt = new DateItem(startingDate).getDateTimeValue(); + } + + + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public String getValue() { + return this.value; + } + + @Override + public String getStringValue() { + return this.serialize(); + } + + @Override + public DateTime getDateTimeValue() { + return this.dt; + } + + @Override + public boolean isGMonth() { + return true; + } + + @Override + public String serialize() { + String zone = this.getDateTimeValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getDateTimeValue().getZone().toString(); + return this.value.substring(0, 4) + (this.hasTimeZone ? zone : ""); + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + this.hasTimeZone = input.readBoolean(); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.dt = new DateTime(millis, zone); + } + + private static boolean checkInvalidGMonthFormat(String gMonth, ItemType gMonthType) { + if (gMonthType.equals(BuiltinTypesCatalogue.gMonthItem)) { + return gMonthPattern.matcher(gMonth).matches(); + } + if (gMonthType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(gMonth).matches(); + } + if (gMonthType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(gMonth).matches(); + } + return false; + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.gMonthItem; + } + + @Override + public boolean isAtomic() { + return true; + } + + static String parseGMonth(String gMonth, ItemType gMonthType) throws IllegalArgumentException { + if (!checkInvalidGMonthFormat(gMonth, gMonthType)) { + throw new IllegalArgumentException(); + } + return gMonth; + } + + private static String fixEndOfDay(String dateTime) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTime.contains(endOfDay)) { + if (dateTime.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTime.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTime.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTime.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTime.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTime.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTime.substring(indexOfT + endOfDay.length() + 1); + } + return dateTime; + } +} diff --git a/src/main/java/org/rumbledb/items/gYearItem.java b/src/main/java/org/rumbledb/items/gYearItem.java new file mode 100644 index 0000000000..8eea5b5664 --- /dev/null +++ b/src/main/java/org/rumbledb/items/gYearItem.java @@ -0,0 +1,200 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + +public class gYearItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + + private static final String gYearLexicalRep = "(" + "-" + ")?" + yearFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern gYearPattern = Pattern.compile(gYearLexicalRep); + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + + private static final long serialVersionUID = 1L; + private String value; + private DateTime dt; + private boolean hasTimeZone = true; + + public gYearItem() { + super(); + } + + gYearItem(String gYearString) { + this.value = gYearItem.parseGYear(gYearString, BuiltinTypesCatalogue.gYearItem); + boolean hasDash; + String year; + if (gYearString.startsWith("-")) { + hasDash = true; + year = this.value.substring(1, 5); + } else { + hasDash = false; + year = this.value.substring(0, 4); + } + + String startingDate; + if ((hasDash && gYearString.length() == 5) || (!hasDash && gYearString.length() == 4)) { + this.hasTimeZone = false; + startingDate = year.concat("-01-01"); + } else { + String zone = hasDash ? this.value.substring(5) : this.value.substring(4); + startingDate = year.concat("-01-01").concat(zone); + } + + startingDate = fixEndOfDay(startingDate); + this.dt = new DateItem(startingDate).getDateTimeValue(); + } + + + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public String getValue() { + return this.value; + } + + @Override + public String getStringValue() { + return this.serialize(); + } + + @Override + public DateTime getDateTimeValue() { + return this.dt; + } + + @Override + public boolean isGYear() { + return true; + } + + @Override + public String serialize() { + String zone = this.getDateTimeValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getDateTimeValue().getZone().toString(); + return (this.value.startsWith("-") ? this.value.substring(0, 5) : this.value.substring(0, 4)) + + (this.hasTimeZone ? zone : ""); + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + this.hasTimeZone = input.readBoolean(); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.dt = new DateTime(millis, zone); + } + + private static boolean checkInvalidGYearFormat(String gYear, ItemType gYearType) { + if (gYearType.equals(BuiltinTypesCatalogue.gYearItem)) { + return gYearPattern.matcher(gYear).matches(); + } + if (gYearType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(gYear).matches(); + } + if (gYearType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(gYear).matches(); + } + return false; + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.gYearItem; + } + + @Override + public boolean isAtomic() { + return true; + } + + static String parseGYear(String gYear, ItemType gYearType) throws IllegalArgumentException { + if (!checkInvalidGYearFormat(gYear, gYearType)) { + throw new IllegalArgumentException(); + } + return gYear; + } + + private static String fixEndOfDay(String dateTime) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTime.contains(endOfDay)) { + if (dateTime.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTime.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTime.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTime.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTime.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTime.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTime.substring(indexOfT + endOfDay.length() + 1); + } + return dateTime; + } +} diff --git a/src/main/java/org/rumbledb/items/gYearMonthItem.java b/src/main/java/org/rumbledb/items/gYearMonthItem.java new file mode 100644 index 0000000000..2448c29c83 --- /dev/null +++ b/src/main/java/org/rumbledb/items/gYearMonthItem.java @@ -0,0 +1,208 @@ +package org.rumbledb.items; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; +import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; + +import java.util.regex.Pattern; + +public class gYearMonthItem implements Item { + + private static final String yearFrag = "((-)?(([1-9]\\d\\d(\\d)+)|(0\\d\\d\\d)))"; + private static final String monthFrag = "((0[1-9])|(1[0-2]))"; + private static final String dayFrag = "((0[1-9])|([1-2]\\d)|(3[0-1]))"; + private static final String hourFrag = "(([0-1]\\d)|(2[0-3]))"; + private static final String minuteFrag = "([0-5]\\d)"; + private static final String secondFrag = "(([0-5]\\d)(\\.(\\d)+)?)"; + private static final String endOfDayFrag = "(24:00:00(\\.(0)+)?)"; + private static final String timezoneFrag = "(Z|([+\\-])(((0\\d|1[0-3]):" + minuteFrag + ")|(14:00)))"; + private static final String dateFrag = "(" + yearFrag + '-' + monthFrag + '-' + dayFrag + ")"; + private static final String timeFrag = "((" + + hourFrag + + ":" + + minuteFrag + + ":" + + secondFrag + + ")|(" + + endOfDayFrag + + "))"; + + + private static final String gYearMonthLexicalRep = "(" + + "-" + + ")?" + + yearFrag + + "-" + + monthFrag + + "(" + + timezoneFrag + + ")?"; + private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; + + private static final Pattern gYearMonthPattern = Pattern.compile(gYearMonthLexicalRep); + private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern datePattern = Pattern.compile(dateLexicalRep); + + private static final long serialVersionUID = 1L; + private String value; + private DateTime dt; + private boolean hasTimeZone = true; + + public gYearMonthItem() { + super(); + } + + gYearMonthItem(String gYearMonthString) { + this.value = gYearMonthItem.parseGYearMonth(gYearMonthString, BuiltinTypesCatalogue.gYearMonthItem); + boolean hasDash; + String yearMonth; + if (gYearMonthString.startsWith("-")) { + hasDash = true; + yearMonth = this.value.substring(1, 8); + } else { + hasDash = false; + yearMonth = this.value.substring(0, 7); + } + + String startingDate; + if ((hasDash && gYearMonthString.length() == 8) || (!hasDash && gYearMonthString.length() == 7)) { + this.hasTimeZone = false; + startingDate = yearMonth.concat("-01"); + } else { + String zone = hasDash ? this.value.substring(8) : this.value.substring(7); + startingDate = yearMonth.concat("-01").concat(zone); + } + + startingDate = fixEndOfDay(startingDate); + this.dt = new DateItem(startingDate).getDateTimeValue(); + } + + + + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof Item) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + + public String getValue() { + return this.value; + } + + @Override + public String getStringValue() { + return this.serialize(); + } + + @Override + public DateTime getDateTimeValue() { + return this.dt; + } + + @Override + public boolean isGYearMonth() { + return true; + } + + @Override + public String serialize() { + String zone = this.getDateTimeValue().getZone() == DateTimeZone.UTC + ? "Z" + : this.getDateTimeValue().getZone().toString(); + return (this.value.startsWith("-") ? this.value.substring(0, 8) : this.value.substring(0, 7)) + + (this.hasTimeZone ? zone : ""); + } + + @Override + public void write(Kryo kryo, Output output) { + output.writeLong(this.getDateTimeValue().getMillis(), true); + output.writeString(this.getDateTimeValue().getZone().getID()); + } + + @Override + public void read(Kryo kryo, Input input) { + Long millis = input.readLong(true); + this.hasTimeZone = input.readBoolean(); + DateTimeZone zone = DateTimeZone.forID(input.readString()); + this.dt = new DateTime(millis, zone); + } + + private static boolean checkInvalidGYearMonthFormat(String gYearMonth, ItemType gYearMonthType) { + if (gYearMonthType.equals(BuiltinTypesCatalogue.gYearMonthItem)) { + return gYearMonthPattern.matcher(gYearMonth).matches(); + } + if (gYearMonthType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + return dateTimePattern.matcher(gYearMonth).matches(); + } + if (gYearMonthType.equals(BuiltinTypesCatalogue.dateItem)) { + return datePattern.matcher(gYearMonth).matches(); + } + return false; + } + + @Override + public ItemType getDynamicType() { + return BuiltinTypesCatalogue.gYearMonthItem; + } + + @Override + public boolean isAtomic() { + return true; + } + + static String parseGYearMonth(String gYearMonth, ItemType gYearMonthType) throws IllegalArgumentException { + if (!checkInvalidGYearMonthFormat(gYearMonth, gYearMonthType)) { + throw new IllegalArgumentException(); + } + return gYearMonth; + } + + private static String fixEndOfDay(String dateTime) { + String endOfDay = "24:00:00"; + String startOfDay = "00:00:00"; + if (dateTime.contains(endOfDay)) { + if (dateTime.indexOf(endOfDay) == 0) { + return startOfDay; + } + int indexOfT = dateTime.indexOf('T'); + if ( + indexOfT < 1 + || indexOfT != dateTime.indexOf(endOfDay) - 1 + || !Character.isDigit(dateTime.charAt(indexOfT - 1)) + ) { + throw new IllegalArgumentException(); + } + int dayValue; + try { + dayValue = Character.getNumericValue(dateTime.charAt(indexOfT - 1)); + } catch (Exception e) { + throw new IllegalArgumentException(); + } + return dateTime.substring(0, indexOfT - 1) + + + (dayValue + 1) + + "T" + + startOfDay + + + dateTime.substring(indexOfT + endOfDay.length() + 1); + } + return dateTime; + } +} diff --git a/src/main/java/org/rumbledb/runtime/functions/booleans/NotFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/booleans/NotFunctionIterator.java new file mode 100644 index 0000000000..ca3094c15e --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/booleans/NotFunctionIterator.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.runtime.functions.booleans; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class NotFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public NotFunctionIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + RuntimeIterator iterator = this.children.get(0); + boolean effectiveBooleanValue = iterator.getEffectiveBooleanValue( + context + ); + return ItemFactory.getInstance().createBooleanItem(!effectiveBooleanValue); + } + +} diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 146639c882..2a66f1cfb2 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -315,6 +315,31 @@ public static long compareItems( DateTime r = right.getDateTimeValue(); return processDateTime(l, r); } + if (left.isGDay() && right.isGDay()) { + DateTime l = left.getDateTimeValue(); + DateTime r = right.getDateTimeValue(); + return processDateTime(l, r); + } + if (left.isGMonth() && right.isGMonth()) { + DateTime l = left.getDateTimeValue(); + DateTime r = right.getDateTimeValue(); + return processDateTime(l, r); + } + if (left.isGYear() && right.isGYear()) { + DateTime l = left.getDateTimeValue(); + DateTime r = right.getDateTimeValue(); + return processDateTime(l, r); + } + if (left.isGMonthDay() && right.isGMonthDay()) { + DateTime l = left.getDateTimeValue(); + DateTime r = right.getDateTimeValue(); + return processDateTime(l, r); + } + if (left.isGYearMonth() && right.isGYearMonth()) { + DateTime l = left.getDateTimeValue(); + DateTime r = right.getDateTimeValue(); + return processDateTime(l, r); + } if (left.isBoolean() && right.isBoolean()) { Boolean l = left.getBooleanValue(); Boolean r = right.getBooleanValue(); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index ea664db765..e0a024b2f4 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -358,6 +358,37 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } + if (targetType.equals(BuiltinTypesCatalogue.gDayItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createGDayItem(item.getStringValue().trim()); + } + return null; + } + if (targetType.equals(BuiltinTypesCatalogue.gMonthItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createGMonthItem(item.getStringValue().trim()); + } + return null; + } + if (targetType.equals(BuiltinTypesCatalogue.gYearItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createGYearItem(item.getStringValue().trim()); + } + return null; + } + if (targetType.equals(BuiltinTypesCatalogue.gMonthDayItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createGMonthDayItem(item.getStringValue().trim()); + } + return null; + } + if (targetType.equals(BuiltinTypesCatalogue.gYearMonthItem)) { + if (item.isString()) { + return ItemFactory.getInstance().createGYearMonthItem(item.getStringValue().trim()); + } + return null; + } + return null; } catch (Exception e) { return null; diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 7aab6e6c99..89b2679f38 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -193,6 +193,81 @@ public class BuiltinTypesCatalogue { ), DataTypes.TimestampType ); + public static final ItemType gDayItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "gDay"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); + public static final ItemType gMonthItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "gMonth"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); + public static final ItemType gYearItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "gYear"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); + public static final ItemType gMonthDayItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "gMonthDay"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); + public static final ItemType gYearMonthItem = new AtomicItemType( + new Name(Name.XS_NS, "xs", "gYearMonth"), + new HashSet<>( + Arrays.asList( + FacetTypes.ENUMERATION, + FacetTypes.CONSTRAINTS, + FacetTypes.MININCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.MINEXCLUSIVE, + FacetTypes.MAXINCLUSIVE, + FacetTypes.EXPLICITTIMEZONE + ) + ), + DataTypes.DateType + ); public static final ItemType hexBinaryItem = new AtomicItemType( new Name(Name.XS_NS, "xs", "hexBinary"), new HashSet<>( @@ -429,6 +504,11 @@ public static boolean typeExists(Name name) { dateTimeStampItem, dateItem, timeItem, + gDayItem, + gMonthItem, + gYearItem, + gMonthDayItem, + gYearMonthItem, hexBinaryItem, anyURIItem, base64BinaryItem, diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index 209c3be71f..3c9fa2df07 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -419,6 +419,22 @@ public String toString() { sequenceTypes.put("time?", new SequenceType(BuiltinTypesCatalogue.timeItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put("gDay?", new SequenceType(BuiltinTypesCatalogue.gDayItem, SequenceType.Arity.OneOrZero)); + + sequenceTypes.put("gMonth?", new SequenceType(BuiltinTypesCatalogue.gMonthItem, SequenceType.Arity.OneOrZero)); + + sequenceTypes.put("gYear?", new SequenceType(BuiltinTypesCatalogue.gYearItem, SequenceType.Arity.OneOrZero)); + + sequenceTypes.put( + "gMonthDay?", + new SequenceType(BuiltinTypesCatalogue.gMonthDayItem, SequenceType.Arity.OneOrZero) + ); + + sequenceTypes.put( + "gYearMonth?", + new SequenceType(BuiltinTypesCatalogue.gYearMonthItem, SequenceType.Arity.OneOrZero) + ); + sequenceTypes.put("anyURI", new SequenceType(BuiltinTypesCatalogue.anyURIItem)); sequenceTypes.put("anyURI?", new SequenceType(BuiltinTypesCatalogue.anyURIItem, SequenceType.Arity.OneOrZero)); From 1d61f1805277c4053f29ce4154a3bf67e7c02fbd Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 16:27:23 +0200 Subject: [PATCH 073/142] fix to accept xs:int. --- src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 89b2679f38..d8c42a655f 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -331,7 +331,7 @@ public class BuiltinTypesCatalogue { ); public static final ItemType intItem = new DerivedAtomicItemType( - Name.createVariableInDefaultTypeNamespace("int"), + new Name(Name.XS_NS, "xs", "int"), longItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets(new IntItem(-2147483648), new IntItem(2147483647), true), From 6e519f5d1ffdb65b4508803ef1fecc2ad1bcfc8a Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 16:38:07 +0200 Subject: [PATCH 074/142] Min, Max, OneOrMore, ZeroOrOne consume DF. --- .../aggregate/MaxFunctionIterator.java | 19 +++++++++ .../aggregate/MinFunctionIterator.java | 19 +++++++++ .../cardinality/OneOrMoreIterator.java | 18 +++++++++ .../cardinality/ZeroOrOneIterator.java | 39 +++++++++++++------ 4 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index 0b64e88d07..d8feb43ed9 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -30,9 +30,11 @@ import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; +import sparksoniq.spark.SparkSessionManager; import java.util.Collections; import java.util.List; @@ -89,6 +91,23 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } + if (this.iterator.isDataFrame()) { + JSoundDataFrame df = this.iterator.getDataFrame(context); + if (df.isEmptySequence()) { + return null; + } + df.createOrReplaceTempView("input"); + JSoundDataFrame maxDF = df.evaluateSQL( + String.format( + "SELECT MAX(`%s`) as `%s` FROM input", + SparkSessionManager.atomicJSONiqItemColumnName, + SparkSessionManager.atomicJSONiqItemColumnName + ), + df.getItemType() + ); + return maxDF.getExactlyOneItem(); + } + JavaRDD rdd = this.iterator.getRDD(context); if (rdd.isEmpty()) { return null; diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index aa5b17f66e..b88f80cc9c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -30,9 +30,11 @@ import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; +import sparksoniq.spark.SparkSessionManager; import java.util.Collections; import java.util.List; @@ -89,6 +91,23 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } + if (this.iterator.isDataFrame()) { + JSoundDataFrame df = this.iterator.getDataFrame(context); + if (df.isEmptySequence()) { + return null; + } + df.createOrReplaceTempView("input"); + JSoundDataFrame minDF = df.evaluateSQL( + String.format( + "SELECT MIN(`%s`) as `%s` FROM input", + SparkSessionManager.atomicJSONiqItemColumnName, + SparkSessionManager.atomicJSONiqItemColumnName + ), + df.getItemType() + ); + return minDF.getExactlyOneItem(); + } + JavaRDD rdd = this.iterator.getRDD(context); if (rdd.isEmpty()) { return null; diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/OneOrMoreIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/OneOrMoreIterator.java index 586e87295e..3785f6b3cc 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/OneOrMoreIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/OneOrMoreIterator.java @@ -27,6 +27,7 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.SequenceExceptionOneOrMore; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -59,6 +60,23 @@ protected JavaRDD getRDDAux(DynamicContext context) { ); } + @Override + public boolean implementsDataFrames() { + return true; + } + + @Override + public JSoundDataFrame getDataFrame(DynamicContext context) { + JSoundDataFrame childDataFrame = this.children.get(0).getDataFrame(context); + if (childDataFrame.isEmptySequence()) { + throw new SequenceExceptionOneOrMore( + "fn:one-or-more() called with a sequence containing less than 1 item", + getMetadata() + ); + } + return childDataFrame; + } + @Override public void openLocal() { this.iterator.open(this.currentDynamicContextForLocalExecution); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java index 2a9012932e..05b08a1255 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java @@ -26,6 +26,7 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.SequenceExceptionZeroOrOne; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.RuntimeIterator; import java.util.List; @@ -60,18 +61,34 @@ public Item materializeFirstItemOrNull(DynamicContext context) { ); } } else { - JavaRDD rdd = sequenceIterator.getRDD(context); - List results = rdd.take(2); - if (results.size() == 0) { - return null; - } else if (results.size() == 1) { - return results.get(0); - } else if (results.size() > 1) { - throw new SequenceExceptionZeroOrOne( - "fn:zero-or-one() called with a sequence containing more than one item", - getMetadata() - ); + if (sequenceIterator.isDataFrame()) { + JSoundDataFrame df = sequenceIterator.getDataFrame(context); + if (df.isEmptySequence()) { + return null; + } else if (df.count() == 1) { + return df.getExactlyOneItem(); + } else { + throw new SequenceExceptionZeroOrOne( + "fn:zero-or-one() called with a sequence containing more than one item", + getMetadata() + ); + } + + } else { + JavaRDD rdd = sequenceIterator.getRDD(context); + List results = rdd.take(2); + if (results.size() == 0) { + return null; + } else if (results.size() == 1) { + return results.get(0); + } else if (results.size() > 1) { + throw new SequenceExceptionZeroOrOne( + "fn:zero-or-one() called with a sequence containing more than one item", + getMetadata() + ); + } } + } return null; } From ba7884ba5636351326c1c40e2003ca768f62659c Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 17:01:04 +0200 Subject: [PATCH 075/142] Add tests for min, max, one-or-more, zero-or-one DF. --- .../sequences/cardinality/ExactlyOneIterator.java | 15 ++++----------- .../FunctionSequence/Aggregate/AggregateMaxDF1.jq | 7 +++++++ .../FunctionSequence/Aggregate/AggregateMinDF1.jq | 7 +++++++ .../Cardinality/FunctionOneOrMoreDF1.jq | 3 +++ .../Cardinality/FunctionZeroOrOneDF1.jq | 3 +++ 5 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq create mode 100644 src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq create mode 100644 src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionOneOrMoreDF1.jq create mode 100644 src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java index 180130f114..1bf28c2bb6 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java @@ -47,22 +47,15 @@ public ExactlyOneIterator( @Override public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { - try { - Item value = this.children.get(0).materializeAtMostOneItemOrNull(dynamicContext); - if (value == null) { - throw new SequenceExceptionExactlyOne( - "fn:exactly-one() called with a sequence that doesn't contain exactly one item", - getMetadata() - ); - - } - return value; - } catch (MoreThanOneItemException e) { + Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); + if (value == null) { throw new SequenceExceptionExactlyOne( "fn:exactly-one() called with a sequence that doesn't contain exactly one item", getMetadata() ); + } + return value; } @Override diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq new file mode 100644 index 0000000000..454adda5e0 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq @@ -0,0 +1,7 @@ +(:JIQS: ShouldRun; Output="(100)" :) +let $x := annotate( + for $i in 1 to 100 + return {"foo":$i, "bar":($i+1)}, + {"foo":"integer", "bar":"integer"} +).foo +return max($x) diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq new file mode 100644 index 0000000000..8a84729080 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq @@ -0,0 +1,7 @@ +(:JIQS: ShouldRun; Output="(1)" :) +let $x := annotate( + for $i in 1 to 100 + return {"foo":$i, "bar":($i+1)}, + {"foo":"integer", "bar":"integer"} +).foo +return min($x) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionOneOrMoreDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionOneOrMoreDF1.jq new file mode 100644 index 0000000000..29037d63d2 --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionOneOrMoreDF1.jq @@ -0,0 +1,3 @@ +(:JIQS: ShouldRun; Output="(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)" :) +one-or-more(annotate(parallelize(1 to 10) ! { "foo" : $$ cast as int }, { "foo" : "double" }).foo) + diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq new file mode 100644 index 0000000000..85f97b449b --- /dev/null +++ b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq @@ -0,0 +1,3 @@ +(:JIQS: ShouldRun; Output="(1)" :) +zero-or-one(annotate(parallelize(1 to 1) ! { "foo" : $$ cast as int }, { "foo" : "double" }).foo) + From 0625de0d31efbf3aa2fba57fe5ff12fc6b8fd834 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 18:16:23 +0200 Subject: [PATCH 076/142] string-join AtMostOne and consumes RDD. --- .../context/BuiltinFunctionCatalogue.java | 2 +- .../strings/StringJoinFunctionIterator.java | 56 +++++++++++++------ 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 8bea5ce37d..cf34dbda09 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1300,7 +1300,7 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** - * function that returns substrings + * function that returns a string created by concatenating the items in a sequence, with an optional defined separator between adjacent items. */ static final BuiltinFunction string_join1 = createBuiltinFunction( new Name( diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java index f16ebb7d89..fffcc01ba1 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java @@ -20,18 +20,21 @@ package org.rumbledb.runtime.functions.strings; +import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; -public class StringJoinFunctionIterator extends LocalFunctionCallIterator { +public class StringJoinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; @@ -44,17 +47,14 @@ public StringJoinFunctionIterator( } @Override - public Item next() { - if (this.hasNext) { - Item joinString = ItemFactory.getInstance().createStringItem(""); - List strings = this.children.get(0).materialize(this.currentDynamicContextForLocalExecution); - if (this.children.size() > 1) { - RuntimeIterator joinStringIterator = this.children.get(1); - joinStringIterator.open(this.currentDynamicContextForLocalExecution); - if (joinStringIterator.hasNext()) { - joinString = joinStringIterator.next(); - } - } + public Item materializeFirstItemOrNull(DynamicContext context) { + Item joinString = ItemFactory.getInstance().createStringItem(""); + if (this.children.size() > 1) { + joinString = this.children.get(1).materializeFirstItemOrNull(context); + } + if (!this.children.get(0).isRDDOrDataFrame()) { + List strings = this.children.get(0).materialize(context); + StringBuilder stringBuilder = new StringBuilder(); for (Item item : strings) { @@ -66,13 +66,33 @@ public Item next() { } stringBuilder.append(item.getStringValue()); } - this.hasNext = false; return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); - } else { - throw new IteratorFlowException( - RuntimeIterator.FLOW_EXCEPTION_MESSAGE + " string-join function", - getMetadata() - ); } + JavaRDD strings = this.children.get(0).getRDD(context); + StringBuilder stringBuilder = new StringBuilder(); + //Item finalJoinString = joinString; + //strings.map(item -> stringBuilder.append(constructor(stringBuilder, item, finalJoinString))); + for (Item item : strings.collect()) { + if (!(item.isString())) { + throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); + } + if (!stringBuilder.toString().isEmpty()) { + stringBuilder.append(joinString.getStringValue()); + } + stringBuilder.append(item.getStringValue()); + } + return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); } + + + private String constructor(StringBuilder stringBuilder, Item item, Item joinString) { + if (!(item.isString())) { + throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); + } + if (!stringBuilder.toString().isEmpty()) { + return joinString.getStringValue().concat(item.getStringValue()); + } + return item.getStringValue(); + } + } From 6bb65288736f50e45dc27f38bfb87972fe1bb1b5 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 18:31:02 +0200 Subject: [PATCH 077/142] Init fn:collection. --- .../io/CollectionFunctionIterator.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java diff --git a/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java new file mode 100644 index 0000000000..a16e792bcc --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java @@ -0,0 +1,46 @@ +package org.rumbledb.runtime.functions.io; + +import org.apache.spark.sql.DataFrameReader; +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.CannotRetrieveResourceException; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.UnexpectedTypeException; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ObjectItem; +import org.rumbledb.items.structured.JSoundDataFrame; +import org.rumbledb.runtime.DataFrameRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.functions.input.FileSystemUtil; +import sparksoniq.spark.SparkSessionManager; + +import java.net.URI; +import java.util.List; + +public class CollectionFunctionIterator extends DataFrameRuntimeIterator { + + public CollectionFunctionIterator( + List children, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + public JSoundDataFrame getDataFrame(DynamicContext context) { + Item stringItem = this.children.get(0) + .materializeFirstItemOrNull(context); + String url = stringItem.getStringValue(); + URI uri = FileSystemUtil.resolveURI(this.staticURI, url, getMetadata()); + if (!FileSystemUtil.exists(uri, context.getRumbleRuntimeConfiguration(), getMetadata())) { + throw new CannotRetrieveResourceException("File " + uri + " not found.", getMetadata()); + } + Item optionsObjectItem; + DataFrameReader dfr = SparkSessionManager.getInstance().getOrCreateSession().read(); + String extension + switch + } + +} From ac03d6c0775f4f3653e05d7585d9e00e9c2258fd Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 18:41:47 +0200 Subject: [PATCH 078/142] merge master in master-pierre-motard, solve conflicts. --- README.md | 14 +- RumbleSandbox.ipynb | 4 +- docs/CLI.md | 8 +- docs/Error codes.md | 16 +- docs/Function library.md | 4 +- docs/Getting started.md | 41 ++- docs/HTTPServer.md | 20 +- docs/Input.md | 14 +- docs/JSONiq.md | 8 +- docs/Licenses.md | 2 +- docs/RumbleML.md | 20 +- docs/Run on a cluster.md | 18 +- docs/Types.md | 234 +++++++++++++ docs/index.md | 10 +- docs/install.md | 28 +- mkdocs.yml | 11 +- pom.xml | 14 +- src/main/java/org/rumbledb/cli/Main.java | 42 ++- .../compiler/ExecutionModeVisitor.java | 23 +- .../rumbledb/compiler/InferTypeVisitor.java | 2 +- .../compiler/RuntimeIteratorVisitor.java | 2 +- .../rumbledb/compiler/TranslationVisitor.java | 5 +- .../compiler/VariableDependenciesVisitor.java | 34 -- .../org/rumbledb/compiler/VisitorHelpers.java | 2 +- .../compiler/XQueryTranslationVisitor.java | 5 +- .../org/rumbledb/errorcodes/ErrorCode.java | 1 + .../rumbledb/exceptions/RumbleException.java | 6 +- .../typing/ValidateTypeExpression.java | 7 - .../flwor/clauses/ForClauseSparkIterator.java | 3 +- .../clauses/GroupByClauseSparkIterator.java | 3 +- .../clauses/JoinClauseSparkIterator.java | 3 +- .../flwor/clauses/LetClauseSparkIterator.java | 2 +- .../clauses/OrderByClauseSparkIterator.java | 5 +- .../clauses/WhereClauseSparkIterator.java | 3 +- .../runtime/typing/TreatIterator.java | 7 + .../runtime/typing/ValidateTypeIterator.java | 309 ++++++++++++------ .../rumbledb/server/RumbleHttpHandler.java | 20 +- .../org/rumbledb/shell/RumbleJLineShell.java | 2 +- .../org/rumbledb/types/FieldDescriptor.java | 47 +++ .../org/rumbledb/types/ItemTypeFactory.java | 41 ++- .../org/rumbledb/types/ObjectItemType.java | 13 +- .../sparksoniq/jsoniq/tuple/FlworKey.java | 5 +- .../java/sparksoniq/spark/DataFrameUtils.java | 262 --------------- .../sparksoniq/spark/SparkSessionManager.java | 5 +- .../spark/ml/AnnotateFunctionIterator.java | 19 +- .../ml/GetTransformerFunctionIterator.java | 1 - src/main/resources/assets/banner.txt | 10 +- .../runtime-native-flwor/udt/type-default.jq | 16 + .../runtime-native-flwor/udt/type-single.jq | 168 ++++++++++ .../runtime-native-flwor/udt/type1.jq | 2 +- .../runtime-native-flwor/udt/type4.jq | 2 +- .../runtime-native-flwor/udt/type5.jq | 15 + .../runtime-native-flwor/udt/typeError2.jq | 3 - .../MLAnnotateDF-SchemaError4.jq | 2 +- .../AnnotateFunction/MLAnnotateDF1.jq | 2 +- .../AnnotateFunction/MLAnnotateDF2.jq | 7 - .../MLAnnotateForChaining4.jq | 2 +- .../runtime-spark/RumbleML/MLPipeline3.jq | 2 +- .../runtime-spark/RumbleML/MLPipeline4.jq | 2 +- .../runtime-spark/RumbleML/MLPipeline5.jq | 2 +- .../runtime-spark/RumbleML/MLPipeline6.jq | 2 +- .../NamedFunctionRef-Error4.jq | 2 +- .../NamedFunctionRef-Error5.jq | 2 +- 63 files changed, 997 insertions(+), 589 deletions(-) create mode 100644 docs/Types.md delete mode 100644 src/main/java/sparksoniq/spark/DataFrameUtils.java create mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/type-default.jq create mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/type-single.jq create mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/type5.jq delete mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/typeError2.jq delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq diff --git a/README.md b/README.md index 2d95d32b16..5d3991f5dc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,16 @@ -# Rumble +# RumbleDB -Getting started: you will find a Jupyter notebook that introduces the JSONiq language on top of Rumble [here](https://github.com/ghislainfourny/jsoniq-tutorial). You can use it by installing the all-in-one Data Science platform [Anaconda](https://www.anaconda.com), unless you prefer to install Python+Spark+PySpark+Jupyter manually (brew, apt...). +With RumbleDB, you can query with ease a lot of different nested, heterogeneous data formats like JSON, CSV, Parquet, Avro, LibSVM, text, etc. -The documentation also contains an introduction specific to Rumble and how you can read input datasets, but we have not converted it to Jupyter notebooks yet (this will follow). +RumbleDB exposes a query language rather than a DataFrame API, for more flexibility, more productivity but also because a lot of data simply will not fit in DataFrames. + +You can query it in place from any local file systems or data lakes (Azure blob storage, Amazon S3, HDFS, etc). + +You can prepare, clean up, validate your data and put it right into your machine learning pipelines with RumbleDB ML. + +Getting started: you will find a Jupyter notebook that introduces the JSONiq language on top of RumbleDB [here](https://colab.research.google.com/github/RumbleDB/rumble/blob/master/RumbleSandbox.ipynb). You can also run it locally if you prefer. + +The documentation also contains an introduction specific to RumbleDB and how you can read input datasets, but we have not converted it to Jupyter notebooks yet (this will follow). [The documentation of the latest official release is available here.](http://rumble.readthedocs.io/en/latest/) diff --git a/RumbleSandbox.ipynb b/RumbleSandbox.ipynb index 0d4eff65a0..a6103fc1be 100644 --- a/RumbleSandbox.ipynb +++ b/RumbleSandbox.ipynb @@ -47,9 +47,9 @@ " for e in response['values']:\n", " print(json.dumps(e))\n", " elif 'error-message' in response:\n", - " return response['error-message']\n", + " return print(response['error-message'])\n", " else:\n", - " return response" + " return print(response)" ] }, { diff --git a/docs/CLI.md b/docs/CLI.md index cecd2d7393..bf0e4f2256 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -1,4 +1,4 @@ -# Rumble parameters +# RumbleDB parameters The parameters that can be used on the command line as well as on the planned HTTP server are shown below. @@ -17,8 +17,8 @@ The parameters that can be used on the command line as well as on the planned HT | --print-iterator-tree | N/A | yes, no | For debugging purposes, prints out the expression tree and runtime interator tree. | | --show-error-info | show-error-info | yes, no | For debugging purposes. If you want to report a bug, you can use this to get the full exception stack. If no, then only a short message is shown in case of error. | | --static-typing | static-typing | yes, no | Activates static type analysis, which annotates the expression tree with inferred types at compile time and enables more optimizations (experimental). Deactivated by default. | -| --server | N/A | yes, no | yes runs Rumble as a server on port 8001. Run queries with http://localhost:8001/jsoniq?query-path=/folder/foo.json | -| --port | N/A | 8001 (default) | Changes the port of the Rumble HTTP server to any of your liking | -| --host | N/A | localhost (default) | Changes the host of the Rumble HTTP server to any of your liking | +| --server | N/A | yes, no | yes runs RumbleDB as a server on port 8001. Run queries with http://localhost:8001/jsoniq?query-path=/folder/foo.json | +| --port | N/A | 8001 (default) | Changes the port of the RumbleDB HTTP server to any of your liking | +| --host | N/A | localhost (default) | Changes the host of the RumbleDB HTTP server to any of your liking | | --variable:foo | variable:foo | bar | --variable:foo bar initialize the global variable $foo to "bar". The query must contain the corresponding global variable declaration, e.g., "declare variable $foo external;" | diff --git a/docs/Error codes.md b/docs/Error codes.md index 55658ad996..35561d1811 100644 --- a/docs/Error codes.md +++ b/docs/Error codes.md @@ -30,17 +30,17 @@ for an object or array selector. - [RBDY0005] - Materialization Error: the sequence is too big to be materialized. Use --materialization-cap to increase the maximum materialization size, or add an output path to write to. -- [RBML0001] - Unrecognized Rumble ML Class Reference -An unrecognized classname is used in query while accessing the Rumble ML API. +- [RBML0001] - Unrecognized RumbleDB ML Class Reference +An unrecognized classname is used in query while accessing the RumbleDB ML API. -- [RBML0002] - Unrecognized Rumble ML Param Reference -An unrecognized parameter is used in query while operating with a Rumble ML class. +- [RBML0002] - Unrecognized RumbleDB ML Param Reference +An unrecognized parameter is used in query while operating with a RumbleDB ML class. -- [RBML0003] - Invalid Rumble ML Param -Provided parameter does not match the expected type or value for the referenced Rumble ML class. +- [RBML0003] - Invalid RumbleDB ML Param +Provided parameter does not match the expected type or value for the referenced RumbleDB ML class. - [RBML0004] - Input is not a DataFrame -Provided input of items does not form a DataFrame as expected by RumbleML. +Provided input of items does not form a DataFrame as expected by RumbleDB ML. - [RBML0005] - Invalid schema for DataFrame in annotate() The provided schema can not be applied to the item data while converting the data to a DataFrame @@ -48,7 +48,7 @@ The provided schema can not be applied to the item data while converting the dat - [RBST0001] - CLI error. Raised when invalid parameters are supplied at launch. - [RBST0002] - Unimplemented feature error. -Raised when a JSONiq feature that is not yet implemented in Rumble is used. +Raised when a JSONiq feature that is not yet implemented in RumbleDB is used. - [RBST0003] - Invalid for clause expression error. Raised when an expression produces a different, diff --git a/docs/Function library.md b/docs/Function library.md index 3f1145b82d..289e4cc26e 100644 --- a/docs/Function library.md +++ b/docs/Function library.md @@ -1,9 +1,9 @@ # Function library -We list here the functions supported by Rumble, and introduce them by means of examples. Highly detailed specifications can be found in the [underlying W3C standard](https://www.w3.org/TR/xpath-functions-30/#func-floor), unless the function is marked as specific to JSON or Rumble, in which case it can be found [here](http://www.jsoniq.org/docs/JSONiq/html-single/index.html#idm34604304). +We list here the functions supported by RumbleDB, and introduce them by means of examples. Highly detailed specifications can be found in the [underlying W3C standard](https://www.w3.org/TR/xpath-functions-30/#func-floor), unless the function is marked as specific to JSON or RumbleDB, in which case it can be found [here](http://www.jsoniq.org/docs/JSONiq/html-single/index.html#idm34604304). For the sake of ease of use, all W3C standard builtin functions and JSONiq builtin functions are in the -Rumble namespace, which is the default function namespace and does not require any prefix in front of function names. +RumbleDB namespace, which is the default function namespace and does not require any prefix in front of function names. It is recommended that user-defined functions are put in the local namespace, i.e., their name should have the local: prefix (which is predefined). Otherwise, there is the risk that your code becomes incompatible with subsequent releases if new (unprefixed) builtin functions are introduced. diff --git a/docs/Getting started.md b/docs/Getting started.md index 101c980596..44ce9227af 100644 --- a/docs/Getting started.md +++ b/docs/Getting started.md @@ -4,30 +4,30 @@ ### Install Spark -Rumble requires a Spark installation on Linux, Mac or Windows. +RumbleDB requires a Spark installation on Linux, Mac or Windows. Users who love the command line can install Spark with a package management system, such as brew (on macOS) or apt-get (on Ubuntu). However, it is also straightforward to directly [download it](https://spark.apache.org/downloads.html), unpack it, and add the subdirectory "bin" within the unpacked directory to the PATH variable, as well as the location of the unpacked directory to SPARK_HOME. -We recommend installing either Spark 2.4.7, or Spark 3.0.2 (we provide a Rumble jar for each one of these, the default is Spark 3). +We recommend installing either Spark 2.4.7, or Spark 3.0.2 (we provide a RumbleDB jar for each one of these, the default is Spark 3). You can test that Spark was correctly installed with: spark-submit --version -Another important comment: if you use Spark 2.4.x, you need to make sure that you have Java 8 and that, if you have several versions installed, JAVA_HOME correctly points to Java 8. Spark 2.4.x only supports Java 8. Spark 3.0.2 is documented to work with both Java 8 and Java 11, even though we have not tried Java 11 yet. If there is an issue with the Java version, Rumble will inform you with an appropriate error message. You can check the version that is configured with: +Another important comment: if you use Spark 2.4.x, you need to make sure that you have Java 8 and that, if you have several versions installed, JAVA_HOME correctly points to Java 8. Spark 2.4.x only supports Java 8. Spark 3.0.2 is documented to work with both Java 8 and Java 11, even though we have not tried Java 11 yet. If there is an issue with the Java version, RumbleDB will inform you with an appropriate error message. You can check the version that is configured with: java -version -### Download Rumble +### Download RumbleDB -Rumble is just a download with no installation. In order to run Rumble, you simply need to download the .jar file from the [download page](https://github.com/Sparksoniq/rumble/releases) and put it in a directory of your choice (for example, right besides your data). If you use Spark 3.0.2, you can use the default jar. If you use Spark 2.4.x, make sure to use the corresponding jar (for-spark-2) and to replace the jar name accordingly in all our instructions. +RumbleDB is just a download with no installation. In order to run RumbleDB, you simply need to download the .jar file from the [download page](https://github.com/RumbleDB/rumble/releases) and put it in a directory of your choice (for example, right besides your data). If you use Spark 3.0.2, you can use the default jar. If you use Spark 2.4.x, make sure to use the corresponding jar (for-spark-2) and to replace the jar name accordingly in all our instructions. ### Create some data set -Create, in the same directory as Rumble to keep it simple, a file data.json and put the following content inside. This is a small list of JSON objects in the JSON Lines format. +Create, in the same directory as RumbleDB to keep it simple, a file data.json and put the following content inside. This is a small list of JSON objects in the JSON Lines format. { "product" : "broiler", "store number" : 1, "quantity" : 20 } { "product" : "toaster", "store number" : 2, "quantity" : 100 } @@ -41,18 +41,17 @@ Create, in the same directory as Rumble to keep it simple, a file data.json and ## Running simple queries locally -In a shell, from the directory where the rumble .jar lies, type, all on one line: +In a shell, from the directory where the RumbleDB .jar lies, type, all on one line: - spark-submit spark-rumble-1.12.0.jar --shell yes + spark-submit rumbledb-1.14.0.jar --shell yes -The Rumble shell appears: +The RumbleDB shell appears: - ____ __ __ - / __ \__ ______ ___ / /_ / /__ - / /_/ / / / / __ `__ \/ __ \/ / _ \ The distributed JSONiq engine - / _, _/ /_/ / / / / / / /_/ / / __/ 1.12.0 "Ashoka Tree" beta - /_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/ - + ____ __ __ ____ ____ + / __ \__ ______ ___ / /_ / /__ / __ \/ __ ) + / /_/ / / / / __ `__ \/ __ \/ / _ \/ / / / __ | The distributed JSONiq engine + / _, _/ /_/ / / / / / / /_/ / / __/ /_/ / /_/ / 1.14.0 "Acacia" beta + /_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/_____/_____/ Master: local[*] Item Display Limit: 200 @@ -91,7 +90,7 @@ Data can be filtered with the where clause. Again, below the hood, a Spark trans where $i.quantity gt 99 return $i -Rumble also supports grouping and aggregation, like so: +RumbleDB also supports grouping and aggregation, like so: for $i in json-file("data.json", 10) let $quantity := $i.quantity @@ -99,7 +98,7 @@ Rumble also supports grouping and aggregation, like so: return { "product" : $product, "total-quantity" : sum($quantity) } -Rumble also supports ordering. Note that clauses (where, let, group by, order by) can appear in any order. +RumbleDB also supports ordering. Note that clauses (where, let, group by, order by) can appear in any order. The only constraint is that the first clause should be a for or a let clause. for $i in json-file("data.json", 10) @@ -109,7 +108,7 @@ The only constraint is that the first clause should be a for or a let clause. order by $sum descending return { "product" : $product, "total-quantity" : $sum } -Finally, Rumble can also parallelize data provided within the query, exactly like Sparks' parallelize() creation: +Finally, RumbleDB can also parallelize data provided within the query, exactly like Sparks' parallelize() creation: for $i in parallelize(( { "product" : "broiler", "store number" : 1, "quantity" : 20 }, @@ -135,8 +134,8 @@ Mind the double parenthesis, as parallelize is a unary function to which we pass Further steps could involve: - Learning JSONiq. More details can be found in the JSONiq section of this documentation and in the [JSONiq specification](https://www.jsoniq.org/docs/JSONiq/webhelp/index.html) and [tutorials](https://colab.research.google.com/github/RumbleDB/rumble/blob/master/RumbleSandbox.ipynb). -- Storing some data on S3, creating a Spark cluster on Amazon EMR (or Azure blob storage and Azure, etc), and querying the data with Rumble. More details are found in the cluster section of this documentation. -- Using Rumble with Jupyter notebooks. For this, you can run Rumble as a server with a simple command, and get started by downloading the main JSONiq tutorial as a Jupyter notebook and just clicking your way through it. More details are found in the Jupyter notebook section of this documentation. Jupyter notebooks work both locally and on a cluster. -- Write JSONiq code, and share it on the Web, as others can import it from HTTP in just one line from within their queries (no package publication or installation required) or specify an HTTP URL as an input query to Rumble! +- Storing some data on S3, creating a Spark cluster on Amazon EMR (or Azure blob storage and Azure, etc), and querying the data with RumbleDB. More details are found in the cluster section of this documentation. +- Using RumbleDB with Jupyter notebooks. For this, you can run RumbleDB as a server with a simple command, and get started by downloading the main JSONiq tutorial as a Jupyter notebook and just clicking your way through it. More details are found in the Jupyter notebook section of this documentation. Jupyter notebooks work both locally and on a cluster. +- Write JSONiq code, and share it on the Web, as others can import it from HTTP in just one line from within their queries (no package publication or installation required) or specify an HTTP URL as an input query to RumbleDB! diff --git a/docs/HTTPServer.md b/docs/HTTPServer.md index 7474640273..8ac6f0d333 100644 --- a/docs/HTTPServer.md +++ b/docs/HTTPServer.md @@ -2,19 +2,19 @@ ## Starting the HTTP server -Rumble can be run as an HTTP server that listens for queries. In order to do so, you can use the --server and --port parameters: +RumbleDB can be run as an HTTP server that listens for queries. In order to do so, you can use the --server and --port parameters: - spark-submit spark-rumble-1.12.0.jar --server yes --port 8001 + spark-submit rumbledb-1.14.0.jar --server yes --port 8001 This command will not return until you force it to (Ctrl+C on Linux and Mac). This is because the server has to run permanently to listen to incoming requests. Most users will not have to do anything beyond running the above command. For most of them, the next step would be to open a Jupyter notebook that connects to this server automatically. -Caution! Launching a server always has consequences on security, especially as Rumble can read from and write to your disk; So make sure you activate your firewall. In later versions, we may support authentication tokens. +Caution! Launching a server always has consequences on security, especially as RumbleDB can read from and write to your disk; So make sure you activate your firewall. In later versions, we may support authentication tokens. ## Testing that it works (not necessary for most end users) -The HTTP server is meant not to be used directly by end users, but instead to make it possible to integrate Rumble in other languages and environments, such as Python and Jupyter notebooks. +The HTTP server is meant not to be used directly by end users, but instead to make it possible to integrate RumbleDB in other languages and environments, such as Python and Jupyter notebooks. To test that the the server running, you can try the following address in your browser, assuming you have a query stored locally at /tmp/query.jq. All queries have to go to the /jsoniq path. @@ -32,7 +32,7 @@ A query can also be submitted in the request body: ## Use with Jupyter notebooks -With the HTTP server running, if you have installed Python and Jupyter notebooks (for example with the Anaconda data science package that does all of it automatically), you can create a Rumble magic by just executing the following code in a cell: +With the HTTP server running, if you have installed Python and Jupyter notebooks (for example with the Anaconda data science package that does all of it automatically), you can create a RumbleDB magic by just executing the following code in a cell: import requests import json @@ -79,7 +79,7 @@ or on multiple lines: ## Use with clusters -You can also let Rumble run as an HTTP server on the master node of a cluster, e.g. on Amazon EMR or Azure. You just need to: +You can also let RumbleDB run as an HTTP server on the master node of a cluster, e.g. on Amazon EMR or Azure. You just need to: - Create the cluster (it is usually just the push of a few buttons in Amazon or Azure) - Wait for a few minutes @@ -90,13 +90,13 @@ Then there are two options ### With SSH tunneling - Connect to the master with SSH with an extra parameter for securely tunneling the HTTP connection (for example `-L 8001:localhost:8001` or any port of your choosing) -- Download the Rumble jar to the master node +- Download the RumbleDB jar to the master node - wget https://github.com/RumbleDB/rumble/releases/download/v1.12.0/spark-rumble-1.12.0.jar + wget https://github.com/RumbleDB/rumble/releases/download/v1.12.0/rumbledb-1.14.0.jar - Launch the HTTP server on the master node (it will be accessible under `http://localhost:8001/jsoniq`). - spark-submit spark-rumble-1.12.0.jar --server yes --port 8001 + spark-submit rumbledb-1.14.0.jar --server yes --port 8001 - And then use Jupyter notebooks in the same way you would do it locally (it magically works because of the tunneling) @@ -104,7 +104,7 @@ Then there are two options There is also another way that does not need any tunnelling: you can specify the hostname of your EC2 machine (copied over from the EC2 dashboard) with the --host parameter. For example, with the placeholder : - spark-submit spark-rumble-1.12.0.jar --server yes --port 8001 --host + spark-submit rumbledb-1.14.0.jar --server yes --port 8001 --host You also need to make sure in your EMR security group that the chosen port (e.g., 8001) is accessible from the machine in which you run your Jupyter notebook. Then, you can point your Jupyter notebook on this machine to `http://:8001/jsoniq`. diff --git a/docs/Input.md b/docs/Input.md index 85a26e5641..0b9f96ec89 100644 --- a/docs/Input.md +++ b/docs/Input.md @@ -1,6 +1,6 @@ # Reading data -Rumble is able to read a variety of formats from a variety of file systems. +RumbleDB is able to read a variety of formats from a variety of file systems. We support functions to read JSON, JSON Lines, Parquet, CSV, Text and ROOT files from various storage layers such as S3 and HDFS, Azure blob storage. We run most of our tests on Amazon EMR with S3 or HDFS, as well as locally on the local file system, but we welcome feedback on other setups. @@ -69,7 +69,7 @@ where $my-json.property eq "some value" return $my-json ``` -In some cases, JSON Lines files are highly structured, meaning that all objects have the same fields and these fields are associated with values with the same types. In this case, Rumble will be faster navigating such files if you open them with the function structured-json-file(). +In some cases, JSON Lines files are highly structured, meaning that all objects have the same fields and these fields are associated with values with the same types. In this case, RumbleDB will be faster navigating such files if you open them with the function structured-json-file(). structured-json-file() parses one or more json files that follow [JSON-lines](http://jsonlines.org/) format and returns a sequence of objects. This enables better performance with fully structured data and is recommended to use only when such data is available. @@ -85,7 +85,7 @@ return $my-structured-json ### Text -Text files can be read into a sequence of string items, one string per line. Rumble can open files that have billions or potentially even trillions of lines with the function text-file(). +Text files can be read into a sequence of string items, one string per line. RumbleDB can open files that have billions or potentially even trillions of lines with the function text-file(). text-file() exists in unary and binary. The first parameter specifies the text file (or set of text files) to read and return as a sequence of strings. @@ -106,7 +106,7 @@ Several files or whole directories can be read with the same pattern syntax as i (Also see examples for json-file for host and port, sets of files and working directory). -There is also a function local-text-file() that reads locally, without parallelism. Rumble can stream through the file efficiently. +There is also a function local-text-file() that reads locally, without parallelism. RumbleDB can stream through the file efficiently. ``` @@ -118,7 +118,7 @@ count( ) ``` -Rumble supports also the W3C-standard functions unparsed-text and unparsed-text-lines. The output of the latter is automatically parallelized as a potentially large sequence of strings. +RumbleDB supports also the W3C-standard functions unparsed-text and unparsed-text-lines. The output of the latter is automatically parallelized as a potentially large sequence of strings. ``` @@ -230,7 +230,7 @@ return $i ## Creating your own big sequence -The function parallelize() can be used to create, on the fly, a big sequence of items in such a way that Rumble can spread its querying across cores and machines. +The function parallelize() can be used to create, on the fly, a big sequence of items in such a way that RumbleDB can spread its querying across cores and machines. This function behaves like the Spark parallelize() you are familiar with and sends a large sequence to the cluster. The rest of the FLWOR expression is then evaluated with Spark transformations on the cluster. @@ -251,7 +251,7 @@ return $i ## Supported file systems -As a general rule of thumb, Rumble can read from any file system that Spark can read from. The file system is inferred from the scheme used in the path used in any of the functions described above. +As a general rule of thumb, RumbleDB can read from any file system that Spark can read from. The file system is inferred from the scheme used in the path used in any of the functions described above. Note that the scheme is optional, in which case the default file system as configured in Hadoop and Spark is used. A relative path can also be provided, in which case the working directory (including its file system) as configured is used. diff --git a/docs/JSONiq.md b/docs/JSONiq.md index dc1040eb94..69d79e7eb6 100644 --- a/docs/JSONiq.md +++ b/docs/JSONiq.md @@ -1,6 +1,6 @@ # JSONiq -Rumble relies on the JSONiq language. +RumbleDB relies on the JSONiq language. ## JSONiq reference @@ -8,7 +8,7 @@ The complete specification can be found [here](http://www.jsoniq.org/docs/JSONiq ## JSONiq tutorial -A tutorial can be found [here](https://github.com/ghislainfourny/jsoniq-tutorial). All queries in this tutorial will work with Rumble. +A tutorial can be found [here](https://github.com/ghislainfourny/jsoniq-tutorial). All queries in this tutorial will work with RumbleDB. ## JSONiq tutorial for Python users @@ -96,7 +96,7 @@ mod:func($mod:x) ### Try/catch -Try/catch expressions are supported. Error codes are in the default, Rumble namespace and do not need prefixes. +Try/catch expressions are supported. Error codes are in the default, RumbleDB namespace and do not need prefixes. ``` try { 1 div 0 } catch FOAR0001 { "Division by zero!" } @@ -145,7 +145,7 @@ The type system is not quite complete yet, although a lot of progress was made. ## Unsupported/Unimplemented features (beta release) -Most core features of JSONiq are now in place, and we are working on getting the last (less used) ones into Rumble as well. We prioritize their implementation on user requests. +Most core features of JSONiq are now in place, and we are working on getting the last (less used) ones into RumbleDB as well. We prioritize their implementation on user requests. ### Prolog diff --git a/docs/Licenses.md b/docs/Licenses.md index 95739b9b47..ab66bc344c 100644 --- a/docs/Licenses.md +++ b/docs/Licenses.md @@ -1,6 +1,6 @@ # Licenses -Rumble uses the following software: +RumbleDB uses the following software: - ANTLR v4 Framework - BSD License - Apache Commons Text - Apache License diff --git a/docs/RumbleML.md b/docs/RumbleML.md index f6abb9b09e..03d1b683be 100644 --- a/docs/RumbleML.md +++ b/docs/RumbleML.md @@ -1,11 +1,11 @@ -# RumbleML -RumbleML is a Machine Learning library built on top of the Rumble engine that makes it more productive and easier to perform ML tasks thanks to the abstraction layer provided by JSONiq. +# RumbleDB ML +RumbleDB ML is a Machine Learning library built on top of the RumbleDB engine that makes it more productive and easier to perform ML tasks thanks to the abstraction layer provided by JSONiq. The machine learning capabilities are exposed through JSONiq function items. The concepts of "estimator" and "transformer", which are core to Machine Learning, are naturally function items and fit seamlessly in the JSONiq data model. Training sets, test sets, and validation sets, which contain features and labels, are exposed through JSONiq sequences of object items: the keys of these objects are the features and labels. -The names of the estimators and of the transformers, as well as the functionality they encapsulate, are directly inherited from the [SparkML](https://spark.apache.org/docs/latest/ml-guide.html) library which RumbleML is based on: we chose not to reinvent the wheel. +The names of the estimators and of the transformers, as well as the functionality they encapsulate, are directly inherited from the [SparkML](https://spark.apache.org/docs/latest/ml-guide.html) library which RumbleDB ML is based on: we chose not to reinvent the wheel. ## Transformers @@ -25,15 +25,15 @@ Estimators abstract the concept of a Machine Learning algorithm or any algorithm ## Parameters -Transformers and estimators are function items in the Rumble Data Model. Their first argument is the sequence of objects that represents, for example, the training set or test set. Parameters can be provided as their second argument. This second argument is expected to be an object item. The machine learning parameters form the fields of the said object item as key-value pairs. +Transformers and estimators are function items in the RumbleDB Data Model. Their first argument is the sequence of objects that represents, for example, the training set or test set. Parameters can be provided as their second argument. This second argument is expected to be an object item. The machine learning parameters form the fields of the said object item as key-value pairs. ## Type Annotations -RumbleML works on highly structured data, because it requires full type information for all the fields in the training set or test set. It is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly. +RumbleDB ML works on highly structured data, because it requires full type information for all the fields in the training set or test set. It is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly. -Rumble supports a user-defined type system with which you can validate and annotate datasets against a JSound schema. +RumbleDB supports a user-defined type system with which you can validate and annotate datasets against a JSound schema. -This annotation is required to be applied on any dataset that must be used as input to RumbleML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. +This annotation is required to be applied on any dataset that must be used as input to RumbleDB ML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. ## Examples @@ -113,8 +113,8 @@ return $i // { "id" : 5, "col1" : 9.2, "col2" : 9.2, "col3" : 9.2, "prediction" : 1 } ``` -# RumbleML Functionality Overview: -## RumbleML - Catalogue of Estimators: +# RumbleDB ML Functionality Overview: +## RumblDB eML - Catalogue of Estimators: ### [AFTSurvivalRegression](https://spark.apache.org/docs/3.0.0/api/java/org/apache/spark/ml/regression/AFTSurvivalRegression.html) #### Parameters: ``` @@ -634,7 +634,7 @@ return $i - windowSize: integer ``` -## RumbleML - Catalogue of Transformers: +## RumbleDB ML - Catalogue of Transformers: ### [AFTSurvivalRegressionModel](https://spark.apache.org/docs/3.0.0/api/java/org/apache/spark/ml/regression/AFTSurvivalRegressionModel.html) #### Parameters: ``` diff --git a/docs/Run on a cluster.md b/docs/Run on a cluster.md index 860de780de..224089ab41 100644 --- a/docs/Run on a cluster.md +++ b/docs/Run on a cluster.md @@ -1,25 +1,25 @@ -# Running Rumble on a cluster +# Running RumbleDB on a cluster -After you have tried Rumble locally as explained in the getting started section, you can take Rumble to a real cluster +After you have tried RumbleDB locally as explained in the getting started section, you can take RumbleDB to a real cluster simply by modifying the command line parameters as documented [here for spark-submit](https://spark.apache.org/docs/latest/submitting-applications.html). If the Spark cluster is running on yarn, then the --master option can be changed from local[\*] to yarn compared to the getting started guide. Most of the time, though (e.g., on Amazon EMR), it needs not be specified, as this is already set up in the environment. - spark-submit spark-rumble-1.12.0.jar --shell yes + spark-submit rumbledb-1.14.0.jar --shell yes or explicitly: - spark-submit --master yarn --deploy-mode client spark-rumble-1.12.0.jar --shell yes + spark-submit --master yarn --deploy-mode client rumbledb-1.14.0.jar --shell yes You can also adapt the number of executors, etc. spark-submit --num-executors 30 --executor-cores 3 --executor-memory 10g - spark-rumble-1.12.0.jar --shell yes + rumbledb-1.14.0.jar --shell yes The size limit for materialization can also be made higher with --materialization-cap (the default is 200). This affects the number of items displayed on the shells as an answer to a query, as well as any materializations happening within the query with push-down is not supported. Warnings are issued if the cap is reached. spark-submit --num-executors 30 --executor-cores 3 --executor-memory 10g - spark-rumble-1.12.0.jar + rumbledb-1.14.0.jar --shell yes --materialization-cap 10000 ## Creation functions @@ -56,10 +56,10 @@ Note that by default only the first 1000 items in the output will be displayed o ## Execution of single queries and output to HDFS -Rumble also supports executing a single query from the command line, reading from HDFS and outputting the results to HDFS, with the query file being either local or on HDFS. For this, use the --query-path, --output-path and --log-path parameters. +RumbleDB also supports executing a single query from the command line, reading from HDFS and outputting the results to HDFS, with the query file being either local or on HDFS. For this, use the --query-path, --output-path and --log-path parameters. spark-submit --num-executors 30 --executor-cores 3 --executor-memory 10g - spark-rumble-1.12.0.jar + rumbledb-1.14.0.jar --query-path "hdfs:///user/me/query.jq" --output-path "hdfs:///user/me/results/output" --log-path "hdfs:///user/me/logging/mylog" @@ -67,7 +67,7 @@ Rumble also supports executing a single query from the command line, reading fro The query path, output path and log path can be any of the supported schemes (HDFS, file, S3, WASB...) and can be relative or absolute. spark-submit --num-executors 30 --executor-cores 3 --executor-memory 10g - spark-rumble-1.12.0.jar + rumbledb-1.14.0.jar --query-path "/home/me/my-local-machine/query.jq" --output-path "/user/me/results/output" --log-path "hdfs:///user/me/logging/mylog" diff --git a/docs/Types.md b/docs/Types.md new file mode 100644 index 0000000000..48911caa4e --- /dev/null +++ b/docs/Types.md @@ -0,0 +1,234 @@ +# User-defined types + +RumbleDB now support user-defined types in a limited fashion. + +## JSound Schema Compact syntax + +RumbleDB user-defined types can be defined with the JSound syntax. A tutorial for the JSound syntax can be found [here](https://github.com/ghislainfourny/jsound-tutorial). + +For now, RumbleDB only allows the definition of user-defined types for objects and has initial, experimemental, limited support of JSound. Also, the @ (primary key) and ? (nullable) characters are not supported at this point. The implementation is still experimental and bugs are still expected, which we will appreciate to be informed of. + +## Type declaration + +A new type can be declared in the prolog, at the same location where you also define global variables and user-defined functions. + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +{ "foo" : "this is a string", "bar" : 42 } +``` + +In the above query, although the type is defined, the query returns an object that was not validated against this type. + +## Type declaration + +To validate and annotate a sequence of objects, you need to use the validate-type expression, like so: + + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +validate type local:my-type* { + { "foo" : "this is a string", "bar" : 42 } +} +``` + +You can use user-defined types wherever other types can appear: as type annotation for FLWOR variables or global variables, as function parameter or return types, in instance-of or treat-as expressions, etc. + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +declare function local:proj($x as local:my-type+) as string* +{ + $x.foo +}; + +let $a as local:my-type* := validate type local:my-type* { + { "foo" : "this is a string", "bar" : 42 } +} +return if($a instance of local:my-type*) + then local:proj($a) + else "Not an instance." +``` + + +You can validate larger sequences + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +validate type local:my-type* { + { "foo" : "this is a string", "bar" : 42 }, + { "foo" : "this is another string", "bar" : 1 }, + { "foo" : "this is yet another string", "bar" : 2 }, + { "foo" : "this is a string", "bar" : 12 }, + { "foo" : "this is a string", "bar" : 42345 }, + { "foo" : "this is a string", "bar" : 42 } +} +``` + +You can also validate, in parallel, an entire JSON Lines file, like so: + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +validate type local:my-type* { + json-file("hdfs:///directory-file.json") +} +``` + +## Optional vs. required fields + +By defaults, fields are optional: + +``` +declare type local:my-type as { + "foo" : "string", + "bar" : "integer" +}; + +validate type local:my-type* { + { "foo" : "this is a string", "bar" : 42 }, + { "bar" : 1 }, + { "foo" : "this is yet another string", "bar" : 2 }, + { "foo" : "this is a string" }, + { "foo" : "this is a string", "bar" : 42345 }, + { "foo" : "this is a string", "bar" : 42 } +} +``` + +You can, however, make a field required by adding a ! in front of its name: + +``` +declare type local:my-type as { + "foo" : "string", + "!bar" : "integer" +}; + +validate type local:my-type* { + { "foo" : "this is a string", "bar" : 42 }, + { "bar" : 1 }, + { "foo" : "this is yet another string", "bar" : 2 }, + { "foo" : "this is a string", "bar" : 1234 }, + { "foo" : "this is a string", "bar" : 42345 }, + { "foo" : "this is a string", "bar" : 42 } +} +``` + +## Extra fields + +Extra fields will be rejected. However, the verbose version of JSound supports allowing extra fields (open objects) and will be supported in a future version of RumbleDB. + +## Nested arrays + +With the JSound comptact syntax, you can easily define nested array structures: + + +``` +declare type local:my-type as { + "foo" : "string", + "!bar" : [ "integer" ] +}; + +validate type local:my-type* { + { "foo" : "this is a string", "bar" : [ 42, 1234 ] }, + { "bar" : [ 1 ] }, + { "foo" : "this is yet another string", "bar" : [ 2 ] }, + { "foo" : "this is a string", "bar" : [ ] }, + { "foo" : "this is a string", "bar" : [ 1, 2, 3, 4, 5, 6 ] }, + { "foo" : "this is a string", "bar" : [ 42 ] } +} +``` + +You can even further nest objects: + + +``` +declare type local:my-type as { + "foo" : { "bar" : "integer" }, + "!bar" : [ { "first" : "string", "last" : "string" } ] +}; + +validate type local:my-type* { + { + "foo" : { "bar" : 1 }, + "bar" : [ + { "first" : "Albert", "last" : "Einstein" }, + { "first" : "Erwin", "last" : "Schrodinger" } + ] + }, + { + "foo" : { "bar" : 2 }, + "bar" : [ + { "first" : "Alan", "last" : "Turing" }, + { "first" : "John", "last" : "Von Neumann" } + ] + }, + { + "foo" : { "bar" : 3 }, + "bar" : [ + ] + } +} +``` + +Or split your definitions into several types that refer to each other: + +``` +declare type local:person as { + "first" : "string", + "last" : "string" +}; + +declare type local:my-type as { + "foo" : { "bar" : "integer" }, + "!bar" : [ "local:person" ] +}; + +validate type local:my-type* { + { + "foo" : { "bar" : 1 }, + "bar" : [ + { "first" : "Albert", "last" : "Einstein" }, + { "first" : "Erwin", "last" : "Schrodinger" } + ] + }, + { + "foo" : { "bar" : 2 }, + "bar" : [ + { "first" : "Alan", "last" : "Turing" }, + { "first" : "John", "last" : "Von Neumann" } + ] + }, + { + "foo" : { "bar" : 3 }, + "bar" : [ + ] + } +} +``` + +## DataFrames + +In fact, RumbleDB will internally convert the sequence of objects to a Spark DataFrame, leading to faster execution times. + +In other words, the JSound Compact Schema Syntax is perfect for defining DataFrames schema! + +## What's next? + +Once you have validated your data as a dataframe with a user-defined type, you are all set to use the RumbleDB ML Machine Learning library and feed it through ML pipelines! diff --git a/docs/index.md b/docs/index.md index f5c7646b64..490b0ff851 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ -# Rumble documentation +# RumbleDB documentation -Rumble is a querying engine that allows you to query your large, messy datasets with ease and productivity. +RumbleDB is a querying engine that allows you to query your large, messy datasets with ease and productivity. It supports JSON-like datasets including JSON, JSON Lines, Parquet, Avro, SVM, CSV, ROOT as well as text files, of any size from kB to at least the two-digit TB range (we have not found the limit yet). @@ -8,10 +8,10 @@ It is both good at handling small amounts of data on your laptop (in which case It runs on many local or distributed filesystems such as HDFS, S3, Azure blob storage, and HTTP (read-only), and of course your local drive as well. You can use any of these file systems to store your datasets, but also to store and share your queries and functions as library modules with other users, worldwide or within your institution, who can import them with just one line of code. You can also output the results of your query or the log to these filesystems (as long as you have write access). -With Rumble, queries can be written in the tailor-made and expressive JSONiq language. Users can write their queries declaratively and start with just a few lines. No need for complex JSON parsing machinery as JSONiq supports the JSON data model natively. +With RumbleDB, queries can be written in the tailor-made and expressive JSONiq language. Users can write their queries declaratively and start with just a few lines. No need for complex JSON parsing machinery as JSONiq supports the JSON data model natively. -The core of Rumble lies in JSONiq's FLWOR expressions, the semantics of which map beautifully to DataFrames and Spark SQL. Likewise expression semantics is seamlessly translated to transformations on RDDs. Transformations are not exposed as function calls, but are completely hidden behind JSONiq queries, giving the user the simplicity of an SQL-like language and the flexibility needed to query heterogeneous, tree-like data that does not fit in DataFrames. +The core of RumbleDB lies in JSONiq's FLWOR expressions, the semantics of which map beautifully to DataFrames and Spark SQL. Likewise expression semantics is seamlessly translated to transformations on RDDs. Transformations are not exposed as function calls, but are completely hidden behind JSONiq queries, giving the user the simplicity of an SQL-like language and the flexibility needed to query heterogeneous, tree-like data that does not fit in DataFrames. -This documentation provides you with instructions on how to get started, examples of data sets and queries that can be executed locally or on a cluster, links to JSONiq reference and tutorials, notes on the function library implemented so far, and instructions on how to compile Rumble from scratch. +This documentation provides you with instructions on how to get started, examples of data sets and queries that can be executed locally or on a cluster, links to JSONiq reference and tutorials, notes on the function library implemented so far, and instructions on how to compile RumbleDB from scratch. Please note that this is a (maturing) beta version. We welcome bug reports in the GitHub issues section. diff --git a/docs/install.md b/docs/install.md index 9295016aba..28b6b30eda 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,6 +1,6 @@ -# Installing Rumble +# Installing RumbleDB -We show here how to install Rumble from the github repository if you wish to do so (for example, to use the latest master). However, the easiest way to use Rumble is to simply download the already compiled .jar files. +We show here how to install RumbleDB from the github repository if you wish to do so (for example, to use the latest master). However, the easiest way to use RumbleDB is to simply download the already compiled .jar files. ## Requirements @@ -12,7 +12,7 @@ The following software is required: - [ANTLR](http://www.ant.org/), version 4.7 (supplied in our repository) - [Maven](https://maven.apache.org/) 3.6.0 -Important: the ANTLR version varies with the Spark version, because Spark is also shipped with an ANTLR runtime (example: Spark 2.2.0 is with ANTLR 4.5.3, Spark 2.3.0 with ANTLR 4.7). The ANTLR runtime MUST match the ANTLR generator used to generate the Rumble jar file. +Important: the ANTLR version varies with the Spark version, because Spark is also shipped with an ANTLR runtime (example: Spark 2.2.0 is with ANTLR 4.5.3, Spark 2.3.0 with ANTLR 4.7). The ANTLR runtime MUST match the ANTLR generator used to generate the RumbleDB jar file. ### Checking the requirements @@ -52,7 +52,7 @@ From the root directory of the rumble local checkout, you first need to build th $ ant -buildfile build_antlr_parser.xml generate-parser -Dantlr.jar=lib/antlr-4.7-complete.jar -### Rumble +### RumbleDB Once the ANTLR sources have been generated, you can compile the entire project like so: @@ -62,19 +62,19 @@ After successful completion, you can check the `target` directory, which should ## Running locally -The most straightforward to test if the above steps were successful is to run the Rumble shell locally, like so: +The most straightforward to test if the above steps were successful is to run the RumbleDB shell locally, like so: - $ spark-submit target/spark-rumble-1.12.0.jar --shell yes + $ spark-submit target/rumbledb-1.14.0.jar --shell yes -The Rumble shell should start: +The RumbleDB shell should start: Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties - ____ __ __ - / __ \__ ______ ___ / /_ / /__ - / /_/ / / / / __ `__ \/ __ \/ / _ \ The distributed JSONiq engine - / _, _/ /_/ / / / / / / /_/ / / __/ 1.12.0 "Ashoka Tree" beta - /_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/ + ____ __ __ ____ ____ + / __ \__ ______ ___ / /_ / /__ / __ \/ __ ) + / /_/ / / / / __ `__ \/ __ \/ / _ \/ / / / __ | The distributed JSONiq engine + / _, _/ /_/ / / / / / / /_/ / / __/ /_/ / /_/ / 1.14.0 "Acacia" beta + /_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/_____/_____/ Master: local[2] Item Display Limit: 1000 @@ -107,8 +107,8 @@ You can try a few more queries. >>> ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) -This is it. Rumble is step and ready to go locally. You can now move on to a JSONiq tutorial. A Rumble tutorial will also follow soon. +This is it. RumbleDB is step and ready to go locally. You can now move on to a JSONiq tutorial. A RumbleDB tutorial will also follow soon. ## Running on a cluster -You can also try to run the Rumble shell on a cluster if you have one available and configured -- this is done with the same command, as the master and deployment mode are usually already set up in cloud-managed clusters. More details are provided in the rest of the documentation. +You can also try to run the RumbleDB shell on a cluster if you have one available and configured -- this is done with the same command, as the master and deployment mode are usually already set up in cloud-managed clusters. More details are provided in the rest of the documentation. diff --git a/mkdocs.yml b/mkdocs.yml index bf2117dc66..6a03c5fbd8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -site_name: Rumble 1.12 "Ashoka Tree" beta +site_name: RumbleDB 1.14 "Acacia" beta pages: - '1. Documentation home': 'index.md' - '2. Getting started': 'Getting started.md' @@ -8,8 +8,9 @@ pages: - '6. Reading data': 'Input.md' - '7. Function library': 'Function library.md' - '8. CLI and HTTP parameters': 'CLI.md' - - '9. Machine learning library': 'RumbleML.md' - - '10. Error codes': 'Error codes.md' - - '11. Compile from GitHub': 'install.md' - - '12. Licenses': 'Licenses.md' + - '9. Define and validate your own types': 'Types.md' + - '10. Machine learning library': 'RumbleML.md' + - '11. Error codes': 'Error codes.md' + - '12. Compile from GitHub': 'install.md' + - '13. Licenses': 'Licenses.md' theme: readthedocs diff --git a/pom.xml b/pom.xml index 88c54fa9a5..7177b3113a 100644 --- a/pom.xml +++ b/pom.xml @@ -25,10 +25,10 @@ 4.0.0 com.github.rumbledb - spark-rumble - 1.12.0 + rumbledb + 1.14.0 jar - Rumble + RumbleDB A JSONiq engine to query large-scale JSON datasets stored on HDFS. Spark under the hood. http://rumbledb.org/ @@ -200,19 +200,19 @@ org.apache.spark spark-core_2.12 - 3.0.2 + 3.0.3 provided org.apache.spark spark-sql_2.12 - 3.0.2 + 3.0.3 provided org.apache.spark spark-mllib_2.12 - 3.0.2 + 3.0.3 provided @@ -224,7 +224,7 @@ org.apache.spark spark-avro_2.12 - 3.0.2 + 3.0.3 org.antlr diff --git a/src/main/java/org/rumbledb/cli/Main.java b/src/main/java/org/rumbledb/cli/Main.java index 2d92d20eda..faa786bacc 100644 --- a/src/main/java/org/rumbledb/cli/Main.java +++ b/src/main/java/org/rumbledb/cli/Main.java @@ -20,6 +20,7 @@ package org.rumbledb.cli; import java.io.IOException; +import java.net.ConnectException; import org.apache.spark.SparkException; import org.rumbledb.config.RumbleRuntimeConfiguration; @@ -92,7 +93,13 @@ private static void handleException(Throwable ex, boolean showErrorInfo) { if (sparkExceptionCause != null) { handleException(sparkExceptionCause, showErrorInfo); } else { - handleException(new RumbleException(ex.getMessage()), showErrorInfo); + 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()); @@ -129,11 +136,38 @@ private static void handleException(Throwable ex, boolean showErrorInfo) { if (showErrorInfo) { ex.printStackTrace(); } - System.exit(43); + System.exit(44); + } else if (ex instanceof ConnectException) { + System.err.println("⚠️ There was a problem with the connection to the cluster."); + System.err.println( + "For more debug info including the exact exception and a stacktrace, please try again using --show-error-info yes in your command line." + ); + if (showErrorInfo) { + ex.printStackTrace(); + } + System.exit(45); + } else if (ex instanceof NullPointerException) { + System.err.println( + "Oh my oh my, we are very embarrassed, because there was a null pointer exception. 🙈" + ); + System.err.println( + "We would like to investigate this and make sure to fix it in a subsequent release. 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); } else { - System.err.println("An error has occured: " + ex.getMessage()); System.err.println( - "We should investigate this 🙈. Please contact us or file an issue on GitHub with your query." + "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( diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index e85c34979c..1bd50f6fb3 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -51,6 +51,7 @@ import org.rumbledb.expressions.primary.FunctionCallExpression; import org.rumbledb.expressions.primary.InlineFunctionExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; +import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.types.SequenceType; import org.rumbledb.types.SequenceType.Arity; @@ -222,7 +223,6 @@ public StaticContext visitFunctionCall(FunctionCallExpression expression, Static @Override public StaticContext visitReturnClause(ReturnClause expression, StaticContext argument) { - System.err.println(expression.getStaticContext()); visitDescendants(expression, expression.getStaticContext()); if (expression.getPreviousClause().getHighestExecutionMode(this.visitorConfig).isDataFrame()) { expression.setHighestExecutionMode(ExecutionMode.RDD); @@ -408,4 +408,25 @@ public StaticContext visitProlog(Prolog prolog, StaticContext argument) { return argument; } + @Override + public StaticContext visitValidateTypeExpression(ValidateTypeExpression expression, StaticContext argument) { + visitDescendants(expression, null); + if (expression.getSequenceType().getArity().equals(Arity.Zero)) { + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + } + if (expression.getSequenceType().getArity().equals(Arity.One)) { + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + } + if (expression.getSequenceType().getArity().equals(Arity.OneOrZero)) { + expression.setHighestExecutionMode(ExecutionMode.LOCAL); + } + if (expression.getSequenceType().getArity().equals(Arity.OneOrMore)) { + expression.setHighestExecutionMode(ExecutionMode.DATAFRAME); + } + if (expression.getSequenceType().getArity().equals(Arity.ZeroOrMore)) { + expression.setHighestExecutionMode(ExecutionMode.DATAFRAME); + } + return argument; + } + } diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index 9fb3b23218..179dde65d1 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -295,7 +295,7 @@ public StaticContext visitVariableReference(VariableReferenceExpression expressi // we also set variableReference type if (variableType == null) { System.err.println( - "pWARNING] Variable reference type was null so we infer it. Please let us know as we would like to look into it." + "[WARNING] Variable reference type was null so we infer it. Please let us know as we would like to look into it." ); variableType = SequenceType.ITEM_STAR; } diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 35417fd49d..ab1e0223e5 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -851,7 +851,7 @@ public RuntimeIterator visitValidateTypeExpression(ValidateTypeExpression expres RuntimeIterator resultIterator = new TreatIterator( runtimeIterator, new SequenceType(BuiltinTypesCatalogue.item, expression.getSequenceType().getArity()), - ErrorCode.UnexpectedTypeErrorCode, + ErrorCode.InvalidInstance, expression.getHighestExecutionMode(this.visitorConfig), expression.getMetadata() ); diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 47d874e6f5..170131b78c 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1362,8 +1362,9 @@ public Node visitNamedFunctionRef(JsoniqParser.NamedFunctionRefContext ctx) { try { arity = Integer.parseInt(ctx.arity.getText()); } catch (NumberFormatException e) { - throw new RumbleException( - "Parser error: In a named function reference, arity must be an integer." + throw new ParsingException( + "Parser error: In a named function reference, arity must be an integer.", + createMetadataFromContext(ctx) ); } return new NamedFunctionReferenceExpression( diff --git a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java index 5b3cf524b5..ebc689c467 100644 --- a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java +++ b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java @@ -31,7 +31,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.stream.Collectors; import java.util.Map; import org.rumbledb.config.RumbleRuntimeConfiguration; @@ -424,47 +423,14 @@ private Map buildNameToNodeMap(Prolog prolog) { } visit(variableDeclaration, null); nameToNodeMap.put(variableDeclaration.getVariableName(), variableDeclaration); - if (this.rumbleRuntimeConfiguration.isPrintIteratorTree()) { - System.err.print(variableDeclaration.getVariableName()); - System.err.println( - String.join( - ", ", - getInputVariableDependencies(variableDeclaration).stream() - .map(x -> x.toString()) - .collect(Collectors.toList()) - ) - ); - } } for (FunctionDeclaration functionDeclaration : prolog.getFunctionDeclarations()) { visit(functionDeclaration, null); nameToNodeMap.put(functionDeclaration.getFunctionIdentifier().getNameWithArity(), functionDeclaration); - if (this.rumbleRuntimeConfiguration.isPrintIteratorTree()) { - System.err.print(functionDeclaration.getFunctionIdentifier().toString()); - System.err.println( - String.join( - ", ", - getInputVariableDependencies(functionDeclaration).stream() - .map(x -> x.toString()) - .collect(Collectors.toList()) - ) - ); - } } for (TypeDeclaration typeDeclaration : prolog.getTypeDeclarations()) { visit(typeDeclaration, null); nameToNodeMap.put(typeDeclaration.getDefinition().getName(), typeDeclaration); - if (this.rumbleRuntimeConfiguration.isPrintIteratorTree()) { - System.err.print(typeDeclaration.getDefinition().getName().toString()); - System.err.println( - String.join( - ", ", - getInputVariableDependencies(typeDeclaration).stream() - .map(x -> x.toString()) - .collect(Collectors.toList()) - ) - ); - } } return nameToNodeMap; } diff --git a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java index 21554015bd..d0a7249436 100644 --- a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java +++ b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java @@ -341,7 +341,7 @@ private static void populateExecutionModes(Module module, RumbleRuntimeConfigura } if (module.numberOfUnsetExecutionModes() > 0) { System.err.println( - "Warning! Some execution modes could not be set. The query may still work, but we would welcome a bug report." + "[WARNING] Some execution modes could not be set. The query may still work, but we would welcome a bug report." ); } diff --git a/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java b/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java index 78143f439b..fc261cf9a3 100644 --- a/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/XQueryTranslationVisitor.java @@ -1271,8 +1271,9 @@ public Node visitNamedFunctionRef(XQueryParser.NamedFunctionRefContext ctx) { try { arity = Integer.parseInt(ctx.arity.getText()); } catch (NumberFormatException e) { - throw new RumbleException( - "Parser error: In a named function reference, arity must be an integer." + throw new ParsingException( + "Parser error: In a named function reference, arity must be an integer.", + createMetadataFromContext(ctx) ); } return new NamedFunctionReferenceExpression( diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 806d6b82a0..138d505273 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -67,6 +67,7 @@ public enum ErrorCode { UnimplementedErrorCode("RBST0002"), JobWithinAJobErrorCode("RBST0003"), OurBadErrorCode("RBST0004"), + ClusterConnectionErrorCode("RBDY0005"), UnexpectedStaticType("RBTY0001"), diff --git a/src/main/java/org/rumbledb/exceptions/RumbleException.java b/src/main/java/org/rumbledb/exceptions/RumbleException.java index fe2772adb0..e799cb9a31 100644 --- a/src/main/java/org/rumbledb/exceptions/RumbleException.java +++ b/src/main/java/org/rumbledb/exceptions/RumbleException.java @@ -34,14 +34,14 @@ public class RumbleException extends RuntimeException { private final String errorMessage; private ExceptionMetadata metadata; - public RumbleException(String message) { + RumbleException(String message) { super(formatMessage(ErrorCode.RuntimeExceptionErrorCode, ExceptionMetadata.EMPTY_METADATA, message)); this.errorCode = ErrorCode.RuntimeExceptionErrorCode; this.errorMessage = message; this.metadata = ExceptionMetadata.EMPTY_METADATA; } - public RumbleException(String message, ErrorCode errorCode) { + RumbleException(String message, ErrorCode errorCode) { super(formatMessage(errorCode, ExceptionMetadata.EMPTY_METADATA, message)); if (!Arrays.asList(ErrorCode.class.getFields()).stream().anyMatch(f -> { try { @@ -59,7 +59,7 @@ public RumbleException(String message, ErrorCode errorCode) { } - public RumbleException(String message, ErrorCode errorCode, ExceptionMetadata metadata) { + RumbleException(String message, ErrorCode errorCode, ExceptionMetadata metadata) { super(formatMessage(errorCode, metadata, message)); if (!Arrays.asList(ErrorCode.class.getFields()).stream().anyMatch(f -> { try { diff --git a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java index 6e69da76ed..4e0484d375 100644 --- a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java @@ -3,11 +3,9 @@ import java.util.Collections; import java.util.List; -import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; import org.rumbledb.types.SequenceType; @@ -81,9 +79,4 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { this.mainExpression.serializeToJSONiq(sb, 0); sb.append(" as {" + this.sequenceType.toString() + "\n}\n"); } - - @Override - public void initHighestExecutionMode(VisitorConfig visitorConfig) { - this.highestExecutionMode = ExecutionMode.DATAFRAME; - } } diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/ForClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/ForClauseSparkIterator.java index ca548d495a..c8ff5b7d1b 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/ForClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/ForClauseSparkIterator.java @@ -963,9 +963,8 @@ public static Dataset tryNativeQuery( return null; } System.out.println( - "[INFO] Rumble was able to optimize a for clause to a native SQL query: " + nativeQuery.getResultingQuery() + "[INFO] Rumble was able to optimize a for clause to a native SQL query." ); - System.out.println("[INFO] (the lateral view part is " + nativeQuery.getLateralViewPart() + ")"); String selectSQL = FlworDataFrameUtils.getSQLProjection(allColumns, true); dataFrame.createOrReplaceTempView("input"); diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/GroupByClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/GroupByClauseSparkIterator.java index 363783af58..6b7a870627 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/GroupByClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/GroupByClauseSparkIterator.java @@ -570,8 +570,7 @@ private Dataset tryNativeQuery( selectString.append(".sequence`"); } } - System.out.println("[INFO] Rumble was able to optimize a let clause to a native SQL query: " + selectString); - System.out.println("[INFO] group-by part: " + groupByString); + System.out.println("[INFO] Rumble was able to optimize a let clause to a native SQL query."); return dataFrame.sparkSession() .sql( String.format( diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/JoinClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/JoinClauseSparkIterator.java index 3609ba041d..741ea947b7 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/JoinClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/JoinClauseSparkIterator.java @@ -463,8 +463,7 @@ private static Dataset tryNativeQueryStatically( return null; } System.err.println( - "[INFO] Rumble was able to optimize a join to a native SQL query: " - + nativeQuery.getResultingQuery() + "[INFO] Rumble was able to optimize a join to a native SQL query." ); leftInputTuple.createOrReplaceTempView("left"); rightInputTuple.createOrReplaceTempView("right"); diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java index 1ec498d348..1cf96af909 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/LetClauseSparkIterator.java @@ -764,7 +764,7 @@ public static Dataset tryNativeQuery( return null; } System.out.println( - "[INFO] Rumble was able to optimize a let clause to a native SQL query: " + nativeQuery.getResultingQuery() + "[INFO] Rumble was able to optimize a let clause to a native SQL query." ); String selectSQL = FlworDataFrameUtils.getSQLProjection(allColumns, true); dataFrame.createOrReplaceTempView("input"); 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 e5982bbe35..af9ab16789 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/OrderByClauseSparkIterator.java @@ -35,7 +35,6 @@ import org.rumbledb.exceptions.MoreThanOneItemException; import org.rumbledb.exceptions.NoTypedValueException; import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.exceptions.RumbleException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.flowr.FLWOR_CLAUSES; @@ -382,7 +381,7 @@ public Dataset getDataFrame( ) { columnType = DataTypes.LongType; } else { - throw new RumbleException( + throw new OurBadException( "Unexpected ordering type found while determining UDF return type." ); } @@ -560,7 +559,7 @@ public static Dataset tryNativeQuery( } } - System.out.println("[INFO] Rumble was able to optimize an order-by clause to a native SQL query: " + orderSql); + System.out.println("[INFO] Rumble was able to optimize an order-by clause to a native SQL query."); String selectSQL = FlworDataFrameUtils.getSQLProjection(allColumns, false); dataFrame.createOrReplaceTempView("input"); return dataFrame.sparkSession() 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 ea77cff3de..7f40e6ad02 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/WhereClauseSparkIterator.java @@ -381,8 +381,7 @@ public static Dataset tryNativeQuery( return null; } System.err.println( - "[INFO] Rumble was able to optimize a where clause to a native SQL query: " - + nativeQuery.getResultingQuery() + "[INFO] Rumble was able to optimize a where clause to a native SQL query." ); dataFrame.createOrReplaceTempView("input"); return dataFrame.sparkSession() diff --git a/src/main/java/org/rumbledb/runtime/typing/TreatIterator.java b/src/main/java/org/rumbledb/runtime/typing/TreatIterator.java index 092547dbc7..94d888b478 100644 --- a/src/main/java/org/rumbledb/runtime/typing/TreatIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/TreatIterator.java @@ -11,6 +11,7 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.errorcodes.ErrorCode; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.InvalidInstanceException; import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.TreatException; @@ -157,6 +158,12 @@ private RuntimeException errorToThrow(String type) { + this.sequenceType, this.getMetadata() ); + case InvalidInstance: + return new InvalidInstanceException( + "Invalid instance because of arity mismatch. The expected arity is " + + this.sequenceType.getArity(), + this.getMetadata() + ); default: return new OurBadException("Unexpected error code in treat as iterator.", this.getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/typing/ValidateTypeIterator.java b/src/main/java/org/rumbledb/runtime/typing/ValidateTypeIterator.java index b8d270dfea..da8f533b94 100644 --- a/src/main/java/org/rumbledb/runtime/typing/ValidateTypeIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/ValidateTypeIterator.java @@ -2,6 +2,7 @@ import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.function.Function; +import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import org.apache.spark.sql.RowFactory; import org.apache.spark.sql.types.ArrayType; @@ -11,11 +12,14 @@ import org.apache.spark.sql.types.StructType; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidInstanceException; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; +import org.rumbledb.items.ObjectItem; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.HybridRuntimeIterator; @@ -24,13 +28,11 @@ import org.rumbledb.types.FieldDescriptor; import org.rumbledb.types.ItemType; -import sparksoniq.spark.DataFrameUtils; import sparksoniq.spark.SparkSessionManager; import java.sql.Date; import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -68,11 +70,12 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { if (inputDataIterator.isDataFrame()) { JSoundDataFrame inputDataAsDataFrame = inputDataIterator.getDataFrame(context); - validateItemTypeAgainstDataFrame( - this.itemType, - inputDataAsDataFrame.getDataFrame().schema() - ); - return inputDataAsDataFrame; + ItemType actualType = inputDataAsDataFrame.getItemType(); + if (actualType.isSubtypeOf(this.itemType)) { + return inputDataAsDataFrame; + } + JavaRDD inputDataAsRDDOfItems = dataFrameToRDDOfItems(inputDataAsDataFrame, getMetadata()); + return convertRDDToValidDataFrame(inputDataAsRDDOfItems, this.itemType); } if (inputDataIterator.isRDDOrDataFrame()) { @@ -92,7 +95,7 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { } } - private static JSoundDataFrame convertRDDToValidDataFrame( + public static JSoundDataFrame convertRDDToValidDataFrame( JavaRDD itemRDD, ItemType itemType ) { @@ -154,11 +157,10 @@ private static DataType convertToDataType(ItemType itemType) { if (itemType.isObjectItemType()) { return convertToDataFrameSchema(itemType); } - return ItemParser.getDataFrameDataTypeFromItemType(itemType); } - private static JSoundDataFrame convertLocalItemsToDataFrame( + public static JSoundDataFrame convertLocalItemsToDataFrame( List items, ItemType itemType ) { @@ -188,6 +190,24 @@ public static Row convertLocalItemToRow(Item item, ItemType itemType, StructType ); } Object[] rowColumns = new Object[schema.fields().length]; + if (itemType != null && itemType.getClosedFacet()) { + for (String key : item.getKeys()) { + boolean found = false; + for (int fieldIndex = 0; fieldIndex < schema.fields().length; fieldIndex++) { + if (key.equals(schema.fields()[fieldIndex].name())) { + found = true; + } + } + if (!found) { + throw new InvalidInstanceException( + "Unexpected key in closed object type " + + itemType.getIdentifierString() + + " : " + + key + ); + } + } + } for (int fieldIndex = 0; fieldIndex < schema.fields().length; fieldIndex++) { StructField field = schema.fields()[fieldIndex]; String fieldName = field.name(); @@ -210,47 +230,71 @@ private static Object convertColumn(Item item, FieldDescriptor fieldDescriptor, String fieldName = field.name(); DataType fieldDataType = field.dataType(); Item columnValueItem = item.getItemByKey(fieldName); - if (fieldDescriptor != null && fieldDescriptor.isRequired() && columnValueItem == null) { + Item defaultValue = fieldDescriptor != null ? fieldDescriptor.getDefaultValue() : null; + if ( + fieldDescriptor != null && defaultValue == null && fieldDescriptor.isRequired() && columnValueItem == null + ) { throw new InvalidInstanceException( "Missing field '" + fieldName + "' in object '" + item.serialize() + "'." ); } try { if (columnValueItem == null) { + if (defaultValue != null) { + return getRowColumnFromItemUsingDataType( + defaultValue, + fieldDescriptor.getType(), + fieldDataType + ); + } return null; } - return getRowColumnFromItemUsingDataType(columnValueItem, fieldDataType); + return getRowColumnFromItemUsingDataType( + columnValueItem, + fieldDescriptor != null ? fieldDescriptor.getType() : null, + fieldDataType + ); } catch (InvalidInstanceException ex) { - throw new InvalidInstanceException( + RumbleException e = new InvalidInstanceException( "Data does not fit to the given schema in field '" + fieldName + "'; " + ex.getJSONiqErrorMessage() ); + e.initCause(ex); + throw e; } } - private static Object getRowColumnFromItemUsingDataType(Item item, DataType dataType) { + private static Object getRowColumnFromItemUsingDataType(Item item, ItemType itemType, DataType dataType) { try { if (dataType instanceof ArrayType) { if (!item.isArray()) { - throw new InvalidInstanceException("Type mismatch " + dataType); + throw new InvalidInstanceException( + "Type mismatch, expected " + dataType + " but actual " + item.getDynamicType() + ); } List arrayItems = item.getItems(); Object[] arrayItemsForRow = new Object[arrayItems.size()]; DataType elementType = ((ArrayType) dataType).elementType(); for (int i = 0; i < arrayItems.size(); i++) { Item arrayItem = item.getItemAt(i); - arrayItemsForRow[i] = getRowColumnFromItemUsingDataType(arrayItem, elementType); + arrayItemsForRow[i] = getRowColumnFromItemUsingDataType( + arrayItem, + itemType != null ? itemType.getArrayContentFacet().getType() : null, + elementType + ); } return arrayItemsForRow; } if (dataType instanceof StructType) { if (!item.isObject()) { - throw new InvalidInstanceException("Type mismatch " + dataType); + throw new InvalidInstanceException( + "Type mismatch, expected " + dataType + " but actual " + item.getDynamicType() + ); } - return ValidateTypeIterator.convertLocalItemToRow(item, null, (StructType) dataType); + return ValidateTypeIterator.convertLocalItemToRow(item, itemType, (StructType) dataType); } if (dataType.equals(DataTypes.BooleanType)) { @@ -408,62 +452,6 @@ private static Object getRowColumnFromItemUsingDataType(Item item, DataType data } - private static void validateItemTypeAgainstDataFrame( - ItemType itemType, - StructType dataFrameSchema - ) { - StructType generatedSchema = convertToDataFrameSchema(itemType); - for (StructField column : dataFrameSchema.fields()) { - final String columnName = column.name(); - final DataType columnDataType = column.dataType(); - - boolean columnMatched = Arrays.stream(generatedSchema.fields()).anyMatch(structField -> { - String generatedColumnName = structField.name(); - if (!generatedColumnName.equals(columnName)) { - return false; - } - - DataType generatedDataType = structField.dataType(); - if (DataFrameUtils.isUserTypeApplicable(generatedDataType, columnDataType)) { - return true; - } - - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "expected '" - + ItemParser.getItemTypeNameFromDataFrameDataType(columnDataType) - + "' type for field '" - + columnName - + "', but found '" - + ItemParser.getItemTypeNameFromDataFrameDataType(generatedDataType) - + "'" - ); - }); - - if (!columnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "missing type information for '" - + columnName - + "' field." - ); - } - } - - for (String generatedSchemaColumnName : generatedSchema.fieldNames()) { - boolean userColumnMatched = Arrays.asList(dataFrameSchema.fieldNames()).contains(generatedSchemaColumnName); - - if (!userColumnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "redundant type information for non-existent field '" - + generatedSchemaColumnName - + "'." - ); - } - } - } - @Override protected JavaRDD getRDDAux(DynamicContext context) { JavaRDD childrenItems = this.children.get(0).getRDD(context); @@ -495,46 +483,49 @@ protected Item nextLocal() { return validate(this.children.get(0).next(), this.itemType); } - private Item validate(Item item, ItemType type) { - if (this.itemType.isAtomicItemType()) { + private static Item validate(Item item, ItemType itemType) { + if (itemType.isAtomicItemType()) { if (!item.isAtomic()) { throw new InvalidInstanceException( - "Expected atomic item of type " + this.itemType.getIdentifierString() + "Expected an atomic item for type " + itemType.getIdentifierString() ); } - return ItemFactory.getInstance().createUserDefinedItem(item, this.itemType); + return ItemFactory.getInstance().createUserDefinedItem(item, itemType); } - if (this.itemType.isArrayItemType()) { + if (itemType.isArrayItemType()) { if (!item.isArray()) { throw new InvalidInstanceException( - "Expected array item of type " + this.itemType.getIdentifierString() + "Expected array item for array type " + itemType.getIdentifierString() ); } List members = new ArrayList<>(); for (Item member : item.getItems()) { - members.add(validate(member, this.itemType.getArrayContentFacet().getType())); + members.add(validate(member, itemType.getArrayContentFacet().getType())); } Item arrayItem = ItemFactory.getInstance().createArrayItem(members); - return ItemFactory.getInstance().createUserDefinedItem(arrayItem, this.itemType); + return ItemFactory.getInstance().createUserDefinedItem(arrayItem, itemType); } - if (this.itemType.isObjectItemType()) { + if (itemType.isObjectItemType()) { if (!item.isObject()) { throw new InvalidInstanceException( - "Expected object item of type " + this.itemType.getIdentifierString() + "Expected an object item for object type " + + itemType.getIdentifierString() + + ", but have " + + item.serialize() ); } List keys = new ArrayList<>(); List values = new ArrayList<>(); - Map facets = this.itemType.getObjectContentFacet(); + Map facets = itemType.getObjectContentFacet(); for (String key : item.getKeys()) { if (facets.containsKey(key)) { keys.add(key); values.add(validate(item.getItemByKey(key), facets.get(key).getType())); } else { - if (this.itemType.getClosedFacet()) { + if (itemType.getClosedFacet()) { throw new InvalidInstanceException( "Unexpected key in closed object type + " - + this.itemType.getIdentifierString() + + itemType.getIdentifierString() + " : " + key ); @@ -553,7 +544,7 @@ private Item validate(Item item, ItemType type) { if (facets.get(key).isRequired()) { throw new InvalidInstanceException( "Missing required key in object type + " - + this.itemType.getIdentifierString() + + itemType.getIdentifierString() + " : " + key ); @@ -562,12 +553,12 @@ private Item validate(Item item, ItemType type) { } Item objectItem = ItemFactory.getInstance() .createObjectItem(keys, values, ExceptionMetadata.EMPTY_METADATA); - return ItemFactory.getInstance().createUserDefinedItem(objectItem, this.itemType); + return ItemFactory.getInstance().createUserDefinedItem(objectItem, itemType); } - if (this.itemType.isFunctionItemType()) { + if (itemType.isFunctionItemType()) { if (!item.isFunction()) { throw new InvalidInstanceException( - "Expected function item of type " + this.itemType.getIdentifierString() + "Expected function item of type " + itemType.getIdentifierString() ); } return item; @@ -575,4 +566,140 @@ private Item validate(Item item, ItemType type) { return item; } + public static Dataset convertItemRDDToDataFrame( + JavaRDD itemRDD, + Item schemaItem + ) { + Item firstDataItem = (Item) itemRDD.take(1).get(0); + validateSchemaAgainstAnItem(schemaItem, firstDataItem); + StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); + JavaRDD rowRDD = itemRDD.map( + new Function() { + private static final long serialVersionUID = 1L; + + @Override + public Row call(Item item) { + return ValidateTypeIterator.convertLocalItemToRow(item, null, schema); + } + } + ); + return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rowRDD, schema); + } + + public static Dataset convertLocalItemsToDataFrame( + List items, + Item schemaItem + ) { + if (items.size() == 0) { + return SparkSessionManager.getInstance().getOrCreateSession().emptyDataFrame(); + } + ObjectItem firstDataItem = (ObjectItem) items.get(0); + validateSchemaAgainstAnItem(schemaItem, firstDataItem); + StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); + List rows = getRowsFromItemsUsingSchema(items, null, schema); + return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rows, schema); + } + + + + private static List getRowsFromItemsUsingSchema(List items, ItemType itemType, StructType schema) { + List rows = new ArrayList<>(); + for (Item item : items) { + Row row = ValidateTypeIterator.convertLocalItemToRow(item, itemType, schema); + rows.add(row); + } + return rows; + } + + private static void validateSchemaAgainstAnItem( + Item schemaItem, + Item dataItem + ) { + for (String schemaColumn : schemaItem.getKeys()) { + if (!dataItem.getKeys().contains(schemaColumn)) { + throw new InvalidInstanceException( + "Fields defined in schema must fully match the fields of input data: " + + "redundant type information for non-existent field '" + + schemaColumn + + "' column." + ); + } + } + + for (String dataColumn : dataItem.getKeys()) { + if (!schemaItem.getKeys().contains(dataColumn)) { + throw new InvalidInstanceException( + "Fields defined in schema must fully match the fields of input data: " + + "missing type information for '" + + dataColumn + + "' field." + ); + } + } + } + + private static StructType generateDataFrameSchemaFromSchemaItem(Item schemaItem) { + List fields = new ArrayList<>(); + try { + for (String columnName : schemaItem.getKeys()) { + StructField field = generateStructFieldFromNameAndItem( + columnName, + schemaItem.getItemByKey(columnName) + ); + fields.add(field); + } + } catch (IllegalArgumentException ex) { + InvalidInstanceException e = new InvalidInstanceException( + "Error while applying the schema; " + ex.getMessage() + ); + e.initCause(ex); + throw e; + } + return DataTypes.createStructType(fields); + } + + private static StructField generateStructFieldFromNameAndItem(String columnName, Item item) { + DataType type = generateDataTypeFromItem(item); + return DataTypes.createStructField(columnName, type, true); + } + + private static DataType generateDataTypeFromItem(Item item) { + if (item.isArray()) { + validateArrayItemInSchema(item); + Item arrayContentsTypeItem = item.getItemAt(0); + DataType arrayContentsType = generateDataTypeFromItem(arrayContentsTypeItem); + return DataTypes.createArrayType(arrayContentsType); + } + + if (item.isObject()) { + return generateDataFrameSchemaFromSchemaItem((ObjectItem) item); + } + + if (item.isString()) { + ItemType itemType = BuiltinTypesCatalogue.getItemTypeByName( + Name.createVariableInDefaultTypeNamespace(item.getStringValue()) + ); + return ItemParser.getDataFrameDataTypeFromItemType(itemType); + } + + throw new InvalidInstanceException( + "Schema can only contain arrays, objects or strings: " + item.serialize() + " is not accepted" + ); + } + + private static void validateArrayItemInSchema(Item item) { + List arrayTypes = item.getItems(); + if (arrayTypes.size() == 0) { + throw new InvalidInstanceException( + "Arrays in schema must define a type for their contents." + ); + } + if (arrayTypes.size() > 1) { + throw new InvalidInstanceException( + "Arrays in schema can define only a single type for their contents: " + + item.serialize() + + " is invalid." + ); + } + } } diff --git a/src/main/java/org/rumbledb/server/RumbleHttpHandler.java b/src/main/java/org/rumbledb/server/RumbleHttpHandler.java index 91ea78754a..2728c30cbb 100644 --- a/src/main/java/org/rumbledb/server/RumbleHttpHandler.java +++ b/src/main/java/org/rumbledb/server/RumbleHttpHandler.java @@ -5,6 +5,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.net.ConnectException; import java.net.URI; import java.net.URLDecoder; import java.util.ArrayList; @@ -204,7 +205,12 @@ private static Item handleException(Throwable ex) { if (sparkExceptionCause != null) { return handleException(sparkExceptionCause); } - return handleException(new RumbleException(ex.getMessage())); + return 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() + ) + ); } else if (ex instanceof RumbleException && !(ex instanceof OurBadException)) { return assembleErrorReponse( ex.getMessage(), @@ -217,6 +223,18 @@ private static Item handleException(Throwable ex) { ErrorCode.OurBadErrorCode.toString(), ex.getStackTrace() ); + } else if (ex instanceof ConnectException) { + return assembleErrorReponse( + "There was a problem with the connection to the cluster.", + ErrorCode.ClusterConnectionErrorCode.toString(), + ex.getStackTrace() + ); + } else if (ex instanceof NullPointerException) { + return assembleErrorReponse( + "There was a null pointer exception.", + ErrorCode.OurBadErrorCode.toString(), + ex.getStackTrace() + ); } else { return assembleErrorReponse( "An error has occured: " diff --git a/src/main/java/org/rumbledb/shell/RumbleJLineShell.java b/src/main/java/org/rumbledb/shell/RumbleJLineShell.java index d68cbf6a34..53147fe210 100644 --- a/src/main/java/org/rumbledb/shell/RumbleJLineShell.java +++ b/src/main/java/org/rumbledb/shell/RumbleJLineShell.java @@ -46,7 +46,7 @@ public class RumbleJLineShell { private static final String EXIT_COMMAND = "exit"; - private static final String PROMPT = ANSIColor.CYAN + "rumble$ " + ANSIColor.RESET; + private static final String PROMPT = ANSIColor.CYAN + "RumbleDB$ " + ANSIColor.RESET; private static final String MID_QUERY_PROMPT = ">>> "; private final boolean printTime; private final RumbleRuntimeConfiguration configuration; diff --git a/src/main/java/org/rumbledb/types/FieldDescriptor.java b/src/main/java/org/rumbledb/types/FieldDescriptor.java index 7f2b47ef4a..5921a5342f 100644 --- a/src/main/java/org/rumbledb/types/FieldDescriptor.java +++ b/src/main/java/org/rumbledb/types/FieldDescriptor.java @@ -3,6 +3,11 @@ import java.io.Serializable; import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.StaticContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.InvalidSchemaException; +import org.rumbledb.runtime.typing.CastIterator; public class FieldDescriptor implements Serializable { @@ -79,4 +84,46 @@ public String toString() { } return sb.toString(); } + + public void resolve(DynamicContext context, ExceptionMetadata metadata) { + if (!this.type.isResolved()) { + this.type.resolve(context, metadata); + } + if (this.defaultValue != null) { + if (!this.type.isAtomicItemType()) { + throw new InvalidSchemaException( + "Default values can only be literals for atomic types", + ExceptionMetadata.EMPTY_METADATA + ); + } + this.defaultValue = CastIterator.castItemToType(this.defaultValue, this.type, null); + if (this.defaultValue == null) { + throw new InvalidSchemaException( + "The literal " + this.defaultValue + "is not a valid literal for type " + this.type.toString(), + ExceptionMetadata.EMPTY_METADATA + ); + } + } + } + + public void resolve(StaticContext context, ExceptionMetadata metadata) { + if (!this.type.isResolved()) { + this.type.resolve(context, metadata); + } + if (this.defaultValue != null) { + if (!this.type.isAtomicItemType()) { + throw new InvalidSchemaException( + "Default values can only be literals for atomic types", + ExceptionMetadata.EMPTY_METADATA + ); + } + this.defaultValue = CastIterator.castItemToType(this.defaultValue, this.type, null); + if (this.defaultValue == null) { + throw new InvalidSchemaException( + "The literal " + this.defaultValue + "is not a valid literal for type " + this.type.toString(), + ExceptionMetadata.EMPTY_METADATA + ); + } + } + } } diff --git a/src/main/java/org/rumbledb/types/ItemTypeFactory.java b/src/main/java/org/rumbledb/types/ItemTypeFactory.java index d420c310b2..db5d609bc8 100644 --- a/src/main/java/org/rumbledb/types/ItemTypeFactory.java +++ b/src/main/java/org/rumbledb/types/ItemTypeFactory.java @@ -15,11 +15,12 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.InvalidSchemaException; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.items.ItemFactory; + import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; public class ItemTypeFactory { @@ -27,7 +28,10 @@ public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item, if (item.isString()) { String typeString = item.getStringValue(); if (typeString.contains("=")) { - throw new InvalidSchemaException("= not supported yet", ExceptionMetadata.EMPTY_METADATA); + throw new InvalidSchemaException( + "= is only supported for the types of object values", + ExceptionMetadata.EMPTY_METADATA + ); } return new ItemTypeReference(Name.createTypeNameFromLiteral(typeString, staticContext)); } @@ -47,7 +51,7 @@ public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item, ); } if (item.isObject()) { - Map fields = new TreeMap<>(); + Map fields = new LinkedHashMap<>(); for (String key : item.getKeys()) { Item value = item.getItemByKey(key); boolean required = false; @@ -61,12 +65,29 @@ public static ItemType createItemTypeFromJSoundCompactItem(Name name, Item item, if (key.startsWith("@")) { throw new InvalidSchemaException("@ not supported yet", ExceptionMetadata.EMPTY_METADATA); } + Item defaultValueLiteral = null; + if (value.isString() && value.getStringValue().contains("=")) { + String typeString = value.getStringValue(); + int index = typeString.indexOf("="); + String defaultLiteral = typeString.substring(index + 1); + if (defaultLiteral.contains("=")) { + throw new InvalidSchemaException( + "= can only appear once in a field descriptor type reference", + ExceptionMetadata.EMPTY_METADATA + ); + } + typeString = typeString.substring(0, index); + value = ItemFactory.getInstance().createStringItem(typeString); + defaultValueLiteral = ItemFactory.getInstance().createStringItem(defaultLiteral); + } + FieldDescriptor fieldDescriptor = new FieldDescriptor(); fieldDescriptor.setName(key); fieldDescriptor.setRequired(required); - fieldDescriptor.setType(createItemTypeFromJSoundCompactItem(null, value, staticContext)); + ItemType type = createItemTypeFromJSoundCompactItem(null, value, staticContext); + fieldDescriptor.setType(type); fieldDescriptor.setUnique(false); - fieldDescriptor.setDefaultValue(null); + fieldDescriptor.setDefaultValue(defaultValueLiteral); fields.put(key, fieldDescriptor); } return new ObjectItemType( @@ -99,7 +120,7 @@ public static FunctionItemType createFunctionItemType(FunctionSignature signatur private static ItemType createItemTypeFromSparkStructType(StructType structType) { // TODO : handle type registration // TODO : identical anonymous types should be equivalent? - Map content = new HashMap<>(); + Map content = new LinkedHashMap<>(); for (StructField field : structType.fields()) { DataType filedType = field.dataType(); ItemType mappedItemType; @@ -172,7 +193,11 @@ public static ItemType createItemType(DataType dt) { } else if (dt.equals(DataTypes.BinaryType)) { return BuiltinTypesCatalogue.hexBinaryItem; } else if (dt instanceof VectorUDT) { - return BuiltinTypesCatalogue.arrayItem; + VectorUDT vu = (VectorUDT) dt; + DataType et = vu.defaultConcreteType(); + return createArrayTypeWithSparkDataTypeContent( + DataTypes.DoubleType + ); } throw new OurBadException("DataFrame type unsupported: " + dt); } diff --git a/src/main/java/org/rumbledb/types/ObjectItemType.java b/src/main/java/org/rumbledb/types/ObjectItemType.java index c6f22cd9ca..9bec76465f 100644 --- a/src/main/java/org/rumbledb/types/ObjectItemType.java +++ b/src/main/java/org/rumbledb/types/ObjectItemType.java @@ -128,7 +128,7 @@ public Map getObjectContentFacet() { return this.content; } else { // recursively get content facet, overriding new descriptors - Map map = new HashMap<>(this.baseType.getObjectContentFacet()); + Map map = new LinkedHashMap<>(this.baseType.getObjectContentFacet()); map.putAll(this.content); return map; } @@ -254,9 +254,14 @@ public boolean isResolved() { @Override public void resolve(DynamicContext context, ExceptionMetadata metadata) { for (Map.Entry entry : this.content.entrySet()) { - if (!entry.getValue().getType().isResolved()) { - entry.getValue().getType().resolve(context, metadata); - } + entry.getValue().resolve(context, metadata); + } + } + + @Override + public void resolve(StaticContext context, ExceptionMetadata metadata) { + for (Map.Entry entry : this.content.entrySet()) { + entry.getValue().resolve(context, metadata); } } diff --git a/src/main/java/sparksoniq/jsoniq/tuple/FlworKey.java b/src/main/java/sparksoniq/jsoniq/tuple/FlworKey.java index 7819627e57..57d7e97346 100644 --- a/src/main/java/sparksoniq/jsoniq/tuple/FlworKey.java +++ b/src/main/java/sparksoniq/jsoniq/tuple/FlworKey.java @@ -27,7 +27,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.exceptions.RumbleException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.comparison.ComparisonExpression.ComparisonOperator; import org.rumbledb.expressions.flowr.OrderByClauseSortingKey.EMPTY_ORDER; @@ -93,7 +92,7 @@ public boolean equalFlworKey(FlworKey flworKey) { || (item2 != null && !item2.isAtomic()) ) { - throw new RumbleException("Non atomic key not allowed"); + throw new OurBadException("Non atomic key not allowed"); } long comparison = ComparisonIterator.compareItems( @@ -137,7 +136,7 @@ public int compareWithFlworKey(FlworKey flworKey, List convertItemRDDToDataFrame( - JavaRDD itemRDD, - Item schemaItem - ) { - Item firstDataItem = (Item) itemRDD.take(1).get(0); - validateSchemaAgainstAnItem(schemaItem, firstDataItem); - StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); - JavaRDD rowRDD = itemRDD.map( - new Function() { - private static final long serialVersionUID = 1L; - - @Override - public Row call(Item item) { - return ValidateTypeIterator.convertLocalItemToRow(item, null, schema); - } - } - ); - return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rowRDD, schema); - } - - public static Dataset convertLocalItemsToDataFrame( - List items, - Item schemaItem - ) { - if (items.size() == 0) { - return SparkSessionManager.getInstance().getOrCreateSession().emptyDataFrame(); - } - ObjectItem firstDataItem = (ObjectItem) items.get(0); - validateSchemaAgainstAnItem(schemaItem, firstDataItem); - StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); - List rows = getRowsFromItemsUsingSchema(items, null, schema); - return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rows, schema); - } - - private static List getRowsFromItemsUsingSchema(List items, ItemType itemType, StructType schema) { - List rows = new ArrayList<>(); - for (Item item : items) { - Row row = ValidateTypeIterator.convertLocalItemToRow(item, itemType, schema); - rows.add(row); - } - return rows; - } - - private static void validateSchemaAgainstAnItem( - Item schemaItem, - Item dataItem - ) { - for (String schemaColumn : schemaItem.getKeys()) { - if (!dataItem.getKeys().contains(schemaColumn)) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "redundant type information for non-existent field '" - + schemaColumn - + "' column." - ); - } - } - - for (String dataColumn : dataItem.getKeys()) { - if (!schemaItem.getKeys().contains(dataColumn)) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "missing type information for '" - + dataColumn - + "' field." - ); - } - } - } - - private static StructType generateDataFrameSchemaFromSchemaItem(Item schemaItem) { - List fields = new ArrayList<>(); - try { - for (String columnName : schemaItem.getKeys()) { - StructField field = generateStructFieldFromNameAndItem( - columnName, - schemaItem.getItemByKey(columnName) - ); - fields.add(field); - } - } catch (IllegalArgumentException ex) { - InvalidInstanceException e = new InvalidInstanceException( - "Error while applying the schema; " + ex.getMessage() - ); - e.initCause(ex); - throw e; - } - return DataTypes.createStructType(fields); - } - - private static StructField generateStructFieldFromNameAndItem(String columnName, Item item) { - DataType type = generateDataTypeFromItem(item); - return DataTypes.createStructField(columnName, type, true); - } - - private static DataType generateDataTypeFromItem(Item item) { - if (item.isArray()) { - validateArrayItemInSchema(item); - Item arrayContentsTypeItem = item.getItemAt(0); - DataType arrayContentsType = generateDataTypeFromItem(arrayContentsTypeItem); - return DataTypes.createArrayType(arrayContentsType); - } - - if (item.isObject()) { - return generateDataFrameSchemaFromSchemaItem((ObjectItem) item); - } - - if (item.isString()) { - ItemType itemType = BuiltinTypesCatalogue.getItemTypeByName( - Name.createVariableInDefaultTypeNamespace(item.getStringValue()) - ); - return ItemParser.getDataFrameDataTypeFromItemType(itemType); - } - - throw new InvalidInstanceException( - "Schema can only contain arrays, objects or strings: " + item.serialize() + " is not accepted" - ); - } - - private static void validateArrayItemInSchema(Item item) { - List arrayTypes = item.getItems(); - if (arrayTypes.size() == 0) { - throw new InvalidInstanceException( - "Arrays in schema must define a type for their contents." - ); - } - if (arrayTypes.size() > 1) { - throw new InvalidInstanceException( - "Arrays in schema can define only a single type for their contents: " - + item.serialize() - + " is invalid." - ); - } - } - - public static void validateSchemaItemAgainstDataFrame( - ItemType expectedType, - ItemType actualType - ) { - if (expectedType.isAtomicItemType()) { - if (actualType.isSubtypeOf(expectedType)) { - return; - } - throw new InvalidInstanceException( - "Type mismatch: " + expectedType + " vs. " + actualType - ); - } - if (expectedType.isArrayItemType()) { - if (actualType.isArrayItemType()) { - if ( - actualType.getArrayContentFacet() - .getType() - .isSubtypeOf(expectedType.getArrayContentFacet().getType()) - ) { - return; - } - } - throw new InvalidInstanceException( - "Type mismatch: expected " - + expectedType.getArrayContentFacet().getType() - + " but actually " - + actualType.getArrayContentFacet().getType() - ); - } - for (Entry actualTypeDescriptor : actualType.getObjectContentFacet().entrySet()) { - final String actualColumnName = actualTypeDescriptor.getKey(); - final ItemType columnDataType = actualTypeDescriptor.getValue().getType(); - - boolean columnMatched = false; - for ( - Entry expectedTypeDescriptor : expectedType.getObjectContentFacet().entrySet() - ) { - String expectedColumnName = expectedTypeDescriptor.getKey(); - if (!expectedColumnName.equals(actualColumnName)) { - continue; - } - - ItemType expectedColumnType = expectedTypeDescriptor.getValue().getType(); - try { - validateSchemaItemAgainstDataFrame(expectedColumnType, columnDataType); - } catch (Exception e) { - RumbleException ex = new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "expected '" - + expectedColumnType - + "' type for field '" - + actualColumnName - + "', but found '" - + columnDataType - + "'" - ); - ex.initCause(e); - throw ex; - } - - columnMatched = true; - break; - } - - if (!columnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "missing type information for '" - + actualColumnName - + "' field." - ); - } - } - - for (String expectedColumnName : expectedType.getObjectContentFacet().keySet()) { - boolean userColumnMatched = actualType.getObjectContentFacet().keySet().contains(expectedColumnName); - - if (!userColumnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "redundant type information for non-existent field '" - + expectedColumnName - + "'." - ); - } - } - } - - public static boolean isUserTypeApplicable( - DataType userSchemaColumnDataType, - DataType columnDataType - ) { - return userSchemaColumnDataType.equals(columnDataType) - || - (userSchemaColumnDataType.equals(ItemParser.decimalType) && columnDataType.equals(DataTypes.LongType)) - || - (userSchemaColumnDataType.equals(DataTypes.DoubleType) && columnDataType.equals(DataTypes.FloatType)) - || - (userSchemaColumnDataType.equals(DataTypes.IntegerType) && columnDataType.equals(DataTypes.ShortType)); - } -} diff --git a/src/main/java/sparksoniq/spark/SparkSessionManager.java b/src/main/java/sparksoniq/spark/SparkSessionManager.java index 5e77f7b410..c7b0eb85be 100644 --- a/src/main/java/sparksoniq/spark/SparkSessionManager.java +++ b/src/main/java/sparksoniq/spark/SparkSessionManager.java @@ -93,7 +93,10 @@ private void setDefaultConfiguration() { try { this.configuration = new SparkConf(); if (this.configuration.get("spark.app.name", "").equals(" inputDataAsRDDOfItems = dataFrameToRDDOfItems(inputDataAsDataFrame, getMetadata()); + return ValidateTypeIterator.convertRDDToValidDataFrame(inputDataAsRDDOfItems, schemaType); } if (inputDataIterator.isRDDOrDataFrame()) { JavaRDD rdd = inputDataIterator.getRDD(context); return new JSoundDataFrame( - DataFrameUtils.convertItemRDDToDataFrame(rdd, schemaItem), + ValidateTypeIterator.convertItemRDDToDataFrame(rdd, schemaItem), BuiltinTypesCatalogue.objectItem ); } List items = inputDataIterator.materialize(context); return new JSoundDataFrame( - DataFrameUtils.convertLocalItemsToDataFrame(items, schemaItem), + ValidateTypeIterator.convertLocalItemsToDataFrame(items, schemaItem), BuiltinTypesCatalogue.objectItem ); } catch (InvalidInstanceException ex) { diff --git a/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java index ee49819b65..db5a03a89b 100644 --- a/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/GetTransformerFunctionIterator.java @@ -106,7 +106,6 @@ public Item materializeFirstItemOrNull( getMetadata() ); - System.err.println("Setting " + paramJavaTypeName + " to " + paramValueInJava); try { transformer.set(paramName, paramValueInJava); } catch (NoSuchElementException e) { diff --git a/src/main/resources/assets/banner.txt b/src/main/resources/assets/banner.txt index 01013a95ae..bd6364a0e1 100644 --- a/src/main/resources/assets/banner.txt +++ b/src/main/resources/assets/banner.txt @@ -1,6 +1,6 @@ - ____ __ __ - / __ \__ ______ ___ / /_ / /__ - / /_/ / / / / __ `__ \/ __ \/ / _ \ The distributed JSONiq engine - / _, _/ /_/ / / / / / / /_/ / / __/ 1.12.0 "Ashoka Tree" beta -/_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/ + ____ __ __ ____ ____ + / __ \__ ______ ___ / /_ / /__ / __ \/ __ ) + / /_/ / / / / __ `__ \/ __ \/ / _ \/ / / / __ | The distributed JSONiq engine + / _, _/ /_/ / / / / / / /_/ / / __/ /_/ / /_/ / 1.14.0 "Acacia" beta +/_/ |_|\__,_/_/ /_/ /_/_.___/_/\___/_____/_____/ diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type-default.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type-default.jq new file mode 100644 index 0000000000..aa09f33759 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type-default.jq @@ -0,0 +1,16 @@ +(:JIQS: ShouldRun; Output="({ "foo" : "foo", "bar" : "foobar", "int" : 1 }, { "foo" : "foo", "bar" : "def", "int" : 42 }, { "foo" : "foo", "bar" : "foobar", "int" : 42 }, { "foo" : "foo", "bar" : "def", "int" : 42 }, { "foo" : "foo", "bar" : "foobar", "int" : 42 }, { "foo" : "foo", "bar" : "def", "int" : 42 }, { "foo" : "foo", "bar" : "def", "int" : 42 }, { "foo" : "foo", "bar" : "foobar", "int" : 42 }, { "foo" : "foo", "bar" : "def", "int" : 42 }, { "foo" : "foo", "bar" : "foobar", "int" : 42 })" :) +declare type local:a as { "!foo" : "string", "bar" : "string=def", "int" : "integer=42" }; +declare type local:b as { "foo" : "string=def" }; +declare type local:c as { "foo" : "string" }; + +validate type local:a { { "foo" : "foo", "bar" : "foobar", "int" : 1 } }, +validate type local:a { { "foo" : "foo" } }, +validate type local:a { parallelize({ "foo" : "foo", "bar" : "foobar" }) }, +validate type local:a { parallelize({ "foo" : "foo" }) }, +validate type local:a { validate type local:a* { { "foo" : "foo", "bar" : "foobar" } } }, +validate type local:a { validate type local:c* { { "foo" : "foo" } } }, + +validate type local:a* { { "foo" : "foo" }, { "foo" : "foo", "bar" : "foobar" } }, +validate type local:a* { parallelize(({ "foo" : "foo" }, { "foo" : "foo", "bar" : "foobar" })) }(:, +validate type local:a* { validate type local:a* { { "foo" : "foo", "bar" : "foobar" } } }, +validate type local:a* { validate type local:c* { { "foo" : "foo" } } }:) diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type-single.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type-single.jq new file mode 100644 index 0000000000..0ec30ae6b1 --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type-single.jq @@ -0,0 +1,168 @@ +(:JIQS: ShouldRun; Output="({ "foo" : 2 }, { }, { "foo" : 2 }, Success, Success, true, true, true, true, true, true, true, true, true, true, true, Success, { "foo" : "foo" }, Success, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, { }, Success, Success, { "foo" : [ "foo" ] }, { "foo" : [ 2 ] }, Success, Success, { "foo" : [ "foo" ] }, Success)" :) +declare type local:x as { "foo" : "integer" }; +declare type local:y as { "foo" : [ "integer" ] }; +declare type local:z as { "!foo" : [ "integer" ] }; +validate type local:x { + { "foo" : 2 } +}, +validate type local:x? { + { } +}, +validate type local:x? { + { "foo" : 2 } +}, +try { + validate type local:z? { + { "foo" : [ "foo" ] }, + { "foo" : [ "foo" ] } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:z { + { "foo" : [ "foo" ] }, + { "foo" : [ "foo" ] } + } +} catch XQDY0027 { + "Success" +}, +validate type local:x { + { "foo" : 2 } +} instance of local:x, +validate type local:x { + { "foo" : 2 } +} instance of local:x?, +validate type local:x { + { "foo" : 2 } +} instance of local:x*, +validate type local:x { + { "foo" : 2 } +} instance of local:x+, +validate type local:x? { + { "foo" : 2 } +} instance of local:x, +validate type local:x? { + { "foo" : 2 } +} instance of local:x?, +validate type local:x? { + { "foo" : 2 } +} instance of local:x*, +validate type local:x? { + { "foo" : 2 } +} instance of local:x+, + +(validate type local:x { + { "foo" : 2 } +}).foo instance of integer, + +(validate type local:y { parallelize(( + { "foo" : [ 3, 4 ] } +))}).foo[] instance of integer+, + +(validate type local:y+ { + { "foo" : [ 2 ] } +}).foo instance of array*, +try { + validate type local:x { + { "foo" : 2, "bar" : 3 } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x { + { "foo" : "foo" } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x { + { "foo" : [ 1 ] } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x { + { "foo" : { "bar" : 2 } } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x { + 2, 3 + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x { + [ "foo" ] + } +} catch XQDY0027 { + "Success" +}, +validate type local:y { + { "foo" : [ 2 ] } +}, +validate type local:y { + { "foo" : [ 3, 4 ] } +}, +validate type local:y { + { } +}, +try { + validate type local:y { + { "foo" : 2 } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:y { + { "foo" : { "bar" : "foo" } } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:y { + { "foo" : [ "foo" ] } + } +} catch XQDY0027 { + "Success" +}, +validate type local:z { + { "foo" : [ 2 ] } +}, +try { + validate type local:z { + { "foo" : 2 } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:z { + { "foo" : { "bar" : "foo" } } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:z { + { "foo" : [ "foo" ] } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:z { + { } + } +} catch XQDY0027 { + "Success" +} diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type1.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type1.jq index 20998da65c..0e5e6084be 100644 --- a/src/test/resources/test_files/runtime-native-flwor/udt/type1.jq +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "foo" : 2 }, { "foo" : 3 }, { }, true, true, true, true, { "foo" : 2 }, Success, Success, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, { }, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, Success, Success, Success, Success)" :) +(:JIQS: ShouldRun; Output="({ "foo" : 2 }, { "foo" : 3 }, { }, true, true, true, true, Success, Success, Success, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, { }, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, Success, Success, Success, Success)" :) declare type local:x as { "foo" : "integer" }; declare type local:y as { "foo" : [ "integer" ] }; declare type local:z as { "!foo" : [ "integer" ] }; diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq index af35d747bd..41554adb3e 100644 --- a/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 1 }, { "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 2 }, { "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ], "foobar" : 3 })" :) +(:JIQS: ShouldRun; Output="({ "foobar" : 1, "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ] }, { "foobar" : 2, "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ] }, { "foobar" : 3, "bar" : [ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ] })" :) declare type local:at as { "foo" : "integer" }; declare type local:bt as { "foobar" : "integer", "bar" : [ "local:at" ] }; diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type5.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type5.jq new file mode 100644 index 0000000000..6b6aebf75d --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type5.jq @@ -0,0 +1,15 @@ +(:JIQS: ShouldRun; Output="(Success, Success)" :) +declare type local:a as { "foo" : "integer" }; +declare type local:b as { "foo" : "integer", "bar" : "string" }; + +try { +validate type local:a* { validate type local:b* { { "foo" : 1, "bar" : 2 } } } +} catch XQDY0027 { + "Success" +}, + +try { +validate type local:a* { { "foo" : 1, "bar" : 2 } } +} catch XQDY0027 { + "Success" +} \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/typeError2.jq b/src/test/resources/test_files/runtime-native-flwor/udt/typeError2.jq deleted file mode 100644 index e9fd040377..0000000000 --- a/src/test/resources/test_files/runtime-native-flwor/udt/typeError2.jq +++ /dev/null @@ -1,3 +0,0 @@ -(:JIQS: ShouldNotParse; ErrorCode="XQST0012"; ErrorMetadata="LINE:1:COLUMN:0:" :) -declare type local:x as { "foo" : "integer=2" }; -2+2 diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq index 440b3a5892..fb505b83e2 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF-SchemaError4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XQDY0027"; :) +(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8 }, { "id" : 2, "age" : 35, "weight" : 72.4 }, { "id" : 3, "age" : 50, "weight" : 76.3 })" :) annotate( structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), {"id": "integer", "age": "integer", "weight": "decimal"} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF1.jq index 818b9e9cdc..2b2e584ce6 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8 }, { "age" : 35, "id" : 2, "weight" : 72.4 }, { "age" : 50, "id" : 3, "weight" : 76.3 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8 }, { "id" : 2, "age" : 35, "weight" : 72.4 }, { "id" : 3, "age" : 50, "weight" : 76.3 })" :) annotate( structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json"), {"id": "decimal", "age": "decimal", "weight": "double"} diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq deleted file mode 100644 index e41775902c..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq +++ /dev/null @@ -1,7 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "label" : 0, "features" : { } }, { "label" : 1, "features" : { "0" : 0.1, "1" : 0.1, "2" : 0.1 } }, { "label" : 2, "features" : { "0" : 0.2, "1" : 0.2, "2" : 0.2 } }, { "label" : 3, "features" : { "0" : 9, "1" : 9, "2" : 9 } }, { "label" : 4, "features" : { "0" : 9.1, "1" : 9.1, "2" : 9.1 } }, { "label" : 5, "features" : { "0" : 9.2, "1" : 9.2, "2" : 9.2 } })" :) -annotate( - libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-kmeans.txt"), - {"label": "double", "features": "array"} -) - -(: annotate with vector type representation in the 'features' :) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq index 25be9df18a..7538a6435b 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0, "features" : [ 0 ], "prediction" : 1 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0, "features" : [ 0 ], "prediction" : 1 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1, "features" : [ 1 ], "prediction" : 0 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq index 5dcc007192..3204b05df9 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) declare type local:mytype as { "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq index 2f918638f8..520c307381 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq index ef83c7cdc5..297bb024ea 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq index c5f2d43411..f2bbe8ed97 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col2" : 1.5, "col3" : 1.3, "col1" : -1, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col2" : 2, "col3" : -0.1, "col1" : 3, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col2" : 2.2, "col3" : -1.5, "col1" : 0, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $pipeline := get-estimator("Pipeline", { diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq index 5853987134..5eeff54f61 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XPDY0130"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) asd#true (: using non-integer literals for arity :) diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq index 5e55b26721..ed7c8e767a 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldCrash; ErrorCode="XPDY0130"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) asd#.9 (: using non-integer literals for arity :) From 776bdee251718c223c6c4317c91be04d60530ca4 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 10 Jul 2021 18:52:53 +0200 Subject: [PATCH 079/142] fix duplicate method. --- src/main/java/org/rumbledb/types/ObjectItemType.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/main/java/org/rumbledb/types/ObjectItemType.java b/src/main/java/org/rumbledb/types/ObjectItemType.java index 9bec76465f..ce08fba148 100644 --- a/src/main/java/org/rumbledb/types/ObjectItemType.java +++ b/src/main/java/org/rumbledb/types/ObjectItemType.java @@ -264,13 +264,4 @@ public void resolve(StaticContext context, ExceptionMetadata metadata) { entry.getValue().resolve(context, metadata); } } - - @Override - public void resolve(StaticContext context, ExceptionMetadata metadata) { - for (Map.Entry entry : this.content.entrySet()) { - if (!entry.getValue().getType().isResolved()) { - entry.getValue().getType().resolve(context, metadata); - } - } - } } From bbdbd7eb4818620081ee44929f1d301be8eb6e61 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:42:04 +0200 Subject: [PATCH 080/142] Take over. --- docs/RumbleML.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/RumbleML.md b/docs/RumbleML.md index aeb511f23e..03d1b683be 100644 --- a/docs/RumbleML.md +++ b/docs/RumbleML.md @@ -29,19 +29,11 @@ Transformers and estimators are function items in the RumbleDB Data Model. Their ## Type Annotations -<<<<<<< HEAD -RumbleML works on highly structured data, because it requires full type information for all the fields in the training set or test set. It is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly. - -Rumble supports a user-defined type system with which you can validate and annotate datasets against a JSound schema. - -This annotation is required to be applied on any dataset that must be used as input to RumbleML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. -======= RumbleDB ML works on highly structured data, because it requires full type information for all the fields in the training set or test set. It is on our development plan to automate the detection of these types when the sequence of objects gets created in the fly. RumbleDB supports a user-defined type system with which you can validate and annotate datasets against a JSound schema. This annotation is required to be applied on any dataset that must be used as input to RumbleDB ML, but it is superfluous if the data was directly read from a structured input format such as Parquet, CSV, Avro, SVM or ROOT. ->>>>>>> ddae27156d839030762872201ae0d5961abc2b16 ## Examples From c180f768cfc091b2e83237015aa9f81e3d0f0681 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:43:46 +0200 Subject: [PATCH 081/142] Remove import. --- src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java index bf410f04c4..48d6e9a51a 100644 --- a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java @@ -14,7 +14,6 @@ import org.rumbledb.types.ItemType; import org.rumbledb.types.ItemTypeFactory; -import sparksoniq.spark.DataFrameUtils; import java.util.List; From 4212aee33bb0313e884d669ee4244a21df023cc9 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:44:19 +0200 Subject: [PATCH 082/142] Remove diff. --- src/main/java/org/rumbledb/types/JsonItemType.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/rumbledb/types/JsonItemType.java b/src/main/java/org/rumbledb/types/JsonItemType.java index 37aa427ddb..17017aeb17 100644 --- a/src/main/java/org/rumbledb/types/JsonItemType.java +++ b/src/main/java/org/rumbledb/types/JsonItemType.java @@ -20,7 +20,6 @@ public class JsonItemType implements ItemType { this.name = new Name(Name.JS_NS, "js", "json-item"); } - @Override public boolean equals(Object other) { if (!(other instanceof ItemType)) { From 5956bc4c84aa21f39e63bd29d2c06b8de98f01a8 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:44:59 +0200 Subject: [PATCH 083/142] Fix diff. --- src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java index 48d6e9a51a..8a6cf2231b 100644 --- a/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java +++ b/src/main/java/sparksoniq/spark/ml/AnnotateFunctionIterator.java @@ -14,7 +14,6 @@ import org.rumbledb.types.ItemType; import org.rumbledb.types.ItemTypeFactory; - import java.util.List; public class AnnotateFunctionIterator extends DataFrameRuntimeIterator { From 2bd714ead6db3a55929fe224e4f737210ca04797 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:45:58 +0200 Subject: [PATCH 084/142] Update ObjectItemType.java --- src/main/java/org/rumbledb/types/ObjectItemType.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/types/ObjectItemType.java b/src/main/java/org/rumbledb/types/ObjectItemType.java index 0cb6734c07..f20eb506a9 100644 --- a/src/main/java/org/rumbledb/types/ObjectItemType.java +++ b/src/main/java/org/rumbledb/types/ObjectItemType.java @@ -244,7 +244,6 @@ public boolean isDataFrameType() { public boolean isResolved() { for (Map.Entry entry : this.content.entrySet()) { if (!entry.getValue().getType().isResolved()) { - System.err.println("Unresolved: " + entry.getValue().getType().getClass().getCanonicalName()); return false; } } @@ -254,7 +253,9 @@ public boolean isResolved() { @Override public void resolve(DynamicContext context, ExceptionMetadata metadata) { for (Map.Entry entry : this.content.entrySet()) { - entry.getValue().resolve(context, metadata); + if (!entry.getValue().getType().isResolved()) { + entry.getValue().resolve(context, metadata); + } } } From f4d9239daf1a3c3500f28a0d73fd89983846a081 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 13:46:42 +0200 Subject: [PATCH 085/142] Fix tests. --- .../RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq | 2 +- .../RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq index 05e08126c6..a1035cc0f0 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq index 4b9cb48843..1016c7a0ba 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateForChaining2.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "age" : 20, "id" : 1, "weight" : 68.8, "binarized_weight" : 0, "binarized_weight2" : 0 }, { "age" : 35, "id" : 2, "weight" : 72.4, "binarized_weight" : 1, "binarized_weight2" : 0 }, { "age" : 50, "id" : 3, "weight" : 76.3, "binarized_weight" : 1, "binarized_weight2" : 0 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 1, "age" : 20, "weight" : 68.8, "binarized_weight" : 0, "binarized_weight2" : 0 }, { "id" : 2, "age" : 35, "weight" : 72.4, "binarized_weight" : 1, "binarized_weight2" : 0 }, { "id" : 3, "age" : 50, "weight" : 76.3, "binarized_weight" : 1, "binarized_weight2" : 0 })" :) let $data := structured-json-file("../../../../queries/rumbleML/sample-ml-data-age-weight.json") let $binarizer := get-transformer("Binarizer") From 418b75e711078401792a9427c242d879e4e59026 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 14:28:46 +0200 Subject: [PATCH 086/142] Remove test. --- .../RumbleML/AnnotateFunction/MLAnnotateDF2.jq | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq deleted file mode 100644 index e41775902c..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/AnnotateFunction/MLAnnotateDF2.jq +++ /dev/null @@ -1,7 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "label" : 0, "features" : { } }, { "label" : 1, "features" : { "0" : 0.1, "1" : 0.1, "2" : 0.1 } }, { "label" : 2, "features" : { "0" : 0.2, "1" : 0.2, "2" : 0.2 } }, { "label" : 3, "features" : { "0" : 9, "1" : 9, "2" : 9 } }, { "label" : 4, "features" : { "0" : 9.1, "1" : 9.1, "2" : 9.1 } }, { "label" : 5, "features" : { "0" : 9.2, "1" : 9.2, "2" : 9.2 } })" :) -annotate( - libsvm-file("../../../../queries/rumbleML/sample-libsvm-data-kmeans.txt"), - {"label": "double", "features": "array"} -) - -(: annotate with vector type representation in the 'features' :) From 367a155ba7f3ffbab43f56f8f647f4531c66f018 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 13 Jul 2021 14:29:25 +0200 Subject: [PATCH 087/142] Remove unused file. --- .../java/sparksoniq/spark/DataFrameUtils.java | 262 ------------------ 1 file changed, 262 deletions(-) delete mode 100644 src/main/java/sparksoniq/spark/DataFrameUtils.java diff --git a/src/main/java/sparksoniq/spark/DataFrameUtils.java b/src/main/java/sparksoniq/spark/DataFrameUtils.java deleted file mode 100644 index 7ca241a805..0000000000 --- a/src/main/java/sparksoniq/spark/DataFrameUtils.java +++ /dev/null @@ -1,262 +0,0 @@ -package sparksoniq.spark; - -import org.apache.spark.api.java.JavaRDD; -import org.apache.spark.api.java.function.Function; -import org.apache.spark.sql.Dataset; -import org.apache.spark.sql.Row; -import org.apache.spark.sql.types.DataType; -import org.apache.spark.sql.types.DataTypes; -import org.apache.spark.sql.types.StructField; -import org.apache.spark.sql.types.StructType; -import org.rumbledb.api.Item; -import org.rumbledb.context.Name; -import org.rumbledb.exceptions.InvalidInstanceException; -import org.rumbledb.exceptions.RumbleException; -import org.rumbledb.items.ObjectItem; -import org.rumbledb.items.parsing.ItemParser; -import org.rumbledb.runtime.typing.ValidateTypeIterator; -import org.rumbledb.types.BuiltinTypesCatalogue; -import org.rumbledb.types.FieldDescriptor; -import org.rumbledb.types.ItemType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; - -public class DataFrameUtils { - public static Dataset convertItemRDDToDataFrame( - JavaRDD itemRDD, - Item schemaItem - ) { - Item firstDataItem = (Item) itemRDD.take(1).get(0); - validateSchemaAgainstAnItem(schemaItem, firstDataItem); - StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); - JavaRDD rowRDD = itemRDD.map( - new Function() { - private static final long serialVersionUID = 1L; - - @Override - public Row call(Item item) { - return ValidateTypeIterator.convertLocalItemToRow(item, null, schema); - } - } - ); - return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rowRDD, schema); - } - - public static Dataset convertLocalItemsToDataFrame( - List items, - Item schemaItem - ) { - if (items.size() == 0) { - return SparkSessionManager.getInstance().getOrCreateSession().emptyDataFrame(); - } - ObjectItem firstDataItem = (ObjectItem) items.get(0); - validateSchemaAgainstAnItem(schemaItem, firstDataItem); - StructType schema = generateDataFrameSchemaFromSchemaItem(schemaItem); - List rows = getRowsFromItemsUsingSchema(items, null, schema); - return SparkSessionManager.getInstance().getOrCreateSession().createDataFrame(rows, schema); - } - - private static List getRowsFromItemsUsingSchema(List items, ItemType itemType, StructType schema) { - List rows = new ArrayList<>(); - for (Item item : items) { - Row row = ValidateTypeIterator.convertLocalItemToRow(item, itemType, schema); - rows.add(row); - } - return rows; - } - - private static void validateSchemaAgainstAnItem( - Item schemaItem, - Item dataItem - ) { - for (String schemaColumn : schemaItem.getKeys()) { - if (!dataItem.getKeys().contains(schemaColumn)) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "redundant type information for non-existent field '" - + schemaColumn - + "' column." - ); - } - } - - for (String dataColumn : dataItem.getKeys()) { - if (!schemaItem.getKeys().contains(dataColumn)) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "missing type information for '" - + dataColumn - + "' field." - ); - } - } - } - - private static StructType generateDataFrameSchemaFromSchemaItem(Item schemaItem) { - List fields = new ArrayList<>(); - try { - for (String columnName : schemaItem.getKeys()) { - StructField field = generateStructFieldFromNameAndItem( - columnName, - schemaItem.getItemByKey(columnName) - ); - fields.add(field); - } - } catch (IllegalArgumentException ex) { - InvalidInstanceException e = new InvalidInstanceException( - "Error while applying the schema; " + ex.getMessage() - ); - e.initCause(ex); - throw e; - } - return DataTypes.createStructType(fields); - } - - private static StructField generateStructFieldFromNameAndItem(String columnName, Item item) { - DataType type = generateDataTypeFromItem(item); - return DataTypes.createStructField(columnName, type, true); - } - - private static DataType generateDataTypeFromItem(Item item) { - if (item.isArray()) { - validateArrayItemInSchema(item); - Item arrayContentsTypeItem = item.getItemAt(0); - DataType arrayContentsType = generateDataTypeFromItem(arrayContentsTypeItem); - return DataTypes.createArrayType(arrayContentsType); - } - - if (item.isObject()) { - return generateDataFrameSchemaFromSchemaItem((ObjectItem) item); - } - - if (item.isString()) { - ItemType itemType = BuiltinTypesCatalogue.getItemTypeByName( - Name.createVariableInDefaultTypeNamespace(item.getStringValue()) - ); - return ItemParser.getDataFrameDataTypeFromItemType(itemType); - } - - throw new InvalidInstanceException( - "Schema can only contain arrays, objects or strings: " + item.serialize() + " is not accepted" - ); - } - - private static void validateArrayItemInSchema(Item item) { - List arrayTypes = item.getItems(); - if (arrayTypes.size() == 0) { - throw new InvalidInstanceException( - "Arrays in schema must define a type for their contents." - ); - } - if (arrayTypes.size() > 1) { - throw new InvalidInstanceException( - "Arrays in schema can define only a single type for their contents: " - + item.serialize() - + " is invalid." - ); - } - } - - public static void validateSchemaItemAgainstDataFrame( - ItemType expectedType, - ItemType actualType - ) { - if (expectedType.isAtomicItemType()) { - if (actualType.isSubtypeOf(expectedType)) { - return; - } - throw new InvalidInstanceException( - "Type mismatch: " + expectedType + " vs. " + actualType - ); - } - if (expectedType.isArrayItemType()) { - if (actualType.isArrayItemType()) { - if ( - actualType.getArrayContentFacet() - .getType() - .isSubtypeOf(expectedType.getArrayContentFacet().getType()) - ) { - return; - } - } - throw new InvalidInstanceException( - "Type mismatch: expected " - + expectedType.getArrayContentFacet().getType() - + " but actually " - + actualType.getArrayContentFacet().getType() - ); - } - for (Entry actualTypeDescriptor : actualType.getObjectContentFacet().entrySet()) { - final String actualColumnName = actualTypeDescriptor.getKey(); - final ItemType columnDataType = actualTypeDescriptor.getValue().getType(); - - boolean columnMatched = false; - for ( - Entry expectedTypeDescriptor : expectedType.getObjectContentFacet().entrySet() - ) { - String expectedColumnName = expectedTypeDescriptor.getKey(); - if (!expectedColumnName.equals(actualColumnName)) { - continue; - } - - ItemType expectedColumnType = expectedTypeDescriptor.getValue().getType(); - try { - validateSchemaItemAgainstDataFrame(expectedColumnType, columnDataType); - } catch (Exception e) { - RumbleException ex = new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "expected '" - + expectedColumnType - + "' type for field '" - + actualColumnName - + "', but found '" - + columnDataType - + "'" - ); - ex.initCause(e); - throw ex; - } - - columnMatched = true; - break; - } - - if (!columnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "missing type information for '" - + actualColumnName - + "' field." - ); - } - } - - for (String expectedColumnName : expectedType.getObjectContentFacet().keySet()) { - boolean userColumnMatched = actualType.getObjectContentFacet().keySet().contains(expectedColumnName); - - if (!userColumnMatched) { - throw new InvalidInstanceException( - "Fields defined in schema must fully match the fields of input data: " - + "redundant type information for non-existent field '" - + expectedColumnName - + "'." - ); - } - } - } - - public static boolean isUserTypeApplicable( - DataType userSchemaColumnDataType, - DataType columnDataType - ) { - return userSchemaColumnDataType.equals(columnDataType) - || - (userSchemaColumnDataType.equals(ItemParser.decimalType) && columnDataType.equals(DataTypes.LongType)) - || - (userSchemaColumnDataType.equals(DataTypes.DoubleType) && columnDataType.equals(DataTypes.FloatType)) - || - (userSchemaColumnDataType.equals(DataTypes.IntegerType) && columnDataType.equals(DataTypes.ShortType)); - } -} From 39ec83097f0dee8f6ac770e653631de955db7be9 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 15:32:52 +0200 Subject: [PATCH 088/142] unordered keyw --- src/main/java/org/rumbledb/parser/Jsoniq.g4 | 8 ++++---- .../runtime/functions/io/CollectionFunctionIterator.java | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index b4f3b24dd7..b336d4a6bf 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -39,10 +39,7 @@ decimalFormatDecl : 'declare' (dfPropertyName '=' stringLiteral)*; qname : ((ns=NCName | nskw=keyWords)':')? - (local_name=nCNameOrKeyWord | local_namekw = keyWords); - -nCNameOrKeyWord : NCName - | NullLiteral; + (local_name=NCName | local_namekw = keyWords); dfPropertyName : 'decimal-separator' | 'grouping-separator' @@ -299,6 +296,7 @@ keyWords : Kjsoniq | Korder | Kcount | Kreturn + | Kunordered ; ///////////////////////// literals @@ -391,6 +389,8 @@ Kversion : 'version'; Kjsoniq : 'jsoniq'; +Kunordered : 'unordered'; + STRING : '"' (ESC | ~ ["\\])* '"'; fragment ESC : '\\' (["\\/bfnrt] | UNICODE); diff --git a/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java index a16e792bcc..c485ae7b77 100644 --- a/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java @@ -28,6 +28,8 @@ public CollectionFunctionIterator( super(children, executionMode, iteratorMetadata); } + //TODO: implement collection function + @Override public JSoundDataFrame getDataFrame(DynamicContext context) { Item stringItem = this.children.get(0) @@ -39,8 +41,7 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { } Item optionsObjectItem; DataFrameReader dfr = SparkSessionManager.getInstance().getOrCreateSession().read(); - String extension - switch + return JSoundDataFrame.emptyDataFrame(); } } From df3efba4eb36ae85e147c0cb9e21a4181a46a87b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 17:01:44 +0200 Subject: [PATCH 089/142] fn:unordered allowed + clean grammar file. --- .../context/BuiltinFunctionCatalogue.java | 2 +- .../java/org/rumbledb/parser/Jsoniq.tokens | 284 +- .../rumbledb/parser/JsoniqBaseVisitor.java | 7 - .../java/org/rumbledb/parser/JsoniqLexer.java | 597 ++-- .../org/rumbledb/parser/JsoniqLexer.tokens | 284 +- .../org/rumbledb/parser/JsoniqParser.java | 2589 ++++++++--------- .../org/rumbledb/parser/JsoniqVisitor.java | 6 - 7 files changed, 1875 insertions(+), 1894 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index cf34dbda09..5311155886 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -622,7 +622,7 @@ private static BuiltinFunction createBuiltinFunction( new Name( Name.FN_NS, "fn", - "unorder" + "unordered" ), "item*", "item*", diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.tokens b/src/main/java/org/rumbledb/parser/Jsoniq.tokens index d1974c069c..ced2126dd5 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.tokens +++ b/src/main/java/org/rumbledb/parser/Jsoniq.tokens @@ -57,51 +57,51 @@ T__55=56 T__56=57 T__57=58 T__58=59 -T__59=60 -Kfor=61 -Klet=62 -Kwhere=63 -Kgroup=64 -Kby=65 -Korder=66 -Kreturn=67 -Kif=68 -Kin=69 -Kas=70 -Kat=71 -Kallowing=72 -Kempty=73 -Kcount=74 -Kstable=75 -Kascending=76 -Kdescending=77 -Ksome=78 -Kevery=79 -Ksatisfies=80 -Kcollation=81 -Kgreatest=82 -Kleast=83 -Kswitch=84 -Kcase=85 -Ktry=86 -Kcatch=87 -Kdefault=88 -Kthen=89 -Kelse=90 -Ktypeswitch=91 -Kor=92 -Kand=93 -Knot=94 -Kto=95 -Kinstance=96 -Kof=97 -Kstatically=98 -Kis=99 -Ktreat=100 -Kcast=101 -Kcastable=102 -Kversion=103 -Kjsoniq=104 +Kfor=60 +Klet=61 +Kwhere=62 +Kgroup=63 +Kby=64 +Korder=65 +Kreturn=66 +Kif=67 +Kin=68 +Kas=69 +Kat=70 +Kallowing=71 +Kempty=72 +Kcount=73 +Kstable=74 +Kascending=75 +Kdescending=76 +Ksome=77 +Kevery=78 +Ksatisfies=79 +Kcollation=80 +Kgreatest=81 +Kleast=82 +Kswitch=83 +Kcase=84 +Ktry=85 +Kcatch=86 +Kdefault=87 +Kthen=88 +Kelse=89 +Ktypeswitch=90 +Kor=91 +Kand=92 +Knot=93 +Kto=94 +Kinstance=95 +Kof=96 +Kstatically=97 +Kis=98 +Ktreat=99 +Kcast=100 +Kcastable=101 +Kversion=102 +Kjsoniq=103 +Kunordered=104 STRING=105 ArgumentPlaceholder=106 NullLiteral=107 @@ -122,102 +122,102 @@ ContentChar=117 'declare'=5 'ordering'=6 'ordered'=7 -'unordered'=8 -'decimal-format'=9 -':'=10 -'decimal-separator'=11 -'grouping-separator'=12 -'infinity'=13 -'minus-sign'=14 -'NaN'=15 -'percent'=16 -'per-mille'=17 -'zero-digit'=18 -'digit'=19 -'pattern-separator'=20 -'import'=21 -','=22 -'variable'=23 -':='=24 -'external'=25 -'function'=26 -'('=27 -')'=28 -'{'=29 -'}'=30 -'type'=31 -'$'=32 -'|'=33 -'*'=34 -'eq'=35 -'ne'=36 -'lt'=37 -'le'=38 -'gt'=39 -'ge'=40 -'!='=41 -'<'=42 -'<='=43 -'>'=44 -'>='=45 -'||'=46 -'+'=47 -'-'=48 -'div'=49 -'idiv'=50 -'mod'=51 -'validate'=52 -'!'=53 -'['=54 -']'=55 -'.'=56 -'$$'=57 -'#'=58 -'{|'=59 -'|}'=60 -'for'=61 -'let'=62 -'where'=63 -'group'=64 -'by'=65 -'order'=66 -'return'=67 -'if'=68 -'in'=69 -'as'=70 -'at'=71 -'allowing'=72 -'empty'=73 -'count'=74 -'stable'=75 -'ascending'=76 -'descending'=77 -'some'=78 -'every'=79 -'satisfies'=80 -'collation'=81 -'greatest'=82 -'least'=83 -'switch'=84 -'case'=85 -'try'=86 -'catch'=87 -'default'=88 -'then'=89 -'else'=90 -'typeswitch'=91 -'or'=92 -'and'=93 -'not'=94 -'to'=95 -'instance'=96 -'of'=97 -'statically'=98 -'is'=99 -'treat'=100 -'cast'=101 -'castable'=102 -'version'=103 -'jsoniq'=104 +'decimal-format'=8 +':'=9 +'decimal-separator'=10 +'grouping-separator'=11 +'infinity'=12 +'minus-sign'=13 +'NaN'=14 +'percent'=15 +'per-mille'=16 +'zero-digit'=17 +'digit'=18 +'pattern-separator'=19 +'import'=20 +','=21 +'variable'=22 +':='=23 +'external'=24 +'function'=25 +'('=26 +')'=27 +'{'=28 +'}'=29 +'type'=30 +'$'=31 +'|'=32 +'*'=33 +'eq'=34 +'ne'=35 +'lt'=36 +'le'=37 +'gt'=38 +'ge'=39 +'!='=40 +'<'=41 +'<='=42 +'>'=43 +'>='=44 +'||'=45 +'+'=46 +'-'=47 +'div'=48 +'idiv'=49 +'mod'=50 +'validate'=51 +'!'=52 +'['=53 +']'=54 +'.'=55 +'$$'=56 +'#'=57 +'{|'=58 +'|}'=59 +'for'=60 +'let'=61 +'where'=62 +'group'=63 +'by'=64 +'order'=65 +'return'=66 +'if'=67 +'in'=68 +'as'=69 +'at'=70 +'allowing'=71 +'empty'=72 +'count'=73 +'stable'=74 +'ascending'=75 +'descending'=76 +'some'=77 +'every'=78 +'satisfies'=79 +'collation'=80 +'greatest'=81 +'least'=82 +'switch'=83 +'case'=84 +'try'=85 +'catch'=86 +'default'=87 +'then'=88 +'else'=89 +'typeswitch'=90 +'or'=91 +'and'=92 +'not'=93 +'to'=94 +'instance'=95 +'of'=96 +'statically'=97 +'is'=98 +'treat'=99 +'cast'=100 +'castable'=101 +'version'=102 +'jsoniq'=103 +'unordered'=104 '?'=106 'null'=107 diff --git a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java index 92740acf74..83170d5853 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java @@ -105,13 +105,6 @@ public class JsoniqBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitQname(JsoniqParser.QnameContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitNCNameOrKeyWord(JsoniqParser.NCNameOrKeyWordContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/src/main/java/org/rumbledb/parser/JsoniqLexer.java b/src/main/java/org/rumbledb/parser/JsoniqLexer.java index cef633b58c..fa1e474817 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.java +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.java @@ -3,16 +3,14 @@ // Java header package org.rumbledb.parser; -import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.RuntimeMetaData; -import org.antlr.v4.runtime.Vocabulary; -import org.antlr.v4.runtime.VocabularyImpl; -import org.antlr.v4.runtime.atn.ATN; -import org.antlr.v4.runtime.atn.ATNDeserializer; -import org.antlr.v4.runtime.atn.LexerATNSimulator; -import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class JsoniqLexer extends Lexer { @@ -30,16 +28,16 @@ public class JsoniqLexer extends Lexer { T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, - T__59=60, Kfor=61, Klet=62, Kwhere=63, Kgroup=64, Kby=65, Korder=66, Kreturn=67, - Kif=68, Kin=69, Kas=70, Kat=71, Kallowing=72, Kempty=73, Kcount=74, Kstable=75, - Kascending=76, Kdescending=77, Ksome=78, Kevery=79, Ksatisfies=80, Kcollation=81, - Kgreatest=82, Kleast=83, Kswitch=84, Kcase=85, Ktry=86, Kcatch=87, Kdefault=88, - Kthen=89, Kelse=90, Ktypeswitch=91, Kor=92, Kand=93, Knot=94, Kto=95, - Kinstance=96, Kof=97, Kstatically=98, Kis=99, Ktreat=100, Kcast=101, Kcastable=102, - Kversion=103, Kjsoniq=104, STRING=105, ArgumentPlaceholder=106, NullLiteral=107, - Literal=108, NumericLiteral=109, BooleanLiteral=110, IntegerLiteral=111, - DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, XQComment=116, - ContentChar=117; + Kfor=60, Klet=61, Kwhere=62, Kgroup=63, Kby=64, Korder=65, Kreturn=66, + Kif=67, Kin=68, Kas=69, Kat=70, Kallowing=71, Kempty=72, Kcount=73, Kstable=74, + Kascending=75, Kdescending=76, Ksome=77, Kevery=78, Ksatisfies=79, Kcollation=80, + Kgreatest=81, Kleast=82, Kswitch=83, Kcase=84, Ktry=85, Kcatch=86, Kdefault=87, + Kthen=88, Kelse=89, Ktypeswitch=90, Kor=91, Kand=92, Knot=93, Kto=94, + Kinstance=95, Kof=96, Kstatically=97, Kis=98, Ktreat=99, Kcast=100, Kcastable=101, + Kversion=102, Kjsoniq=103, Kunordered=104, STRING=105, ArgumentPlaceholder=106, + NullLiteral=107, Literal=108, NumericLiteral=109, BooleanLiteral=110, + IntegerLiteral=111, DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, + XQComment=116, ContentChar=117; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -56,35 +54,34 @@ public class JsoniqLexer extends Lexer { "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48", "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", - "T__57", "T__58", "T__59", "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", - "Korder", "Kreturn", "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", - "Kcount", "Kstable", "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", + "T__57", "T__58", "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", + "Kreturn", "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", + "Kstable", "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", - "Kversion", "Kjsoniq", "STRING", "ESC", "UNICODE", "HEX", "ArgumentPlaceholder", - "NullLiteral", "Literal", "NumericLiteral", "BooleanLiteral", "IntegerLiteral", - "DecimalLiteral", "DoubleLiteral", "Digits", "WS", "NCName", "NameStartChar", - "NameChar", "XQComment", "ContentChar" + "Kversion", "Kjsoniq", "Kunordered", "STRING", "ESC", "UNICODE", "HEX", + "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", "BooleanLiteral", + "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", "Digits", "WS", "NCName", + "NameStartChar", "NameChar", "XQComment", "ContentChar" }; private static final String[] _LITERAL_NAMES = { null, "';'", "'module'", "'namespace'", "'='", "'declare'", "'ordering'", - "'ordered'", "'unordered'", "'decimal-format'", "':'", "'decimal-separator'", - "'grouping-separator'", "'infinity'", "'minus-sign'", "'NaN'", "'percent'", - "'per-mille'", "'zero-digit'", "'digit'", "'pattern-separator'", "'import'", - "','", "'variable'", "':='", "'external'", "'function'", "'('", "')'", - "'{'", "'}'", "'type'", "'$'", "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", - "'gt'", "'ge'", "'!='", "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", - "'div'", "'idiv'", "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", - "'$$'", "'#'", "'{|'", "'|}'", "'for'", "'let'", "'where'", "'group'", - "'by'", "'order'", "'return'", "'if'", "'in'", "'as'", "'at'", "'allowing'", - "'empty'", "'count'", "'stable'", "'ascending'", "'descending'", "'some'", - "'every'", "'satisfies'", "'collation'", "'greatest'", "'least'", "'switch'", - "'case'", "'try'", "'catch'", "'default'", "'then'", "'else'", "'typeswitch'", - "'or'", "'and'", "'not'", "'to'", "'instance'", "'of'", "'statically'", - "'is'", "'treat'", "'cast'", "'castable'", "'version'", "'jsoniq'", null, - "'?'", "'null'" + "'ordered'", "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", + "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", + "'digit'", "'pattern-separator'", "'import'", "','", "'variable'", "':='", + "'external'", "'function'", "'('", "')'", "'{'", "'}'", "'type'", "'$'", + "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", "'gt'", "'ge'", "'!='", + "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", "'div'", "'idiv'", + "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", "'$$'", "'#'", "'{|'", + "'|}'", "'for'", "'let'", "'where'", "'group'", "'by'", "'order'", "'return'", + "'if'", "'in'", "'as'", "'at'", "'allowing'", "'empty'", "'count'", "'stable'", + "'ascending'", "'descending'", "'some'", "'every'", "'satisfies'", "'collation'", + "'greatest'", "'least'", "'switch'", "'case'", "'try'", "'catch'", "'default'", + "'then'", "'else'", "'typeswitch'", "'or'", "'and'", "'not'", "'to'", + "'instance'", "'of'", "'statically'", "'is'", "'treat'", "'cast'", "'castable'", + "'version'", "'jsoniq'", "'unordered'", null, "'?'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -92,15 +89,15 @@ public class JsoniqLexer extends Lexer { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", - "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", - "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", - "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", - "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", - "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", - "Kjsoniq", "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", - "NumericLiteral", "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", - "DoubleLiteral", "WS", "NCName", "XQComment", "ContentChar" + "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", "Kif", + "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", "Kascending", + "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", + "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", + "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", + "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", "Kjsoniq", "Kunordered", + "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", + "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", + "WS", "NCName", "XQComment", "ContentChar" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -176,41 +173,41 @@ public JsoniqLexer(CharStream input) { "w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+ "\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3"+ "\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b"+ - "\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3"+ - "\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3"+ - "\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r"+ - "\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16"+ - "\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ - "\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ - "\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23"+ - "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24"+ - "\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25"+ - "\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\32\3\32\3\32"+ - "\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ - "\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3 \3 \3 \3 \3 \3!\3!\3\""+ - "\3\"\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3"+ - "*\3*\3*\3+\3+\3,\3,\3,\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\62"+ - "\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65"+ - "\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\67\3\67\38\38\39\39\3"+ - ":\3:\3:\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3"+ - "@\3@\3A\3A\3A\3A\3A\3A\3B\3B\3B\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3"+ - "D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3I\3I\3J\3"+ - "J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3"+ - "M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3P\3P\3"+ - "P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3R\3"+ - "R\3S\3S\3S\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3U\3"+ - "V\3V\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3"+ - "Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+ - "\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3a\3a\3a\3a\3a\3a\3a\3a\3"+ - "a\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3d\3d\3d\3e\3e\3e\3e\3e\3"+ - "e\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3h\3"+ - "i\3i\3i\3i\3i\3i\3i\3j\3j\3j\7j\u034e\nj\fj\16j\u0351\13j\3j\3j\3k\3k"+ - "\3k\5k\u0358\nk\3l\3l\3l\3l\3l\3l\3m\3m\3n\3n\3o\3o\3o\3o\3o\3p\3p\5p"+ - "\u036b\np\3q\3q\3q\5q\u0370\nq\3r\3r\3r\3r\3r\3r\3r\3r\3r\5r\u037b\nr"+ - "\3s\3s\3t\3t\3t\3t\3t\7t\u0384\nt\ft\16t\u0387\13t\5t\u0389\nt\3u\3u\3"+ - "u\3u\3u\7u\u0390\nu\fu\16u\u0393\13u\5u\u0395\nu\5u\u0397\nu\3u\3u\5u"+ - "\u039b\nu\3u\3u\3v\6v\u03a0\nv\rv\16v\u03a1\3w\3w\3w\3w\3x\3x\7x\u03aa"+ + "\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+ + "\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+ + "\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+ + "\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+ + "\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3"+ + "\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3"+ + "\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3"+ + "\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3"+ + "\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3"+ + "\25\3\25\3\25\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3"+ + "\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3"+ + "\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3"+ + "\35\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\3#\3#\3"+ + "$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3+\3+\3"+ + "+\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3\62"+ + "\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\64"+ + "\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\38\38\39\39\39\3:\3:\3;\3;\3"+ + ";\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3"+ + "@\3A\3A\3A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3E\3E\3E\3"+ + "F\3F\3F\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3J\3J\3"+ + "J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3M\3M\3"+ + "M\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3P\3"+ + "P\3P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3"+ + "R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3"+ + "V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3"+ + "Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3]\3]\3]\3]\3^\3"+ + "^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3`\3`\3`\3`\3`\3a\3a\3a\3b\3b\3b\3b\3b\3"+ + "b\3b\3b\3b\3b\3b\3c\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3f\3f\3f\3"+ + "f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3i\3i\3"+ + "i\3i\3i\3i\3i\3i\3i\3i\3j\3j\3j\7j\u034e\nj\fj\16j\u0351\13j\3j\3j\3k"+ + "\3k\3k\5k\u0358\nk\3l\3l\3l\3l\3l\3l\3m\3m\3n\3n\3o\3o\3o\3o\3o\3p\3p"+ + "\5p\u036b\np\3q\3q\3q\5q\u0370\nq\3r\3r\3r\3r\3r\3r\3r\3r\3r\5r\u037b"+ + "\nr\3s\3s\3t\3t\3t\3t\3t\7t\u0384\nt\ft\16t\u0387\13t\5t\u0389\nt\3u\3"+ + "u\3u\3u\3u\7u\u0390\nu\fu\16u\u0393\13u\5u\u0395\nu\5u\u0397\nu\3u\3u"+ + "\5u\u039b\nu\3u\3u\3v\6v\u03a0\nv\rv\16v\u03a1\3w\3w\3w\3w\3x\3x\7x\u03aa"+ "\nx\fx\16x\u03ad\13x\3y\5y\u03b0\ny\3z\3z\5z\u03b4\nz\3{\3{\3{\3{\3{\3"+ "{\3{\3{\7{\u03be\n{\f{\16{\u03c1\13{\3{\6{\u03c4\n{\r{\16{\u03c5\3{\3"+ "{\3{\3{\3|\3|\2\2}\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r"+ @@ -251,31 +248,31 @@ public JsoniqLexer(CharStream input) { "\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00ed"+ "\3\2\2\2\2\u00ef\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\3\u00f9\3\2\2"+ "\2\5\u00fb\3\2\2\2\7\u0102\3\2\2\2\t\u010c\3\2\2\2\13\u010e\3\2\2\2\r"+ - "\u0116\3\2\2\2\17\u011f\3\2\2\2\21\u0127\3\2\2\2\23\u0131\3\2\2\2\25\u0140"+ - "\3\2\2\2\27\u0142\3\2\2\2\31\u0154\3\2\2\2\33\u0167\3\2\2\2\35\u0170\3"+ - "\2\2\2\37\u017b\3\2\2\2!\u017f\3\2\2\2#\u0187\3\2\2\2%\u0191\3\2\2\2\'"+ - "\u019c\3\2\2\2)\u01a2\3\2\2\2+\u01b4\3\2\2\2-\u01bb\3\2\2\2/\u01bd\3\2"+ - "\2\2\61\u01c6\3\2\2\2\63\u01c9\3\2\2\2\65\u01d2\3\2\2\2\67\u01db\3\2\2"+ - "\29\u01dd\3\2\2\2;\u01df\3\2\2\2=\u01e1\3\2\2\2?\u01e3\3\2\2\2A\u01e8"+ - "\3\2\2\2C\u01ea\3\2\2\2E\u01ec\3\2\2\2G\u01ee\3\2\2\2I\u01f1\3\2\2\2K"+ - "\u01f4\3\2\2\2M\u01f7\3\2\2\2O\u01fa\3\2\2\2Q\u01fd\3\2\2\2S\u0200\3\2"+ - "\2\2U\u0203\3\2\2\2W\u0205\3\2\2\2Y\u0208\3\2\2\2[\u020a\3\2\2\2]\u020d"+ - "\3\2\2\2_\u0210\3\2\2\2a\u0212\3\2\2\2c\u0214\3\2\2\2e\u0218\3\2\2\2g"+ - "\u021d\3\2\2\2i\u0221\3\2\2\2k\u022a\3\2\2\2m\u022c\3\2\2\2o\u022e\3\2"+ - "\2\2q\u0230\3\2\2\2s\u0232\3\2\2\2u\u0235\3\2\2\2w\u0237\3\2\2\2y\u023a"+ - "\3\2\2\2{\u023d\3\2\2\2}\u0241\3\2\2\2\177\u0245\3\2\2\2\u0081\u024b\3"+ - "\2\2\2\u0083\u0251\3\2\2\2\u0085\u0254\3\2\2\2\u0087\u025a\3\2\2\2\u0089"+ - "\u0261\3\2\2\2\u008b\u0264\3\2\2\2\u008d\u0267\3\2\2\2\u008f\u026a\3\2"+ - "\2\2\u0091\u026d\3\2\2\2\u0093\u0276\3\2\2\2\u0095\u027c\3\2\2\2\u0097"+ - "\u0282\3\2\2\2\u0099\u0289\3\2\2\2\u009b\u0293\3\2\2\2\u009d\u029e\3\2"+ - "\2\2\u009f\u02a3\3\2\2\2\u00a1\u02a9\3\2\2\2\u00a3\u02b3\3\2\2\2\u00a5"+ - "\u02bd\3\2\2\2\u00a7\u02c6\3\2\2\2\u00a9\u02cc\3\2\2\2\u00ab\u02d3\3\2"+ - "\2\2\u00ad\u02d8\3\2\2\2\u00af\u02dc\3\2\2\2\u00b1\u02e2\3\2\2\2\u00b3"+ - "\u02ea\3\2\2\2\u00b5\u02ef\3\2\2\2\u00b7\u02f4\3\2\2\2\u00b9\u02ff\3\2"+ - "\2\2\u00bb\u0302\3\2\2\2\u00bd\u0306\3\2\2\2\u00bf\u030a\3\2\2\2\u00c1"+ - "\u030d\3\2\2\2\u00c3\u0316\3\2\2\2\u00c5\u0319\3\2\2\2\u00c7\u0324\3\2"+ - "\2\2\u00c9\u0327\3\2\2\2\u00cb\u032d\3\2\2\2\u00cd\u0332\3\2\2\2\u00cf"+ - "\u033b\3\2\2\2\u00d1\u0343\3\2\2\2\u00d3\u034a\3\2\2\2\u00d5\u0354\3\2"+ + "\u0116\3\2\2\2\17\u011f\3\2\2\2\21\u0127\3\2\2\2\23\u0136\3\2\2\2\25\u0138"+ + "\3\2\2\2\27\u014a\3\2\2\2\31\u015d\3\2\2\2\33\u0166\3\2\2\2\35\u0171\3"+ + "\2\2\2\37\u0175\3\2\2\2!\u017d\3\2\2\2#\u0187\3\2\2\2%\u0192\3\2\2\2\'"+ + "\u0198\3\2\2\2)\u01aa\3\2\2\2+\u01b1\3\2\2\2-\u01b3\3\2\2\2/\u01bc\3\2"+ + "\2\2\61\u01bf\3\2\2\2\63\u01c8\3\2\2\2\65\u01d1\3\2\2\2\67\u01d3\3\2\2"+ + "\29\u01d5\3\2\2\2;\u01d7\3\2\2\2=\u01d9\3\2\2\2?\u01de\3\2\2\2A\u01e0"+ + "\3\2\2\2C\u01e2\3\2\2\2E\u01e4\3\2\2\2G\u01e7\3\2\2\2I\u01ea\3\2\2\2K"+ + "\u01ed\3\2\2\2M\u01f0\3\2\2\2O\u01f3\3\2\2\2Q\u01f6\3\2\2\2S\u01f9\3\2"+ + "\2\2U\u01fb\3\2\2\2W\u01fe\3\2\2\2Y\u0200\3\2\2\2[\u0203\3\2\2\2]\u0206"+ + "\3\2\2\2_\u0208\3\2\2\2a\u020a\3\2\2\2c\u020e\3\2\2\2e\u0213\3\2\2\2g"+ + "\u0217\3\2\2\2i\u0220\3\2\2\2k\u0222\3\2\2\2m\u0224\3\2\2\2o\u0226\3\2"+ + "\2\2q\u0228\3\2\2\2s\u022b\3\2\2\2u\u022d\3\2\2\2w\u0230\3\2\2\2y\u0233"+ + "\3\2\2\2{\u0237\3\2\2\2}\u023b\3\2\2\2\177\u0241\3\2\2\2\u0081\u0247\3"+ + "\2\2\2\u0083\u024a\3\2\2\2\u0085\u0250\3\2\2\2\u0087\u0257\3\2\2\2\u0089"+ + "\u025a\3\2\2\2\u008b\u025d\3\2\2\2\u008d\u0260\3\2\2\2\u008f\u0263\3\2"+ + "\2\2\u0091\u026c\3\2\2\2\u0093\u0272\3\2\2\2\u0095\u0278\3\2\2\2\u0097"+ + "\u027f\3\2\2\2\u0099\u0289\3\2\2\2\u009b\u0294\3\2\2\2\u009d\u0299\3\2"+ + "\2\2\u009f\u029f\3\2\2\2\u00a1\u02a9\3\2\2\2\u00a3\u02b3\3\2\2\2\u00a5"+ + "\u02bc\3\2\2\2\u00a7\u02c2\3\2\2\2\u00a9\u02c9\3\2\2\2\u00ab\u02ce\3\2"+ + "\2\2\u00ad\u02d2\3\2\2\2\u00af\u02d8\3\2\2\2\u00b1\u02e0\3\2\2\2\u00b3"+ + "\u02e5\3\2\2\2\u00b5\u02ea\3\2\2\2\u00b7\u02f5\3\2\2\2\u00b9\u02f8\3\2"+ + "\2\2\u00bb\u02fc\3\2\2\2\u00bd\u0300\3\2\2\2\u00bf\u0303\3\2\2\2\u00c1"+ + "\u030c\3\2\2\2\u00c3\u030f\3\2\2\2\u00c5\u031a\3\2\2\2\u00c7\u031d\3\2"+ + "\2\2\u00c9\u0323\3\2\2\2\u00cb\u0328\3\2\2\2\u00cd\u0331\3\2\2\2\u00cf"+ + "\u0339\3\2\2\2\u00d1\u0340\3\2\2\2\u00d3\u034a\3\2\2\2\u00d5\u0354\3\2"+ "\2\2\u00d7\u0359\3\2\2\2\u00d9\u035f\3\2\2\2\u00db\u0361\3\2\2\2\u00dd"+ "\u0363\3\2\2\2\u00df\u036a\3\2\2\2\u00e1\u036f\3\2\2\2\u00e3\u037a\3\2"+ "\2\2\u00e5\u037c\3\2\2\2\u00e7\u0388\3\2\2\2\u00e9\u0396\3\2\2\2\u00eb"+ @@ -293,197 +290,197 @@ public JsoniqLexer(CharStream input) { "\u011c\u011d\7p\2\2\u011d\u011e\7i\2\2\u011e\16\3\2\2\2\u011f\u0120\7"+ "q\2\2\u0120\u0121\7t\2\2\u0121\u0122\7f\2\2\u0122\u0123\7g\2\2\u0123\u0124"+ "\7t\2\2\u0124\u0125\7g\2\2\u0125\u0126\7f\2\2\u0126\20\3\2\2\2\u0127\u0128"+ - "\7w\2\2\u0128\u0129\7p\2\2\u0129\u012a\7q\2\2\u012a\u012b\7t\2\2\u012b"+ - "\u012c\7f\2\2\u012c\u012d\7g\2\2\u012d\u012e\7t\2\2\u012e\u012f\7g\2\2"+ - "\u012f\u0130\7f\2\2\u0130\22\3\2\2\2\u0131\u0132\7f\2\2\u0132\u0133\7"+ - "g\2\2\u0133\u0134\7e\2\2\u0134\u0135\7k\2\2\u0135\u0136\7o\2\2\u0136\u0137"+ - "\7c\2\2\u0137\u0138\7n\2\2\u0138\u0139\7/\2\2\u0139\u013a\7h\2\2\u013a"+ - "\u013b\7q\2\2\u013b\u013c\7t\2\2\u013c\u013d\7o\2\2\u013d\u013e\7c\2\2"+ - "\u013e\u013f\7v\2\2\u013f\24\3\2\2\2\u0140\u0141\7<\2\2\u0141\26\3\2\2"+ - "\2\u0142\u0143\7f\2\2\u0143\u0144\7g\2\2\u0144\u0145\7e\2\2\u0145\u0146"+ - "\7k\2\2\u0146\u0147\7o\2\2\u0147\u0148\7c\2\2\u0148\u0149\7n\2\2\u0149"+ - "\u014a\7/\2\2\u014a\u014b\7u\2\2\u014b\u014c\7g\2\2\u014c\u014d\7r\2\2"+ - "\u014d\u014e\7c\2\2\u014e\u014f\7t\2\2\u014f\u0150\7c\2\2\u0150\u0151"+ - "\7v\2\2\u0151\u0152\7q\2\2\u0152\u0153\7t\2\2\u0153\30\3\2\2\2\u0154\u0155"+ - "\7i\2\2\u0155\u0156\7t\2\2\u0156\u0157\7q\2\2\u0157\u0158\7w\2\2\u0158"+ - "\u0159\7r\2\2\u0159\u015a\7k\2\2\u015a\u015b\7p\2\2\u015b\u015c\7i\2\2"+ - "\u015c\u015d\7/\2\2\u015d\u015e\7u\2\2\u015e\u015f\7g\2\2\u015f\u0160"+ - "\7r\2\2\u0160\u0161\7c\2\2\u0161\u0162\7t\2\2\u0162\u0163\7c\2\2\u0163"+ - "\u0164\7v\2\2\u0164\u0165\7q\2\2\u0165\u0166\7t\2\2\u0166\32\3\2\2\2\u0167"+ - "\u0168\7k\2\2\u0168\u0169\7p\2\2\u0169\u016a\7h\2\2\u016a\u016b\7k\2\2"+ - "\u016b\u016c\7p\2\2\u016c\u016d\7k\2\2\u016d\u016e\7v\2\2\u016e\u016f"+ - "\7{\2\2\u016f\34\3\2\2\2\u0170\u0171\7o\2\2\u0171\u0172\7k\2\2\u0172\u0173"+ - "\7p\2\2\u0173\u0174\7w\2\2\u0174\u0175\7u\2\2\u0175\u0176\7/\2\2\u0176"+ - "\u0177\7u\2\2\u0177\u0178\7k\2\2\u0178\u0179\7i\2\2\u0179\u017a\7p\2\2"+ - "\u017a\36\3\2\2\2\u017b\u017c\7P\2\2\u017c\u017d\7c\2\2\u017d\u017e\7"+ - "P\2\2\u017e \3\2\2\2\u017f\u0180\7r\2\2\u0180\u0181\7g\2\2\u0181\u0182"+ - "\7t\2\2\u0182\u0183\7e\2\2\u0183\u0184\7g\2\2\u0184\u0185\7p\2\2\u0185"+ - "\u0186\7v\2\2\u0186\"\3\2\2\2\u0187\u0188\7r\2\2\u0188\u0189\7g\2\2\u0189"+ - "\u018a\7t\2\2\u018a\u018b\7/\2\2\u018b\u018c\7o\2\2\u018c\u018d\7k\2\2"+ - "\u018d\u018e\7n\2\2\u018e\u018f\7n\2\2\u018f\u0190\7g\2\2\u0190$\3\2\2"+ - "\2\u0191\u0192\7|\2\2\u0192\u0193\7g\2\2\u0193\u0194\7t\2\2\u0194\u0195"+ - "\7q\2\2\u0195\u0196\7/\2\2\u0196\u0197\7f\2\2\u0197\u0198\7k\2\2\u0198"+ - "\u0199\7i\2\2\u0199\u019a\7k\2\2\u019a\u019b\7v\2\2\u019b&\3\2\2\2\u019c"+ - "\u019d\7f\2\2\u019d\u019e\7k\2\2\u019e\u019f\7i\2\2\u019f\u01a0\7k\2\2"+ - "\u01a0\u01a1\7v\2\2\u01a1(\3\2\2\2\u01a2\u01a3\7r\2\2\u01a3\u01a4\7c\2"+ - "\2\u01a4\u01a5\7v\2\2\u01a5\u01a6\7v\2\2\u01a6\u01a7\7g\2\2\u01a7\u01a8"+ - "\7t\2\2\u01a8\u01a9\7p\2\2\u01a9\u01aa\7/\2\2\u01aa\u01ab\7u\2\2\u01ab"+ - "\u01ac\7g\2\2\u01ac\u01ad\7r\2\2\u01ad\u01ae\7c\2\2\u01ae\u01af\7t\2\2"+ - "\u01af\u01b0\7c\2\2\u01b0\u01b1\7v\2\2\u01b1\u01b2\7q\2\2\u01b2\u01b3"+ - "\7t\2\2\u01b3*\3\2\2\2\u01b4\u01b5\7k\2\2\u01b5\u01b6\7o\2\2\u01b6\u01b7"+ - "\7r\2\2\u01b7\u01b8\7q\2\2\u01b8\u01b9\7t\2\2\u01b9\u01ba\7v\2\2\u01ba"+ - ",\3\2\2\2\u01bb\u01bc\7.\2\2\u01bc.\3\2\2\2\u01bd\u01be\7x\2\2\u01be\u01bf"+ - "\7c\2\2\u01bf\u01c0\7t\2\2\u01c0\u01c1\7k\2\2\u01c1\u01c2\7c\2\2\u01c2"+ - "\u01c3\7d\2\2\u01c3\u01c4\7n\2\2\u01c4\u01c5\7g\2\2\u01c5\60\3\2\2\2\u01c6"+ - "\u01c7\7<\2\2\u01c7\u01c8\7?\2\2\u01c8\62\3\2\2\2\u01c9\u01ca\7g\2\2\u01ca"+ - "\u01cb\7z\2\2\u01cb\u01cc\7v\2\2\u01cc\u01cd\7g\2\2\u01cd\u01ce\7t\2\2"+ - "\u01ce\u01cf\7p\2\2\u01cf\u01d0\7c\2\2\u01d0\u01d1\7n\2\2\u01d1\64\3\2"+ - "\2\2\u01d2\u01d3\7h\2\2\u01d3\u01d4\7w\2\2\u01d4\u01d5\7p\2\2\u01d5\u01d6"+ - "\7e\2\2\u01d6\u01d7\7v\2\2\u01d7\u01d8\7k\2\2\u01d8\u01d9\7q\2\2\u01d9"+ - "\u01da\7p\2\2\u01da\66\3\2\2\2\u01db\u01dc\7*\2\2\u01dc8\3\2\2\2\u01dd"+ - "\u01de\7+\2\2\u01de:\3\2\2\2\u01df\u01e0\7}\2\2\u01e0<\3\2\2\2\u01e1\u01e2"+ - "\7\177\2\2\u01e2>\3\2\2\2\u01e3\u01e4\7v\2\2\u01e4\u01e5\7{\2\2\u01e5"+ - "\u01e6\7r\2\2\u01e6\u01e7\7g\2\2\u01e7@\3\2\2\2\u01e8\u01e9\7&\2\2\u01e9"+ - "B\3\2\2\2\u01ea\u01eb\7~\2\2\u01ebD\3\2\2\2\u01ec\u01ed\7,\2\2\u01edF"+ - "\3\2\2\2\u01ee\u01ef\7g\2\2\u01ef\u01f0\7s\2\2\u01f0H\3\2\2\2\u01f1\u01f2"+ - "\7p\2\2\u01f2\u01f3\7g\2\2\u01f3J\3\2\2\2\u01f4\u01f5\7n\2\2\u01f5\u01f6"+ - "\7v\2\2\u01f6L\3\2\2\2\u01f7\u01f8\7n\2\2\u01f8\u01f9\7g\2\2\u01f9N\3"+ - "\2\2\2\u01fa\u01fb\7i\2\2\u01fb\u01fc\7v\2\2\u01fcP\3\2\2\2\u01fd\u01fe"+ - "\7i\2\2\u01fe\u01ff\7g\2\2\u01ffR\3\2\2\2\u0200\u0201\7#\2\2\u0201\u0202"+ - "\7?\2\2\u0202T\3\2\2\2\u0203\u0204\7>\2\2\u0204V\3\2\2\2\u0205\u0206\7"+ - ">\2\2\u0206\u0207\7?\2\2\u0207X\3\2\2\2\u0208\u0209\7@\2\2\u0209Z\3\2"+ - "\2\2\u020a\u020b\7@\2\2\u020b\u020c\7?\2\2\u020c\\\3\2\2\2\u020d\u020e"+ - "\7~\2\2\u020e\u020f\7~\2\2\u020f^\3\2\2\2\u0210\u0211\7-\2\2\u0211`\3"+ - "\2\2\2\u0212\u0213\7/\2\2\u0213b\3\2\2\2\u0214\u0215\7f\2\2\u0215\u0216"+ - "\7k\2\2\u0216\u0217\7x\2\2\u0217d\3\2\2\2\u0218\u0219\7k\2\2\u0219\u021a"+ - "\7f\2\2\u021a\u021b\7k\2\2\u021b\u021c\7x\2\2\u021cf\3\2\2\2\u021d\u021e"+ - "\7o\2\2\u021e\u021f\7q\2\2\u021f\u0220\7f\2\2\u0220h\3\2\2\2\u0221\u0222"+ - "\7x\2\2\u0222\u0223\7c\2\2\u0223\u0224\7n\2\2\u0224\u0225\7k\2\2\u0225"+ - "\u0226\7f\2\2\u0226\u0227\7c\2\2\u0227\u0228\7v\2\2\u0228\u0229\7g\2\2"+ - "\u0229j\3\2\2\2\u022a\u022b\7#\2\2\u022bl\3\2\2\2\u022c\u022d\7]\2\2\u022d"+ - "n\3\2\2\2\u022e\u022f\7_\2\2\u022fp\3\2\2\2\u0230\u0231\7\60\2\2\u0231"+ - "r\3\2\2\2\u0232\u0233\7&\2\2\u0233\u0234\7&\2\2\u0234t\3\2\2\2\u0235\u0236"+ - "\7%\2\2\u0236v\3\2\2\2\u0237\u0238\7}\2\2\u0238\u0239\7~\2\2\u0239x\3"+ - "\2\2\2\u023a\u023b\7~\2\2\u023b\u023c\7\177\2\2\u023cz\3\2\2\2\u023d\u023e"+ - "\7h\2\2\u023e\u023f\7q\2\2\u023f\u0240\7t\2\2\u0240|\3\2\2\2\u0241\u0242"+ - "\7n\2\2\u0242\u0243\7g\2\2\u0243\u0244\7v\2\2\u0244~\3\2\2\2\u0245\u0246"+ - "\7y\2\2\u0246\u0247\7j\2\2\u0247\u0248\7g\2\2\u0248\u0249\7t\2\2\u0249"+ - "\u024a\7g\2\2\u024a\u0080\3\2\2\2\u024b\u024c\7i\2\2\u024c\u024d\7t\2"+ - "\2\u024d\u024e\7q\2\2\u024e\u024f\7w\2\2\u024f\u0250\7r\2\2\u0250\u0082"+ - "\3\2\2\2\u0251\u0252\7d\2\2\u0252\u0253\7{\2\2\u0253\u0084\3\2\2\2\u0254"+ - "\u0255\7q\2\2\u0255\u0256\7t\2\2\u0256\u0257\7f\2\2\u0257\u0258\7g\2\2"+ - "\u0258\u0259\7t\2\2\u0259\u0086\3\2\2\2\u025a\u025b\7t\2\2\u025b\u025c"+ - "\7g\2\2\u025c\u025d\7v\2\2\u025d\u025e\7w\2\2\u025e\u025f\7t\2\2\u025f"+ - "\u0260\7p\2\2\u0260\u0088\3\2\2\2\u0261\u0262\7k\2\2\u0262\u0263\7h\2"+ - "\2\u0263\u008a\3\2\2\2\u0264\u0265\7k\2\2\u0265\u0266\7p\2\2\u0266\u008c"+ - "\3\2\2\2\u0267\u0268\7c\2\2\u0268\u0269\7u\2\2\u0269\u008e\3\2\2\2\u026a"+ - "\u026b\7c\2\2\u026b\u026c\7v\2\2\u026c\u0090\3\2\2\2\u026d\u026e\7c\2"+ - "\2\u026e\u026f\7n\2\2\u026f\u0270\7n\2\2\u0270\u0271\7q\2\2\u0271\u0272"+ - "\7y\2\2\u0272\u0273\7k\2\2\u0273\u0274\7p\2\2\u0274\u0275\7i\2\2\u0275"+ - "\u0092\3\2\2\2\u0276\u0277\7g\2\2\u0277\u0278\7o\2\2\u0278\u0279\7r\2"+ - "\2\u0279\u027a\7v\2\2\u027a\u027b\7{\2\2\u027b\u0094\3\2\2\2\u027c\u027d"+ - "\7e\2\2\u027d\u027e\7q\2\2\u027e\u027f\7w\2\2\u027f\u0280\7p\2\2\u0280"+ - "\u0281\7v\2\2\u0281\u0096\3\2\2\2\u0282\u0283\7u\2\2\u0283\u0284\7v\2"+ - "\2\u0284\u0285\7c\2\2\u0285\u0286\7d\2\2\u0286\u0287\7n\2\2\u0287\u0288"+ - "\7g\2\2\u0288\u0098\3\2\2\2\u0289\u028a\7c\2\2\u028a\u028b\7u\2\2\u028b"+ - "\u028c\7e\2\2\u028c\u028d\7g\2\2\u028d\u028e\7p\2\2\u028e\u028f\7f\2\2"+ - "\u028f\u0290\7k\2\2\u0290\u0291\7p\2\2\u0291\u0292\7i\2\2\u0292\u009a"+ - "\3\2\2\2\u0293\u0294\7f\2\2\u0294\u0295\7g\2\2\u0295\u0296\7u\2\2\u0296"+ - "\u0297\7e\2\2\u0297\u0298\7g\2\2\u0298\u0299\7p\2\2\u0299\u029a\7f\2\2"+ - "\u029a\u029b\7k\2\2\u029b\u029c\7p\2\2\u029c\u029d\7i\2\2\u029d\u009c"+ - "\3\2\2\2\u029e\u029f\7u\2\2\u029f\u02a0\7q\2\2\u02a0\u02a1\7o\2\2\u02a1"+ - "\u02a2\7g\2\2\u02a2\u009e\3\2\2\2\u02a3\u02a4\7g\2\2\u02a4\u02a5\7x\2"+ - "\2\u02a5\u02a6\7g\2\2\u02a6\u02a7\7t\2\2\u02a7\u02a8\7{\2\2\u02a8\u00a0"+ - "\3\2\2\2\u02a9\u02aa\7u\2\2\u02aa\u02ab\7c\2\2\u02ab\u02ac\7v\2\2\u02ac"+ - "\u02ad\7k\2\2\u02ad\u02ae\7u\2\2\u02ae\u02af\7h\2\2\u02af\u02b0\7k\2\2"+ - "\u02b0\u02b1\7g\2\2\u02b1\u02b2\7u\2\2\u02b2\u00a2\3\2\2\2\u02b3\u02b4"+ - "\7e\2\2\u02b4\u02b5\7q\2\2\u02b5\u02b6\7n\2\2\u02b6\u02b7\7n\2\2\u02b7"+ - "\u02b8\7c\2\2\u02b8\u02b9\7v\2\2\u02b9\u02ba\7k\2\2\u02ba\u02bb\7q\2\2"+ - "\u02bb\u02bc\7p\2\2\u02bc\u00a4\3\2\2\2\u02bd\u02be\7i\2\2\u02be\u02bf"+ - "\7t\2\2\u02bf\u02c0\7g\2\2\u02c0\u02c1\7c\2\2\u02c1\u02c2\7v\2\2\u02c2"+ - "\u02c3\7g\2\2\u02c3\u02c4\7u\2\2\u02c4\u02c5\7v\2\2\u02c5\u00a6\3\2\2"+ - "\2\u02c6\u02c7\7n\2\2\u02c7\u02c8\7g\2\2\u02c8\u02c9\7c\2\2\u02c9\u02ca"+ - "\7u\2\2\u02ca\u02cb\7v\2\2\u02cb\u00a8\3\2\2\2\u02cc\u02cd\7u\2\2\u02cd"+ - "\u02ce\7y\2\2\u02ce\u02cf\7k\2\2\u02cf\u02d0\7v\2\2\u02d0\u02d1\7e\2\2"+ - "\u02d1\u02d2\7j\2\2\u02d2\u00aa\3\2\2\2\u02d3\u02d4\7e\2\2\u02d4\u02d5"+ - "\7c\2\2\u02d5\u02d6\7u\2\2\u02d6\u02d7\7g\2\2\u02d7\u00ac\3\2\2\2\u02d8"+ - "\u02d9\7v\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7{\2\2\u02db\u00ae\3\2\2"+ - "\2\u02dc\u02dd\7e\2\2\u02dd\u02de\7c\2\2\u02de\u02df\7v\2\2\u02df\u02e0"+ - "\7e\2\2\u02e0\u02e1\7j\2\2\u02e1\u00b0\3\2\2\2\u02e2\u02e3\7f\2\2\u02e3"+ - "\u02e4\7g\2\2\u02e4\u02e5\7h\2\2\u02e5\u02e6\7c\2\2\u02e6\u02e7\7w\2\2"+ - "\u02e7\u02e8\7n\2\2\u02e8\u02e9\7v\2\2\u02e9\u00b2\3\2\2\2\u02ea\u02eb"+ - "\7v\2\2\u02eb\u02ec\7j\2\2\u02ec\u02ed\7g\2\2\u02ed\u02ee\7p\2\2\u02ee"+ - "\u00b4\3\2\2\2\u02ef\u02f0\7g\2\2\u02f0\u02f1\7n\2\2\u02f1\u02f2\7u\2"+ - "\2\u02f2\u02f3\7g\2\2\u02f3\u00b6\3\2\2\2\u02f4\u02f5\7v\2\2\u02f5\u02f6"+ - "\7{\2\2\u02f6\u02f7\7r\2\2\u02f7\u02f8\7g\2\2\u02f8\u02f9\7u\2\2\u02f9"+ - "\u02fa\7y\2\2\u02fa\u02fb\7k\2\2\u02fb\u02fc\7v\2\2\u02fc\u02fd\7e\2\2"+ - "\u02fd\u02fe\7j\2\2\u02fe\u00b8\3\2\2\2\u02ff\u0300\7q\2\2\u0300\u0301"+ - "\7t\2\2\u0301\u00ba\3\2\2\2\u0302\u0303\7c\2\2\u0303\u0304\7p\2\2\u0304"+ - "\u0305\7f\2\2\u0305\u00bc\3\2\2\2\u0306\u0307\7p\2\2\u0307\u0308\7q\2"+ - "\2\u0308\u0309\7v\2\2\u0309\u00be\3\2\2\2\u030a\u030b\7v\2\2\u030b\u030c"+ - "\7q\2\2\u030c\u00c0\3\2\2\2\u030d\u030e\7k\2\2\u030e\u030f\7p\2\2\u030f"+ - "\u0310\7u\2\2\u0310\u0311\7v\2\2\u0311\u0312\7c\2\2\u0312\u0313\7p\2\2"+ - "\u0313\u0314\7e\2\2\u0314\u0315\7g\2\2\u0315\u00c2\3\2\2\2\u0316\u0317"+ - "\7q\2\2\u0317\u0318\7h\2\2\u0318\u00c4\3\2\2\2\u0319\u031a\7u\2\2\u031a"+ - "\u031b\7v\2\2\u031b\u031c\7c\2\2\u031c\u031d\7v\2\2\u031d\u031e\7k\2\2"+ - "\u031e\u031f\7e\2\2\u031f\u0320\7c\2\2\u0320\u0321\7n\2\2\u0321\u0322"+ - "\7n\2\2\u0322\u0323\7{\2\2\u0323\u00c6\3\2\2\2\u0324\u0325\7k\2\2\u0325"+ - "\u0326\7u\2\2\u0326\u00c8\3\2\2\2\u0327\u0328\7v\2\2\u0328\u0329\7t\2"+ - "\2\u0329\u032a\7g\2\2\u032a\u032b\7c\2\2\u032b\u032c\7v\2\2\u032c\u00ca"+ - "\3\2\2\2\u032d\u032e\7e\2\2\u032e\u032f\7c\2\2\u032f\u0330\7u\2\2\u0330"+ - "\u0331\7v\2\2\u0331\u00cc\3\2\2\2\u0332\u0333\7e\2\2\u0333\u0334\7c\2"+ - "\2\u0334\u0335\7u\2\2\u0335\u0336\7v\2\2\u0336\u0337\7c\2\2\u0337\u0338"+ - "\7d\2\2\u0338\u0339\7n\2\2\u0339\u033a\7g\2\2\u033a\u00ce\3\2\2\2\u033b"+ - "\u033c\7x\2\2\u033c\u033d\7g\2\2\u033d\u033e\7t\2\2\u033e\u033f\7u\2\2"+ - "\u033f\u0340\7k\2\2\u0340\u0341\7q\2\2\u0341\u0342\7p\2\2\u0342\u00d0"+ - "\3\2\2\2\u0343\u0344\7l\2\2\u0344\u0345\7u\2\2\u0345\u0346\7q\2\2\u0346"+ - "\u0347\7p\2\2\u0347\u0348\7k\2\2\u0348\u0349\7s\2\2\u0349\u00d2\3\2\2"+ - "\2\u034a\u034f\7$\2\2\u034b\u034e\5\u00d5k\2\u034c\u034e\n\2\2\2\u034d"+ - "\u034b\3\2\2\2\u034d\u034c\3\2\2\2\u034e\u0351\3\2\2\2\u034f\u034d\3\2"+ - "\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351\u034f\3\2\2\2\u0352"+ - "\u0353\7$\2\2\u0353\u00d4\3\2\2\2\u0354\u0357\7^\2\2\u0355\u0358\t\3\2"+ - "\2\u0356\u0358\5\u00d7l\2\u0357\u0355\3\2\2\2\u0357\u0356\3\2\2\2\u0358"+ - "\u00d6\3\2\2\2\u0359\u035a\7w\2\2\u035a\u035b\5\u00d9m\2\u035b\u035c\5"+ - "\u00d9m\2\u035c\u035d\5\u00d9m\2\u035d\u035e\5\u00d9m\2\u035e\u00d8\3"+ - "\2\2\2\u035f\u0360\t\4\2\2\u0360\u00da\3\2\2\2\u0361\u0362\7A\2\2\u0362"+ - "\u00dc\3\2\2\2\u0363\u0364\7p\2\2\u0364\u0365\7w\2\2\u0365\u0366\7n\2"+ - "\2\u0366\u0367\7n\2\2\u0367\u00de\3\2\2\2\u0368\u036b\5\u00e1q\2\u0369"+ - "\u036b\5\u00e3r\2\u036a\u0368\3\2\2\2\u036a\u0369\3\2\2\2\u036b\u00e0"+ - "\3\2\2\2\u036c\u0370\5\u00e5s\2\u036d\u0370\5\u00e7t\2\u036e\u0370\5\u00e9"+ - "u\2\u036f\u036c\3\2\2\2\u036f\u036d\3\2\2\2\u036f\u036e\3\2\2\2\u0370"+ - "\u00e2\3\2\2\2\u0371\u0372\7v\2\2\u0372\u0373\7t\2\2\u0373\u0374\7w\2"+ - "\2\u0374\u037b\7g\2\2\u0375\u0376\7h\2\2\u0376\u0377\7c\2\2\u0377\u0378"+ - "\7n\2\2\u0378\u0379\7u\2\2\u0379\u037b\7g\2\2\u037a\u0371\3\2\2\2\u037a"+ - "\u0375\3\2\2\2\u037b\u00e4\3\2\2\2\u037c\u037d\5\u00ebv\2\u037d\u00e6"+ - "\3\2\2\2\u037e\u037f\7\60\2\2\u037f\u0389\5\u00ebv\2\u0380\u0381\5\u00eb"+ - "v\2\u0381\u0385\7\60\2\2\u0382\u0384\t\5\2\2\u0383\u0382\3\2\2\2\u0384"+ - "\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386\u0389\3\2"+ - "\2\2\u0387\u0385\3\2\2\2\u0388\u037e\3\2\2\2\u0388\u0380\3\2\2\2\u0389"+ - "\u00e8\3\2\2\2\u038a\u038b\7\60\2\2\u038b\u0397\5\u00ebv\2\u038c\u0394"+ - "\5\u00ebv\2\u038d\u0391\7\60\2\2\u038e\u0390\t\5\2\2\u038f\u038e\3\2\2"+ - "\2\u0390\u0393\3\2\2\2\u0391\u038f\3\2\2\2\u0391\u0392\3\2\2\2\u0392\u0395"+ - "\3\2\2\2\u0393\u0391\3\2\2\2\u0394\u038d\3\2\2\2\u0394\u0395\3\2\2\2\u0395"+ - "\u0397\3\2\2\2\u0396\u038a\3\2\2\2\u0396\u038c\3\2\2\2\u0397\u0398\3\2"+ - "\2\2\u0398\u039a\t\6\2\2\u0399\u039b\t\7\2\2\u039a\u0399\3\2\2\2\u039a"+ - "\u039b\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039d\5\u00ebv\2\u039d\u00ea"+ - "\3\2\2\2\u039e\u03a0\t\5\2\2\u039f\u039e\3\2\2\2\u03a0\u03a1\3\2\2\2\u03a1"+ - "\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u00ec\3\2\2\2\u03a3\u03a4\t\b"+ - "\2\2\u03a4\u03a5\3\2\2\2\u03a5\u03a6\bw\2\2\u03a6\u00ee\3\2\2\2\u03a7"+ - "\u03ab\5\u00f1y\2\u03a8\u03aa\5\u00f3z\2\u03a9\u03a8\3\2\2\2\u03aa\u03ad"+ - "\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u00f0\3\2\2\2\u03ad"+ - "\u03ab\3\2\2\2\u03ae\u03b0\t\t\2\2\u03af\u03ae\3\2\2\2\u03b0\u00f2\3\2"+ - "\2\2\u03b1\u03b4\5\u00f1y\2\u03b2\u03b4\t\n\2\2\u03b3\u03b1\3\2\2\2\u03b3"+ - "\u03b2\3\2\2\2\u03b4\u00f4\3\2\2\2\u03b5\u03b6\7*\2\2\u03b6\u03bf\7<\2"+ - "\2\u03b7\u03be\5\u00f5{\2\u03b8\u03b9\7*\2\2\u03b9\u03be\n\13\2\2\u03ba"+ - "\u03bb\7<\2\2\u03bb\u03be\n\f\2\2\u03bc\u03be\n\r\2\2\u03bd\u03b7\3\2"+ - "\2\2\u03bd\u03b8\3\2\2\2\u03bd\u03ba\3\2\2\2\u03bd\u03bc\3\2\2\2\u03be"+ - "\u03c1\3\2\2\2\u03bf\u03bd\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0\u03c3\3\2"+ - "\2\2\u03c1\u03bf\3\2\2\2\u03c2\u03c4\7<\2\2\u03c3\u03c2\3\2\2\2\u03c4"+ - "\u03c5\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c5\u03c6\3\2\2\2\u03c6\u03c7\3\2"+ - "\2\2\u03c7\u03c8\7+\2\2\u03c8\u03c9\3\2\2\2\u03c9\u03ca\b{\2\2\u03ca\u00f6"+ - "\3\2\2\2\u03cb\u03cc\n\16\2\2\u03cc\u00f8\3\2\2\2\26\2\u034d\u034f\u0357"+ - "\u036a\u036f\u037a\u0385\u0388\u0391\u0394\u0396\u039a\u03a1\u03ab\u03af"+ - "\u03b3\u03bd\u03bf\u03c5\3\2\3\2"; + "\7f\2\2\u0128\u0129\7g\2\2\u0129\u012a\7e\2\2\u012a\u012b\7k\2\2\u012b"+ + "\u012c\7o\2\2\u012c\u012d\7c\2\2\u012d\u012e\7n\2\2\u012e\u012f\7/\2\2"+ + "\u012f\u0130\7h\2\2\u0130\u0131\7q\2\2\u0131\u0132\7t\2\2\u0132\u0133"+ + "\7o\2\2\u0133\u0134\7c\2\2\u0134\u0135\7v\2\2\u0135\22\3\2\2\2\u0136\u0137"+ + "\7<\2\2\u0137\24\3\2\2\2\u0138\u0139\7f\2\2\u0139\u013a\7g\2\2\u013a\u013b"+ + "\7e\2\2\u013b\u013c\7k\2\2\u013c\u013d\7o\2\2\u013d\u013e\7c\2\2\u013e"+ + "\u013f\7n\2\2\u013f\u0140\7/\2\2\u0140\u0141\7u\2\2\u0141\u0142\7g\2\2"+ + "\u0142\u0143\7r\2\2\u0143\u0144\7c\2\2\u0144\u0145\7t\2\2\u0145\u0146"+ + "\7c\2\2\u0146\u0147\7v\2\2\u0147\u0148\7q\2\2\u0148\u0149\7t\2\2\u0149"+ + "\26\3\2\2\2\u014a\u014b\7i\2\2\u014b\u014c\7t\2\2\u014c\u014d\7q\2\2\u014d"+ + "\u014e\7w\2\2\u014e\u014f\7r\2\2\u014f\u0150\7k\2\2\u0150\u0151\7p\2\2"+ + "\u0151\u0152\7i\2\2\u0152\u0153\7/\2\2\u0153\u0154\7u\2\2\u0154\u0155"+ + "\7g\2\2\u0155\u0156\7r\2\2\u0156\u0157\7c\2\2\u0157\u0158\7t\2\2\u0158"+ + "\u0159\7c\2\2\u0159\u015a\7v\2\2\u015a\u015b\7q\2\2\u015b\u015c\7t\2\2"+ + "\u015c\30\3\2\2\2\u015d\u015e\7k\2\2\u015e\u015f\7p\2\2\u015f\u0160\7"+ + "h\2\2\u0160\u0161\7k\2\2\u0161\u0162\7p\2\2\u0162\u0163\7k\2\2\u0163\u0164"+ + "\7v\2\2\u0164\u0165\7{\2\2\u0165\32\3\2\2\2\u0166\u0167\7o\2\2\u0167\u0168"+ + "\7k\2\2\u0168\u0169\7p\2\2\u0169\u016a\7w\2\2\u016a\u016b\7u\2\2\u016b"+ + "\u016c\7/\2\2\u016c\u016d\7u\2\2\u016d\u016e\7k\2\2\u016e\u016f\7i\2\2"+ + "\u016f\u0170\7p\2\2\u0170\34\3\2\2\2\u0171\u0172\7P\2\2\u0172\u0173\7"+ + "c\2\2\u0173\u0174\7P\2\2\u0174\36\3\2\2\2\u0175\u0176\7r\2\2\u0176\u0177"+ + "\7g\2\2\u0177\u0178\7t\2\2\u0178\u0179\7e\2\2\u0179\u017a\7g\2\2\u017a"+ + "\u017b\7p\2\2\u017b\u017c\7v\2\2\u017c \3\2\2\2\u017d\u017e\7r\2\2\u017e"+ + "\u017f\7g\2\2\u017f\u0180\7t\2\2\u0180\u0181\7/\2\2\u0181\u0182\7o\2\2"+ + "\u0182\u0183\7k\2\2\u0183\u0184\7n\2\2\u0184\u0185\7n\2\2\u0185\u0186"+ + "\7g\2\2\u0186\"\3\2\2\2\u0187\u0188\7|\2\2\u0188\u0189\7g\2\2\u0189\u018a"+ + "\7t\2\2\u018a\u018b\7q\2\2\u018b\u018c\7/\2\2\u018c\u018d\7f\2\2\u018d"+ + "\u018e\7k\2\2\u018e\u018f\7i\2\2\u018f\u0190\7k\2\2\u0190\u0191\7v\2\2"+ + "\u0191$\3\2\2\2\u0192\u0193\7f\2\2\u0193\u0194\7k\2\2\u0194\u0195\7i\2"+ + "\2\u0195\u0196\7k\2\2\u0196\u0197\7v\2\2\u0197&\3\2\2\2\u0198\u0199\7"+ + "r\2\2\u0199\u019a\7c\2\2\u019a\u019b\7v\2\2\u019b\u019c\7v\2\2\u019c\u019d"+ + "\7g\2\2\u019d\u019e\7t\2\2\u019e\u019f\7p\2\2\u019f\u01a0\7/\2\2\u01a0"+ + "\u01a1\7u\2\2\u01a1\u01a2\7g\2\2\u01a2\u01a3\7r\2\2\u01a3\u01a4\7c\2\2"+ + "\u01a4\u01a5\7t\2\2\u01a5\u01a6\7c\2\2\u01a6\u01a7\7v\2\2\u01a7\u01a8"+ + "\7q\2\2\u01a8\u01a9\7t\2\2\u01a9(\3\2\2\2\u01aa\u01ab\7k\2\2\u01ab\u01ac"+ + "\7o\2\2\u01ac\u01ad\7r\2\2\u01ad\u01ae\7q\2\2\u01ae\u01af\7t\2\2\u01af"+ + "\u01b0\7v\2\2\u01b0*\3\2\2\2\u01b1\u01b2\7.\2\2\u01b2,\3\2\2\2\u01b3\u01b4"+ + "\7x\2\2\u01b4\u01b5\7c\2\2\u01b5\u01b6\7t\2\2\u01b6\u01b7\7k\2\2\u01b7"+ + "\u01b8\7c\2\2\u01b8\u01b9\7d\2\2\u01b9\u01ba\7n\2\2\u01ba\u01bb\7g\2\2"+ + "\u01bb.\3\2\2\2\u01bc\u01bd\7<\2\2\u01bd\u01be\7?\2\2\u01be\60\3\2\2\2"+ + "\u01bf\u01c0\7g\2\2\u01c0\u01c1\7z\2\2\u01c1\u01c2\7v\2\2\u01c2\u01c3"+ + "\7g\2\2\u01c3\u01c4\7t\2\2\u01c4\u01c5\7p\2\2\u01c5\u01c6\7c\2\2\u01c6"+ + "\u01c7\7n\2\2\u01c7\62\3\2\2\2\u01c8\u01c9\7h\2\2\u01c9\u01ca\7w\2\2\u01ca"+ + "\u01cb\7p\2\2\u01cb\u01cc\7e\2\2\u01cc\u01cd\7v\2\2\u01cd\u01ce\7k\2\2"+ + "\u01ce\u01cf\7q\2\2\u01cf\u01d0\7p\2\2\u01d0\64\3\2\2\2\u01d1\u01d2\7"+ + "*\2\2\u01d2\66\3\2\2\2\u01d3\u01d4\7+\2\2\u01d48\3\2\2\2\u01d5\u01d6\7"+ + "}\2\2\u01d6:\3\2\2\2\u01d7\u01d8\7\177\2\2\u01d8<\3\2\2\2\u01d9\u01da"+ + "\7v\2\2\u01da\u01db\7{\2\2\u01db\u01dc\7r\2\2\u01dc\u01dd\7g\2\2\u01dd"+ + ">\3\2\2\2\u01de\u01df\7&\2\2\u01df@\3\2\2\2\u01e0\u01e1\7~\2\2\u01e1B"+ + "\3\2\2\2\u01e2\u01e3\7,\2\2\u01e3D\3\2\2\2\u01e4\u01e5\7g\2\2\u01e5\u01e6"+ + "\7s\2\2\u01e6F\3\2\2\2\u01e7\u01e8\7p\2\2\u01e8\u01e9\7g\2\2\u01e9H\3"+ + "\2\2\2\u01ea\u01eb\7n\2\2\u01eb\u01ec\7v\2\2\u01ecJ\3\2\2\2\u01ed\u01ee"+ + "\7n\2\2\u01ee\u01ef\7g\2\2\u01efL\3\2\2\2\u01f0\u01f1\7i\2\2\u01f1\u01f2"+ + "\7v\2\2\u01f2N\3\2\2\2\u01f3\u01f4\7i\2\2\u01f4\u01f5\7g\2\2\u01f5P\3"+ + "\2\2\2\u01f6\u01f7\7#\2\2\u01f7\u01f8\7?\2\2\u01f8R\3\2\2\2\u01f9\u01fa"+ + "\7>\2\2\u01faT\3\2\2\2\u01fb\u01fc\7>\2\2\u01fc\u01fd\7?\2\2\u01fdV\3"+ + "\2\2\2\u01fe\u01ff\7@\2\2\u01ffX\3\2\2\2\u0200\u0201\7@\2\2\u0201\u0202"+ + "\7?\2\2\u0202Z\3\2\2\2\u0203\u0204\7~\2\2\u0204\u0205\7~\2\2\u0205\\\3"+ + "\2\2\2\u0206\u0207\7-\2\2\u0207^\3\2\2\2\u0208\u0209\7/\2\2\u0209`\3\2"+ + "\2\2\u020a\u020b\7f\2\2\u020b\u020c\7k\2\2\u020c\u020d\7x\2\2\u020db\3"+ + "\2\2\2\u020e\u020f\7k\2\2\u020f\u0210\7f\2\2\u0210\u0211\7k\2\2\u0211"+ + "\u0212\7x\2\2\u0212d\3\2\2\2\u0213\u0214\7o\2\2\u0214\u0215\7q\2\2\u0215"+ + "\u0216\7f\2\2\u0216f\3\2\2\2\u0217\u0218\7x\2\2\u0218\u0219\7c\2\2\u0219"+ + "\u021a\7n\2\2\u021a\u021b\7k\2\2\u021b\u021c\7f\2\2\u021c\u021d\7c\2\2"+ + "\u021d\u021e\7v\2\2\u021e\u021f\7g\2\2\u021fh\3\2\2\2\u0220\u0221\7#\2"+ + "\2\u0221j\3\2\2\2\u0222\u0223\7]\2\2\u0223l\3\2\2\2\u0224\u0225\7_\2\2"+ + "\u0225n\3\2\2\2\u0226\u0227\7\60\2\2\u0227p\3\2\2\2\u0228\u0229\7&\2\2"+ + "\u0229\u022a\7&\2\2\u022ar\3\2\2\2\u022b\u022c\7%\2\2\u022ct\3\2\2\2\u022d"+ + "\u022e\7}\2\2\u022e\u022f\7~\2\2\u022fv\3\2\2\2\u0230\u0231\7~\2\2\u0231"+ + "\u0232\7\177\2\2\u0232x\3\2\2\2\u0233\u0234\7h\2\2\u0234\u0235\7q\2\2"+ + "\u0235\u0236\7t\2\2\u0236z\3\2\2\2\u0237\u0238\7n\2\2\u0238\u0239\7g\2"+ + "\2\u0239\u023a\7v\2\2\u023a|\3\2\2\2\u023b\u023c\7y\2\2\u023c\u023d\7"+ + "j\2\2\u023d\u023e\7g\2\2\u023e\u023f\7t\2\2\u023f\u0240\7g\2\2\u0240~"+ + "\3\2\2\2\u0241\u0242\7i\2\2\u0242\u0243\7t\2\2\u0243\u0244\7q\2\2\u0244"+ + "\u0245\7w\2\2\u0245\u0246\7r\2\2\u0246\u0080\3\2\2\2\u0247\u0248\7d\2"+ + "\2\u0248\u0249\7{\2\2\u0249\u0082\3\2\2\2\u024a\u024b\7q\2\2\u024b\u024c"+ + "\7t\2\2\u024c\u024d\7f\2\2\u024d\u024e\7g\2\2\u024e\u024f\7t\2\2\u024f"+ + "\u0084\3\2\2\2\u0250\u0251\7t\2\2\u0251\u0252\7g\2\2\u0252\u0253\7v\2"+ + "\2\u0253\u0254\7w\2\2\u0254\u0255\7t\2\2\u0255\u0256\7p\2\2\u0256\u0086"+ + "\3\2\2\2\u0257\u0258\7k\2\2\u0258\u0259\7h\2\2\u0259\u0088\3\2\2\2\u025a"+ + "\u025b\7k\2\2\u025b\u025c\7p\2\2\u025c\u008a\3\2\2\2\u025d\u025e\7c\2"+ + "\2\u025e\u025f\7u\2\2\u025f\u008c\3\2\2\2\u0260\u0261\7c\2\2\u0261\u0262"+ + "\7v\2\2\u0262\u008e\3\2\2\2\u0263\u0264\7c\2\2\u0264\u0265\7n\2\2\u0265"+ + "\u0266\7n\2\2\u0266\u0267\7q\2\2\u0267\u0268\7y\2\2\u0268\u0269\7k\2\2"+ + "\u0269\u026a\7p\2\2\u026a\u026b\7i\2\2\u026b\u0090\3\2\2\2\u026c\u026d"+ + "\7g\2\2\u026d\u026e\7o\2\2\u026e\u026f\7r\2\2\u026f\u0270\7v\2\2\u0270"+ + "\u0271\7{\2\2\u0271\u0092\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7q\2"+ + "\2\u0274\u0275\7w\2\2\u0275\u0276\7p\2\2\u0276\u0277\7v\2\2\u0277\u0094"+ + "\3\2\2\2\u0278\u0279\7u\2\2\u0279\u027a\7v\2\2\u027a\u027b\7c\2\2\u027b"+ + "\u027c\7d\2\2\u027c\u027d\7n\2\2\u027d\u027e\7g\2\2\u027e\u0096\3\2\2"+ + "\2\u027f\u0280\7c\2\2\u0280\u0281\7u\2\2\u0281\u0282\7e\2\2\u0282\u0283"+ + "\7g\2\2\u0283\u0284\7p\2\2\u0284\u0285\7f\2\2\u0285\u0286\7k\2\2\u0286"+ + "\u0287\7p\2\2\u0287\u0288\7i\2\2\u0288\u0098\3\2\2\2\u0289\u028a\7f\2"+ + "\2\u028a\u028b\7g\2\2\u028b\u028c\7u\2\2\u028c\u028d\7e\2\2\u028d\u028e"+ + "\7g\2\2\u028e\u028f\7p\2\2\u028f\u0290\7f\2\2\u0290\u0291\7k\2\2\u0291"+ + "\u0292\7p\2\2\u0292\u0293\7i\2\2\u0293\u009a\3\2\2\2\u0294\u0295\7u\2"+ + "\2\u0295\u0296\7q\2\2\u0296\u0297\7o\2\2\u0297\u0298\7g\2\2\u0298\u009c"+ + "\3\2\2\2\u0299\u029a\7g\2\2\u029a\u029b\7x\2\2\u029b\u029c\7g\2\2\u029c"+ + "\u029d\7t\2\2\u029d\u029e\7{\2\2\u029e\u009e\3\2\2\2\u029f\u02a0\7u\2"+ + "\2\u02a0\u02a1\7c\2\2\u02a1\u02a2\7v\2\2\u02a2\u02a3\7k\2\2\u02a3\u02a4"+ + "\7u\2\2\u02a4\u02a5\7h\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a7\7g\2\2\u02a7"+ + "\u02a8\7u\2\2\u02a8\u00a0\3\2\2\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7q\2"+ + "\2\u02ab\u02ac\7n\2\2\u02ac\u02ad\7n\2\2\u02ad\u02ae\7c\2\2\u02ae\u02af"+ + "\7v\2\2\u02af\u02b0\7k\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7p\2\2\u02b2"+ + "\u00a2\3\2\2\2\u02b3\u02b4\7i\2\2\u02b4\u02b5\7t\2\2\u02b5\u02b6\7g\2"+ + "\2\u02b6\u02b7\7c\2\2\u02b7\u02b8\7v\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba"+ + "\7u\2\2\u02ba\u02bb\7v\2\2\u02bb\u00a4\3\2\2\2\u02bc\u02bd\7n\2\2\u02bd"+ + "\u02be\7g\2\2\u02be\u02bf\7c\2\2\u02bf\u02c0\7u\2\2\u02c0\u02c1\7v\2\2"+ + "\u02c1\u00a6\3\2\2\2\u02c2\u02c3\7u\2\2\u02c3\u02c4\7y\2\2\u02c4\u02c5"+ + "\7k\2\2\u02c5\u02c6\7v\2\2\u02c6\u02c7\7e\2\2\u02c7\u02c8\7j\2\2\u02c8"+ + "\u00a8\3\2\2\2\u02c9\u02ca\7e\2\2\u02ca\u02cb\7c\2\2\u02cb\u02cc\7u\2"+ + "\2\u02cc\u02cd\7g\2\2\u02cd\u00aa\3\2\2\2\u02ce\u02cf\7v\2\2\u02cf\u02d0"+ + "\7t\2\2\u02d0\u02d1\7{\2\2\u02d1\u00ac\3\2\2\2\u02d2\u02d3\7e\2\2\u02d3"+ + "\u02d4\7c\2\2\u02d4\u02d5\7v\2\2\u02d5\u02d6\7e\2\2\u02d6\u02d7\7j\2\2"+ + "\u02d7\u00ae\3\2\2\2\u02d8\u02d9\7f\2\2\u02d9\u02da\7g\2\2\u02da\u02db"+ + "\7h\2\2\u02db\u02dc\7c\2\2\u02dc\u02dd\7w\2\2\u02dd\u02de\7n\2\2\u02de"+ + "\u02df\7v\2\2\u02df\u00b0\3\2\2\2\u02e0\u02e1\7v\2\2\u02e1\u02e2\7j\2"+ + "\2\u02e2\u02e3\7g\2\2\u02e3\u02e4\7p\2\2\u02e4\u00b2\3\2\2\2\u02e5\u02e6"+ + "\7g\2\2\u02e6\u02e7\7n\2\2\u02e7\u02e8\7u\2\2\u02e8\u02e9\7g\2\2\u02e9"+ + "\u00b4\3\2\2\2\u02ea\u02eb\7v\2\2\u02eb\u02ec\7{\2\2\u02ec\u02ed\7r\2"+ + "\2\u02ed\u02ee\7g\2\2\u02ee\u02ef\7u\2\2\u02ef\u02f0\7y\2\2\u02f0\u02f1"+ + "\7k\2\2\u02f1\u02f2\7v\2\2\u02f2\u02f3\7e\2\2\u02f3\u02f4\7j\2\2\u02f4"+ + "\u00b6\3\2\2\2\u02f5\u02f6\7q\2\2\u02f6\u02f7\7t\2\2\u02f7\u00b8\3\2\2"+ + "\2\u02f8\u02f9\7c\2\2\u02f9\u02fa\7p\2\2\u02fa\u02fb\7f\2\2\u02fb\u00ba"+ + "\3\2\2\2\u02fc\u02fd\7p\2\2\u02fd\u02fe\7q\2\2\u02fe\u02ff\7v\2\2\u02ff"+ + "\u00bc\3\2\2\2\u0300\u0301\7v\2\2\u0301\u0302\7q\2\2\u0302\u00be\3\2\2"+ + "\2\u0303\u0304\7k\2\2\u0304\u0305\7p\2\2\u0305\u0306\7u\2\2\u0306\u0307"+ + "\7v\2\2\u0307\u0308\7c\2\2\u0308\u0309\7p\2\2\u0309\u030a\7e\2\2\u030a"+ + "\u030b\7g\2\2\u030b\u00c0\3\2\2\2\u030c\u030d\7q\2\2\u030d\u030e\7h\2"+ + "\2\u030e\u00c2\3\2\2\2\u030f\u0310\7u\2\2\u0310\u0311\7v\2\2\u0311\u0312"+ + "\7c\2\2\u0312\u0313\7v\2\2\u0313\u0314\7k\2\2\u0314\u0315\7e\2\2\u0315"+ + "\u0316\7c\2\2\u0316\u0317\7n\2\2\u0317\u0318\7n\2\2\u0318\u0319\7{\2\2"+ + "\u0319\u00c4\3\2\2\2\u031a\u031b\7k\2\2\u031b\u031c\7u\2\2\u031c\u00c6"+ + "\3\2\2\2\u031d\u031e\7v\2\2\u031e\u031f\7t\2\2\u031f\u0320\7g\2\2\u0320"+ + "\u0321\7c\2\2\u0321\u0322\7v\2\2\u0322\u00c8\3\2\2\2\u0323\u0324\7e\2"+ + "\2\u0324\u0325\7c\2\2\u0325\u0326\7u\2\2\u0326\u0327\7v\2\2\u0327\u00ca"+ + "\3\2\2\2\u0328\u0329\7e\2\2\u0329\u032a\7c\2\2\u032a\u032b\7u\2\2\u032b"+ + "\u032c\7v\2\2\u032c\u032d\7c\2\2\u032d\u032e\7d\2\2\u032e\u032f\7n\2\2"+ + "\u032f\u0330\7g\2\2\u0330\u00cc\3\2\2\2\u0331\u0332\7x\2\2\u0332\u0333"+ + "\7g\2\2\u0333\u0334\7t\2\2\u0334\u0335\7u\2\2\u0335\u0336\7k\2\2\u0336"+ + "\u0337\7q\2\2\u0337\u0338\7p\2\2\u0338\u00ce\3\2\2\2\u0339\u033a\7l\2"+ + "\2\u033a\u033b\7u\2\2\u033b\u033c\7q\2\2\u033c\u033d\7p\2\2\u033d\u033e"+ + "\7k\2\2\u033e\u033f\7s\2\2\u033f\u00d0\3\2\2\2\u0340\u0341\7w\2\2\u0341"+ + "\u0342\7p\2\2\u0342\u0343\7q\2\2\u0343\u0344\7t\2\2\u0344\u0345\7f\2\2"+ + "\u0345\u0346\7g\2\2\u0346\u0347\7t\2\2\u0347\u0348\7g\2\2\u0348\u0349"+ + "\7f\2\2\u0349\u00d2\3\2\2\2\u034a\u034f\7$\2\2\u034b\u034e\5\u00d5k\2"+ + "\u034c\u034e\n\2\2\2\u034d\u034b\3\2\2\2\u034d\u034c\3\2\2\2\u034e\u0351"+ + "\3\2\2\2\u034f\u034d\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351"+ + "\u034f\3\2\2\2\u0352\u0353\7$\2\2\u0353\u00d4\3\2\2\2\u0354\u0357\7^\2"+ + "\2\u0355\u0358\t\3\2\2\u0356\u0358\5\u00d7l\2\u0357\u0355\3\2\2\2\u0357"+ + "\u0356\3\2\2\2\u0358\u00d6\3\2\2\2\u0359\u035a\7w\2\2\u035a\u035b\5\u00d9"+ + "m\2\u035b\u035c\5\u00d9m\2\u035c\u035d\5\u00d9m\2\u035d\u035e\5\u00d9"+ + "m\2\u035e\u00d8\3\2\2\2\u035f\u0360\t\4\2\2\u0360\u00da\3\2\2\2\u0361"+ + "\u0362\7A\2\2\u0362\u00dc\3\2\2\2\u0363\u0364\7p\2\2\u0364\u0365\7w\2"+ + "\2\u0365\u0366\7n\2\2\u0366\u0367\7n\2\2\u0367\u00de\3\2\2\2\u0368\u036b"+ + "\5\u00e1q\2\u0369\u036b\5\u00e3r\2\u036a\u0368\3\2\2\2\u036a\u0369\3\2"+ + "\2\2\u036b\u00e0\3\2\2\2\u036c\u0370\5\u00e5s\2\u036d\u0370\5\u00e7t\2"+ + "\u036e\u0370\5\u00e9u\2\u036f\u036c\3\2\2\2\u036f\u036d\3\2\2\2\u036f"+ + "\u036e\3\2\2\2\u0370\u00e2\3\2\2\2\u0371\u0372\7v\2\2\u0372\u0373\7t\2"+ + "\2\u0373\u0374\7w\2\2\u0374\u037b\7g\2\2\u0375\u0376\7h\2\2\u0376\u0377"+ + "\7c\2\2\u0377\u0378\7n\2\2\u0378\u0379\7u\2\2\u0379\u037b\7g\2\2\u037a"+ + "\u0371\3\2\2\2\u037a\u0375\3\2\2\2\u037b\u00e4\3\2\2\2\u037c\u037d\5\u00eb"+ + "v\2\u037d\u00e6\3\2\2\2\u037e\u037f\7\60\2\2\u037f\u0389\5\u00ebv\2\u0380"+ + "\u0381\5\u00ebv\2\u0381\u0385\7\60\2\2\u0382\u0384\t\5\2\2\u0383\u0382"+ + "\3\2\2\2\u0384\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386"+ + "\u0389\3\2\2\2\u0387\u0385\3\2\2\2\u0388\u037e\3\2\2\2\u0388\u0380\3\2"+ + "\2\2\u0389\u00e8\3\2\2\2\u038a\u038b\7\60\2\2\u038b\u0397\5\u00ebv\2\u038c"+ + "\u0394\5\u00ebv\2\u038d\u0391\7\60\2\2\u038e\u0390\t\5\2\2\u038f\u038e"+ + "\3\2\2\2\u0390\u0393\3\2\2\2\u0391\u038f\3\2\2\2\u0391\u0392\3\2\2\2\u0392"+ + "\u0395\3\2\2\2\u0393\u0391\3\2\2\2\u0394\u038d\3\2\2\2\u0394\u0395\3\2"+ + "\2\2\u0395\u0397\3\2\2\2\u0396\u038a\3\2\2\2\u0396\u038c\3\2\2\2\u0397"+ + "\u0398\3\2\2\2\u0398\u039a\t\6\2\2\u0399\u039b\t\7\2\2\u039a\u0399\3\2"+ + "\2\2\u039a\u039b\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039d\5\u00ebv\2\u039d"+ + "\u00ea\3\2\2\2\u039e\u03a0\t\5\2\2\u039f\u039e\3\2\2\2\u03a0\u03a1\3\2"+ + "\2\2\u03a1\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u00ec\3\2\2\2\u03a3"+ + "\u03a4\t\b\2\2\u03a4\u03a5\3\2\2\2\u03a5\u03a6\bw\2\2\u03a6\u00ee\3\2"+ + "\2\2\u03a7\u03ab\5\u00f1y\2\u03a8\u03aa\5\u00f3z\2\u03a9\u03a8\3\2\2\2"+ + "\u03aa\u03ad\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u00f0"+ + "\3\2\2\2\u03ad\u03ab\3\2\2\2\u03ae\u03b0\t\t\2\2\u03af\u03ae\3\2\2\2\u03b0"+ + "\u00f2\3\2\2\2\u03b1\u03b4\5\u00f1y\2\u03b2\u03b4\t\n\2\2\u03b3\u03b1"+ + "\3\2\2\2\u03b3\u03b2\3\2\2\2\u03b4\u00f4\3\2\2\2\u03b5\u03b6\7*\2\2\u03b6"+ + "\u03bf\7<\2\2\u03b7\u03be\5\u00f5{\2\u03b8\u03b9\7*\2\2\u03b9\u03be\n"+ + "\13\2\2\u03ba\u03bb\7<\2\2\u03bb\u03be\n\f\2\2\u03bc\u03be\n\r\2\2\u03bd"+ + "\u03b7\3\2\2\2\u03bd\u03b8\3\2\2\2\u03bd\u03ba\3\2\2\2\u03bd\u03bc\3\2"+ + "\2\2\u03be\u03c1\3\2\2\2\u03bf\u03bd\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0"+ + "\u03c3\3\2\2\2\u03c1\u03bf\3\2\2\2\u03c2\u03c4\7<\2\2\u03c3\u03c2\3\2"+ + "\2\2\u03c4\u03c5\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c5\u03c6\3\2\2\2\u03c6"+ + "\u03c7\3\2\2\2\u03c7\u03c8\7+\2\2\u03c8\u03c9\3\2\2\2\u03c9\u03ca\b{\2"+ + "\2\u03ca\u00f6\3\2\2\2\u03cb\u03cc\n\16\2\2\u03cc\u00f8\3\2\2\2\26\2\u034d"+ + "\u034f\u0357\u036a\u036f\u037a\u0385\u0388\u0391\u0394\u0396\u039a\u03a1"+ + "\u03ab\u03af\u03b3\u03bd\u03bf\u03c5\3\2\3\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens b/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens index d1974c069c..ced2126dd5 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens @@ -57,51 +57,51 @@ T__55=56 T__56=57 T__57=58 T__58=59 -T__59=60 -Kfor=61 -Klet=62 -Kwhere=63 -Kgroup=64 -Kby=65 -Korder=66 -Kreturn=67 -Kif=68 -Kin=69 -Kas=70 -Kat=71 -Kallowing=72 -Kempty=73 -Kcount=74 -Kstable=75 -Kascending=76 -Kdescending=77 -Ksome=78 -Kevery=79 -Ksatisfies=80 -Kcollation=81 -Kgreatest=82 -Kleast=83 -Kswitch=84 -Kcase=85 -Ktry=86 -Kcatch=87 -Kdefault=88 -Kthen=89 -Kelse=90 -Ktypeswitch=91 -Kor=92 -Kand=93 -Knot=94 -Kto=95 -Kinstance=96 -Kof=97 -Kstatically=98 -Kis=99 -Ktreat=100 -Kcast=101 -Kcastable=102 -Kversion=103 -Kjsoniq=104 +Kfor=60 +Klet=61 +Kwhere=62 +Kgroup=63 +Kby=64 +Korder=65 +Kreturn=66 +Kif=67 +Kin=68 +Kas=69 +Kat=70 +Kallowing=71 +Kempty=72 +Kcount=73 +Kstable=74 +Kascending=75 +Kdescending=76 +Ksome=77 +Kevery=78 +Ksatisfies=79 +Kcollation=80 +Kgreatest=81 +Kleast=82 +Kswitch=83 +Kcase=84 +Ktry=85 +Kcatch=86 +Kdefault=87 +Kthen=88 +Kelse=89 +Ktypeswitch=90 +Kor=91 +Kand=92 +Knot=93 +Kto=94 +Kinstance=95 +Kof=96 +Kstatically=97 +Kis=98 +Ktreat=99 +Kcast=100 +Kcastable=101 +Kversion=102 +Kjsoniq=103 +Kunordered=104 STRING=105 ArgumentPlaceholder=106 NullLiteral=107 @@ -122,102 +122,102 @@ ContentChar=117 'declare'=5 'ordering'=6 'ordered'=7 -'unordered'=8 -'decimal-format'=9 -':'=10 -'decimal-separator'=11 -'grouping-separator'=12 -'infinity'=13 -'minus-sign'=14 -'NaN'=15 -'percent'=16 -'per-mille'=17 -'zero-digit'=18 -'digit'=19 -'pattern-separator'=20 -'import'=21 -','=22 -'variable'=23 -':='=24 -'external'=25 -'function'=26 -'('=27 -')'=28 -'{'=29 -'}'=30 -'type'=31 -'$'=32 -'|'=33 -'*'=34 -'eq'=35 -'ne'=36 -'lt'=37 -'le'=38 -'gt'=39 -'ge'=40 -'!='=41 -'<'=42 -'<='=43 -'>'=44 -'>='=45 -'||'=46 -'+'=47 -'-'=48 -'div'=49 -'idiv'=50 -'mod'=51 -'validate'=52 -'!'=53 -'['=54 -']'=55 -'.'=56 -'$$'=57 -'#'=58 -'{|'=59 -'|}'=60 -'for'=61 -'let'=62 -'where'=63 -'group'=64 -'by'=65 -'order'=66 -'return'=67 -'if'=68 -'in'=69 -'as'=70 -'at'=71 -'allowing'=72 -'empty'=73 -'count'=74 -'stable'=75 -'ascending'=76 -'descending'=77 -'some'=78 -'every'=79 -'satisfies'=80 -'collation'=81 -'greatest'=82 -'least'=83 -'switch'=84 -'case'=85 -'try'=86 -'catch'=87 -'default'=88 -'then'=89 -'else'=90 -'typeswitch'=91 -'or'=92 -'and'=93 -'not'=94 -'to'=95 -'instance'=96 -'of'=97 -'statically'=98 -'is'=99 -'treat'=100 -'cast'=101 -'castable'=102 -'version'=103 -'jsoniq'=104 +'decimal-format'=8 +':'=9 +'decimal-separator'=10 +'grouping-separator'=11 +'infinity'=12 +'minus-sign'=13 +'NaN'=14 +'percent'=15 +'per-mille'=16 +'zero-digit'=17 +'digit'=18 +'pattern-separator'=19 +'import'=20 +','=21 +'variable'=22 +':='=23 +'external'=24 +'function'=25 +'('=26 +')'=27 +'{'=28 +'}'=29 +'type'=30 +'$'=31 +'|'=32 +'*'=33 +'eq'=34 +'ne'=35 +'lt'=36 +'le'=37 +'gt'=38 +'ge'=39 +'!='=40 +'<'=41 +'<='=42 +'>'=43 +'>='=44 +'||'=45 +'+'=46 +'-'=47 +'div'=48 +'idiv'=49 +'mod'=50 +'validate'=51 +'!'=52 +'['=53 +']'=54 +'.'=55 +'$$'=56 +'#'=57 +'{|'=58 +'|}'=59 +'for'=60 +'let'=61 +'where'=62 +'group'=63 +'by'=64 +'order'=65 +'return'=66 +'if'=67 +'in'=68 +'as'=69 +'at'=70 +'allowing'=71 +'empty'=72 +'count'=73 +'stable'=74 +'ascending'=75 +'descending'=76 +'some'=77 +'every'=78 +'satisfies'=79 +'collation'=80 +'greatest'=81 +'least'=82 +'switch'=83 +'case'=84 +'try'=85 +'catch'=86 +'default'=87 +'then'=88 +'else'=89 +'typeswitch'=90 +'or'=91 +'and'=92 +'not'=93 +'to'=94 +'instance'=95 +'of'=96 +'statically'=97 +'is'=98 +'treat'=99 +'cast'=100 +'castable'=101 +'version'=102 +'jsoniq'=103 +'unordered'=104 '?'=106 'null'=107 diff --git a/src/main/java/org/rumbledb/parser/JsoniqParser.java b/src/main/java/org/rumbledb/parser/JsoniqParser.java index 4f8a6a4122..0ddaa7a548 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqParser.java +++ b/src/main/java/org/rumbledb/parser/JsoniqParser.java @@ -3,25 +3,14 @@ // Java header package org.rumbledb.parser; -import java.util.ArrayList; -import java.util.List; - -import org.antlr.v4.runtime.NoViableAltException; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.RuntimeMetaData; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.Vocabulary; -import org.antlr.v4.runtime.VocabularyImpl; -import org.antlr.v4.runtime.atn.ATN; -import org.antlr.v4.runtime.atn.ATNDeserializer; -import org.antlr.v4.runtime.atn.ParserATNSimulator; -import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.tree.ParseTreeVisitor; -import org.antlr.v4.runtime.tree.TerminalNode; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class JsoniqParser extends Parser { @@ -39,54 +28,54 @@ public class JsoniqParser extends Parser { T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, - T__59=60, Kfor=61, Klet=62, Kwhere=63, Kgroup=64, Kby=65, Korder=66, Kreturn=67, - Kif=68, Kin=69, Kas=70, Kat=71, Kallowing=72, Kempty=73, Kcount=74, Kstable=75, - Kascending=76, Kdescending=77, Ksome=78, Kevery=79, Ksatisfies=80, Kcollation=81, - Kgreatest=82, Kleast=83, Kswitch=84, Kcase=85, Ktry=86, Kcatch=87, Kdefault=88, - Kthen=89, Kelse=90, Ktypeswitch=91, Kor=92, Kand=93, Knot=94, Kto=95, - Kinstance=96, Kof=97, Kstatically=98, Kis=99, Ktreat=100, Kcast=101, Kcastable=102, - Kversion=103, Kjsoniq=104, STRING=105, ArgumentPlaceholder=106, NullLiteral=107, - Literal=108, NumericLiteral=109, BooleanLiteral=110, IntegerLiteral=111, - DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, XQComment=116, - ContentChar=117; + Kfor=60, Klet=61, Kwhere=62, Kgroup=63, Kby=64, Korder=65, Kreturn=66, + Kif=67, Kin=68, Kas=69, Kat=70, Kallowing=71, Kempty=72, Kcount=73, Kstable=74, + Kascending=75, Kdescending=76, Ksome=77, Kevery=78, Ksatisfies=79, Kcollation=80, + Kgreatest=81, Kleast=82, Kswitch=83, Kcase=84, Ktry=85, Kcatch=86, Kdefault=87, + Kthen=88, Kelse=89, Ktypeswitch=90, Kor=91, Kand=92, Knot=93, Kto=94, + Kinstance=95, Kof=96, Kstatically=97, Kis=98, Ktreat=99, Kcast=100, Kcastable=101, + Kversion=102, Kjsoniq=103, Kunordered=104, STRING=105, ArgumentPlaceholder=106, + NullLiteral=107, Literal=108, NumericLiteral=109, BooleanLiteral=110, + IntegerLiteral=111, DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, + XQComment=116, ContentChar=117; public static final int RULE_moduleAndThisIsIt = 0, RULE_module = 1, RULE_mainModule = 2, RULE_libraryModule = 3, RULE_prolog = 4, RULE_setter = 5, RULE_namespaceDecl = 6, RULE_annotatedDecl = 7, RULE_defaultCollationDecl = 8, RULE_orderingModeDecl = 9, RULE_emptyOrderDecl = 10, - RULE_decimalFormatDecl = 11, RULE_qname = 12, RULE_nCNameOrKeyWord = 13, - RULE_dfPropertyName = 14, RULE_moduleImport = 15, RULE_varDecl = 16, RULE_functionDecl = 17, - RULE_typeDecl = 18, RULE_paramList = 19, RULE_param = 20, RULE_expr = 21, - RULE_exprSingle = 22, RULE_flowrExpr = 23, RULE_forClause = 24, RULE_forVar = 25, - RULE_letClause = 26, RULE_letVar = 27, RULE_whereClause = 28, RULE_groupByClause = 29, - RULE_groupByVar = 30, RULE_orderByClause = 31, RULE_orderByExpr = 32, - RULE_countClause = 33, RULE_quantifiedExpr = 34, RULE_quantifiedExprVar = 35, - RULE_switchExpr = 36, RULE_switchCaseClause = 37, RULE_typeSwitchExpr = 38, - RULE_caseClause = 39, RULE_ifExpr = 40, RULE_tryCatchExpr = 41, RULE_catchClause = 42, - RULE_orExpr = 43, RULE_andExpr = 44, RULE_notExpr = 45, RULE_comparisonExpr = 46, - RULE_stringConcatExpr = 47, RULE_rangeExpr = 48, RULE_additiveExpr = 49, - RULE_multiplicativeExpr = 50, RULE_instanceOfExpr = 51, RULE_isStaticallyExpr = 52, - RULE_treatExpr = 53, RULE_castableExpr = 54, RULE_castExpr = 55, RULE_arrowExpr = 56, - RULE_unaryExpr = 57, RULE_valueExpr = 58, RULE_validateExpr = 59, RULE_simpleMapExpr = 60, - RULE_postFixExpr = 61, RULE_arrayLookup = 62, RULE_arrayUnboxing = 63, - RULE_predicate = 64, RULE_objectLookup = 65, RULE_primaryExpr = 66, RULE_varRef = 67, - RULE_parenthesizedExpr = 68, RULE_contextItemExpr = 69, RULE_orderedExpr = 70, - RULE_unorderedExpr = 71, RULE_functionCall = 72, RULE_argumentList = 73, - RULE_argument = 74, RULE_functionItemExpr = 75, RULE_namedFunctionRef = 76, - RULE_inlineFunctionExpr = 77, RULE_sequenceType = 78, RULE_objectConstructor = 79, - RULE_itemType = 80, RULE_functionTest = 81, RULE_anyFunctionTest = 82, - RULE_typedFunctionTest = 83, RULE_singleType = 84, RULE_pairConstructor = 85, - RULE_arrayConstructor = 86, RULE_uriLiteral = 87, RULE_stringLiteral = 88, - RULE_keyWords = 89; + RULE_decimalFormatDecl = 11, RULE_qname = 12, RULE_dfPropertyName = 13, + RULE_moduleImport = 14, RULE_varDecl = 15, RULE_functionDecl = 16, RULE_typeDecl = 17, + RULE_paramList = 18, RULE_param = 19, RULE_expr = 20, RULE_exprSingle = 21, + RULE_flowrExpr = 22, RULE_forClause = 23, RULE_forVar = 24, RULE_letClause = 25, + RULE_letVar = 26, RULE_whereClause = 27, RULE_groupByClause = 28, RULE_groupByVar = 29, + RULE_orderByClause = 30, RULE_orderByExpr = 31, RULE_countClause = 32, + RULE_quantifiedExpr = 33, RULE_quantifiedExprVar = 34, RULE_switchExpr = 35, + RULE_switchCaseClause = 36, RULE_typeSwitchExpr = 37, RULE_caseClause = 38, + RULE_ifExpr = 39, RULE_tryCatchExpr = 40, RULE_catchClause = 41, RULE_orExpr = 42, + RULE_andExpr = 43, RULE_notExpr = 44, RULE_comparisonExpr = 45, RULE_stringConcatExpr = 46, + RULE_rangeExpr = 47, RULE_additiveExpr = 48, RULE_multiplicativeExpr = 49, + RULE_instanceOfExpr = 50, RULE_isStaticallyExpr = 51, RULE_treatExpr = 52, + RULE_castableExpr = 53, RULE_castExpr = 54, RULE_arrowExpr = 55, RULE_unaryExpr = 56, + RULE_valueExpr = 57, RULE_validateExpr = 58, RULE_simpleMapExpr = 59, + RULE_postFixExpr = 60, RULE_arrayLookup = 61, RULE_arrayUnboxing = 62, + RULE_predicate = 63, RULE_objectLookup = 64, RULE_primaryExpr = 65, RULE_varRef = 66, + RULE_parenthesizedExpr = 67, RULE_contextItemExpr = 68, RULE_orderedExpr = 69, + RULE_unorderedExpr = 70, RULE_functionCall = 71, RULE_argumentList = 72, + RULE_argument = 73, RULE_functionItemExpr = 74, RULE_namedFunctionRef = 75, + RULE_inlineFunctionExpr = 76, RULE_sequenceType = 77, RULE_objectConstructor = 78, + RULE_itemType = 79, RULE_functionTest = 80, RULE_anyFunctionTest = 81, + RULE_typedFunctionTest = 82, RULE_singleType = 83, RULE_pairConstructor = 84, + RULE_arrayConstructor = 85, RULE_uriLiteral = 86, RULE_stringLiteral = 87, + RULE_keyWords = 88; public static final String[] ruleNames = { "moduleAndThisIsIt", "module", "mainModule", "libraryModule", "prolog", "setter", "namespaceDecl", "annotatedDecl", "defaultCollationDecl", "orderingModeDecl", - "emptyOrderDecl", "decimalFormatDecl", "qname", "nCNameOrKeyWord", "dfPropertyName", - "moduleImport", "varDecl", "functionDecl", "typeDecl", "paramList", "param", - "expr", "exprSingle", "flowrExpr", "forClause", "forVar", "letClause", - "letVar", "whereClause", "groupByClause", "groupByVar", "orderByClause", - "orderByExpr", "countClause", "quantifiedExpr", "quantifiedExprVar", "switchExpr", - "switchCaseClause", "typeSwitchExpr", "caseClause", "ifExpr", "tryCatchExpr", - "catchClause", "orExpr", "andExpr", "notExpr", "comparisonExpr", "stringConcatExpr", + "emptyOrderDecl", "decimalFormatDecl", "qname", "dfPropertyName", "moduleImport", + "varDecl", "functionDecl", "typeDecl", "paramList", "param", "expr", "exprSingle", + "flowrExpr", "forClause", "forVar", "letClause", "letVar", "whereClause", + "groupByClause", "groupByVar", "orderByClause", "orderByExpr", "countClause", + "quantifiedExpr", "quantifiedExprVar", "switchExpr", "switchCaseClause", + "typeSwitchExpr", "caseClause", "ifExpr", "tryCatchExpr", "catchClause", + "orExpr", "andExpr", "notExpr", "comparisonExpr", "stringConcatExpr", "rangeExpr", "additiveExpr", "multiplicativeExpr", "instanceOfExpr", "isStaticallyExpr", "treatExpr", "castableExpr", "castExpr", "arrowExpr", "unaryExpr", "valueExpr", "validateExpr", "simpleMapExpr", "postFixExpr", "arrayLookup", "arrayUnboxing", @@ -100,21 +89,20 @@ public class JsoniqParser extends Parser { private static final String[] _LITERAL_NAMES = { null, "';'", "'module'", "'namespace'", "'='", "'declare'", "'ordering'", - "'ordered'", "'unordered'", "'decimal-format'", "':'", "'decimal-separator'", - "'grouping-separator'", "'infinity'", "'minus-sign'", "'NaN'", "'percent'", - "'per-mille'", "'zero-digit'", "'digit'", "'pattern-separator'", "'import'", - "','", "'variable'", "':='", "'external'", "'function'", "'('", "')'", - "'{'", "'}'", "'type'", "'$'", "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", - "'gt'", "'ge'", "'!='", "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", - "'div'", "'idiv'", "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", - "'$$'", "'#'", "'{|'", "'|}'", "'for'", "'let'", "'where'", "'group'", - "'by'", "'order'", "'return'", "'if'", "'in'", "'as'", "'at'", "'allowing'", - "'empty'", "'count'", "'stable'", "'ascending'", "'descending'", "'some'", - "'every'", "'satisfies'", "'collation'", "'greatest'", "'least'", "'switch'", - "'case'", "'try'", "'catch'", "'default'", "'then'", "'else'", "'typeswitch'", - "'or'", "'and'", "'not'", "'to'", "'instance'", "'of'", "'statically'", - "'is'", "'treat'", "'cast'", "'castable'", "'version'", "'jsoniq'", null, - "'?'", "'null'" + "'ordered'", "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", + "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", + "'digit'", "'pattern-separator'", "'import'", "','", "'variable'", "':='", + "'external'", "'function'", "'('", "')'", "'{'", "'}'", "'type'", "'$'", + "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", "'gt'", "'ge'", "'!='", + "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", "'div'", "'idiv'", + "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", "'$$'", "'#'", "'{|'", + "'|}'", "'for'", "'let'", "'where'", "'group'", "'by'", "'order'", "'return'", + "'if'", "'in'", "'as'", "'at'", "'allowing'", "'empty'", "'count'", "'stable'", + "'ascending'", "'descending'", "'some'", "'every'", "'satisfies'", "'collation'", + "'greatest'", "'least'", "'switch'", "'case'", "'try'", "'catch'", "'default'", + "'then'", "'else'", "'typeswitch'", "'or'", "'and'", "'not'", "'to'", + "'instance'", "'of'", "'statically'", "'is'", "'treat'", "'cast'", "'castable'", + "'version'", "'jsoniq'", "'unordered'", null, "'?'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -122,15 +110,15 @@ public class JsoniqParser extends Parser { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", - "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", - "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", - "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", - "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", - "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", - "Kjsoniq", "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", - "NumericLiteral", "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", - "DoubleLiteral", "WS", "NCName", "XQComment", "ContentChar" + "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", "Kif", + "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", "Kascending", + "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", + "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", + "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", + "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", "Kjsoniq", "Kunordered", + "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", + "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", + "WS", "NCName", "XQComment", "ContentChar" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -203,9 +191,9 @@ public final ModuleAndThisIsItContext moduleAndThisIsIt() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(180); + setState(178); module(); - setState(181); + setState(179); match(EOF); } } @@ -251,45 +239,44 @@ public final ModuleContext module() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(188); + setState(186); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { case 1: { - setState(183); + setState(181); match(Kjsoniq); - setState(184); + setState(182); match(Kversion); - setState(185); + setState(183); ((ModuleContext)_localctx).vers = stringLiteral(); - setState(186); + setState(184); match(T__0); } break; } - setState(192); + setState(190); _errHandler.sync(this); switch (_input.LA(1)) { case T__1: { - setState(190); + setState(188); libraryModule(); } break; case T__4: case T__6: - case T__7: - case T__20: + case T__19: + case T__24: case T__25: - case T__26: - case T__28: - case T__31: + case T__27: + case T__30: + case T__45: case T__46: - case T__47: - case T__51: - case T__53: - case T__56: - case T__58: + case T__50: + case T__52: + case T__55: + case T__57: case Kfor: case Klet: case Kwhere: @@ -334,12 +321,13 @@ public final ModuleContext module() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: { - setState(191); + setState(189); ((ModuleContext)_localctx).main = mainModule(); } break; @@ -383,9 +371,9 @@ public final MainModuleContext mainModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(194); + setState(192); prolog(); - setState(195); + setState(193); expr(); } } @@ -425,19 +413,19 @@ public final LibraryModuleContext libraryModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(197); + setState(195); match(T__1); - setState(198); + setState(196); match(T__2); - setState(199); + setState(197); match(NCName); - setState(200); + setState(198); match(T__3); - setState(201); + setState(199); uriLiteral(); - setState(202); + setState(200); match(T__0); - setState(203); + setState(201); prolog(); } } @@ -496,57 +484,57 @@ public final PrologContext prolog() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(214); + setState(212); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(208); + setState(206); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: { - setState(205); + setState(203); setter(); } break; case 2: { - setState(206); + setState(204); namespaceDecl(); } break; case 3: { - setState(207); + setState(205); moduleImport(); } break; } - setState(210); + setState(208); match(T__0); } } } - setState(216); + setState(214); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); } - setState(222); + setState(220); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__4) { { { - setState(217); + setState(215); annotatedDecl(); - setState(218); + setState(216); match(T__0); } } - setState(224); + setState(222); _errHandler.sync(this); _la = _input.LA(1); } @@ -591,34 +579,34 @@ public final SetterContext setter() throws RecognitionException { SetterContext _localctx = new SetterContext(_ctx, getState()); enterRule(_localctx, 10, RULE_setter); try { - setState(229); + setState(227); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(225); + setState(223); defaultCollationDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(226); + setState(224); orderingModeDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(227); + setState(225); emptyOrderDecl(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(228); + setState(226); decimalFormatDecl(); } break; @@ -657,15 +645,15 @@ public final NamespaceDeclContext namespaceDecl() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(231); + setState(229); match(T__4); - setState(232); + setState(230); match(T__2); - setState(233); + setState(231); match(NCName); - setState(234); + setState(232); match(T__3); - setState(235); + setState(233); uriLiteral(); } } @@ -705,27 +693,27 @@ public final AnnotatedDeclContext annotatedDecl() throws RecognitionException { AnnotatedDeclContext _localctx = new AnnotatedDeclContext(_ctx, getState()); enterRule(_localctx, 14, RULE_annotatedDecl); try { - setState(240); + setState(238); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(237); + setState(235); functionDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(238); + setState(236); varDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(239); + setState(237); typeDecl(); } break; @@ -765,13 +753,13 @@ public final DefaultCollationDeclContext defaultCollationDecl() throws Recogniti try { enterOuterAlt(_localctx, 1); { - setState(242); + setState(240); match(T__4); - setState(243); + setState(241); match(Kdefault); - setState(244); + setState(242); match(Kcollation); - setState(245); + setState(243); uriLiteral(); } } @@ -805,13 +793,13 @@ public final OrderingModeDeclContext orderingModeDecl() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(247); + setState(245); match(T__4); - setState(248); + setState(246); match(T__5); - setState(249); + setState(247); _la = _input.LA(1); - if ( !(_la==T__6 || _la==T__7) ) { + if ( !(_la==T__6 || _la==Kunordered) ) { _errHandler.recoverInline(this); } else { @@ -856,16 +844,16 @@ public final EmptyOrderDeclContext emptyOrderDecl() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(251); + setState(249); match(T__4); - setState(252); + setState(250); match(Kdefault); - setState(253); + setState(251); match(Korder); - setState(254); + setState(252); match(Kempty); { - setState(255); + setState(253); ((EmptyOrderDeclContext)_localctx).emptySequenceOrder = _input.LT(1); _la = _input.LA(1); if ( !(_la==Kgreatest || _la==Kleast) ) { @@ -925,17 +913,17 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(257); + setState(255); match(T__4); - setState(262); + setState(260); _errHandler.sync(this); switch (_input.LA(1)) { - case T__8: + case T__7: { { - setState(258); - match(T__8); - setState(259); + setState(256); + match(T__7); + setState(257); qname(); } } @@ -943,31 +931,31 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce case Kdefault: { { - setState(260); + setState(258); match(Kdefault); - setState(261); - match(T__8); + setState(259); + match(T__7); } } break; default: throw new NoViableAltException(this); } - setState(270); + setState(268); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18))) != 0)) { { { - setState(264); + setState(262); dfPropertyName(); - setState(265); + setState(263); match(T__3); - setState(266); + setState(264); stringLiteral(); } } - setState(272); + setState(270); _errHandler.sync(this); _la = _input.LA(1); } @@ -987,10 +975,11 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce public static class QnameContext extends ParserRuleContext { public Token ns; public KeyWordsContext nskw; - public NCNameOrKeyWordContext local_name; + public Token local_name; public KeyWordsContext local_namekw; - public NCNameOrKeyWordContext nCNameOrKeyWord() { - return getRuleContext(NCNameOrKeyWordContext.class,0); + public List NCName() { return getTokens(JsoniqParser.NCName); } + public TerminalNode NCName(int i) { + return getToken(JsoniqParser.NCName, i); } public List keyWords() { return getRuleContexts(KeyWordsContext.class); @@ -998,7 +987,6 @@ public List keyWords() { public KeyWordsContext keyWords(int i) { return getRuleContext(KeyWordsContext.class,i); } - public TerminalNode NCName() { return getToken(JsoniqParser.NCName, 0); } public QnameContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -1016,17 +1004,17 @@ public final QnameContext qname() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(278); + setState(276); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: { - setState(275); + setState(273); _errHandler.sync(this); switch (_input.LA(1)) { case NCName: { - setState(273); + setState(271); ((QnameContext)_localctx).ns = match(NCName); } break; @@ -1074,79 +1062,83 @@ public final QnameContext qname() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: { - setState(274); + setState(272); ((QnameContext)_localctx).nskw = keyWords(); } break; default: throw new NoViableAltException(this); } - setState(277); - match(T__9); + setState(275); + match(T__8); } break; } - setState(282); + setState(280); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { - case 1: + switch (_input.LA(1)) { + case NCName: { - setState(280); - ((QnameContext)_localctx).local_name = nCNameOrKeyWord(); + setState(278); + ((QnameContext)_localctx).local_name = match(NCName); } break; - case 2: + case Kfor: + case Klet: + case Kwhere: + case Kgroup: + case Kby: + case Korder: + case Kreturn: + case Kif: + case Kin: + case Kas: + case Kat: + case Kallowing: + case Kempty: + case Kcount: + case Kstable: + case Kascending: + case Kdescending: + case Ksome: + case Kevery: + case Ksatisfies: + case Kcollation: + case Kgreatest: + case Kleast: + case Kswitch: + case Kcase: + case Ktry: + case Kcatch: + case Kdefault: + case Kthen: + case Kelse: + case Ktypeswitch: + case Kor: + case Kand: + case Knot: + case Kto: + case Kinstance: + case Kof: + case Kstatically: + case Kis: + case Ktreat: + case Kcast: + case Kcastable: + case Kversion: + case Kjsoniq: + case Kunordered: + case NullLiteral: { - setState(281); + setState(279); ((QnameContext)_localctx).local_namekw = keyWords(); } break; - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class NCNameOrKeyWordContext extends ParserRuleContext { - public TerminalNode NCName() { return getToken(JsoniqParser.NCName, 0); } - public TerminalNode NullLiteral() { return getToken(JsoniqParser.NullLiteral, 0); } - public NCNameOrKeyWordContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_nCNameOrKeyWord; } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitNCNameOrKeyWord(this); - else return visitor.visitChildren(this); - } - } - - public final NCNameOrKeyWordContext nCNameOrKeyWord() throws RecognitionException { - NCNameOrKeyWordContext _localctx = new NCNameOrKeyWordContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_nCNameOrKeyWord); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(284); - _la = _input.LA(1); - if ( !(_la==NullLiteral || _la==NCName) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); + default: + throw new NoViableAltException(this); } } } @@ -1175,14 +1167,14 @@ public T accept(ParseTreeVisitor visitor) { public final DfPropertyNameContext dfPropertyName() throws RecognitionException { DfPropertyNameContext _localctx = new DfPropertyNameContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_dfPropertyName); + enterRule(_localctx, 26, RULE_dfPropertyName); int _la; try { enterOuterAlt(_localctx, 1); { - setState(286); + setState(282); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -1227,53 +1219,53 @@ public T accept(ParseTreeVisitor visitor) { public final ModuleImportContext moduleImport() throws RecognitionException { ModuleImportContext _localctx = new ModuleImportContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_moduleImport); + enterRule(_localctx, 28, RULE_moduleImport); int _la; try { enterOuterAlt(_localctx, 1); { - setState(288); - match(T__20); - setState(289); + setState(284); + match(T__19); + setState(285); match(T__1); - setState(293); + setState(289); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__2) { { - setState(290); + setState(286); match(T__2); - setState(291); + setState(287); ((ModuleImportContext)_localctx).prefix = match(NCName); - setState(292); + setState(288); match(T__3); } } - setState(295); + setState(291); ((ModuleImportContext)_localctx).targetNamespace = uriLiteral(); - setState(305); + setState(301); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(296); + setState(292); match(Kat); - setState(297); + setState(293); uriLiteral(); - setState(302); + setState(298); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(298); - match(T__21); - setState(299); + setState(294); + match(T__20); + setState(295); uriLiteral(); } } - setState(304); + setState(300); _errHandler.sync(this); _la = _input.LA(1); } @@ -1318,55 +1310,55 @@ public T accept(ParseTreeVisitor visitor) { public final VarDeclContext varDecl() throws RecognitionException { VarDeclContext _localctx = new VarDeclContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_varDecl); + enterRule(_localctx, 30, RULE_varDecl); int _la; try { enterOuterAlt(_localctx, 1); { - setState(307); + setState(303); match(T__4); - setState(308); - match(T__22); - setState(309); + setState(304); + match(T__21); + setState(305); varRef(); - setState(312); + setState(308); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(310); + setState(306); match(Kas); - setState(311); + setState(307); sequenceType(); } } - setState(321); + setState(317); _errHandler.sync(this); switch (_input.LA(1)) { - case T__23: + case T__22: { { - setState(314); - match(T__23); - setState(315); + setState(310); + match(T__22); + setState(311); exprSingle(); } } break; - case T__24: + case T__23: { { - setState(316); - ((VarDeclContext)_localctx).external = match(T__24); - setState(319); + setState(312); + ((VarDeclContext)_localctx).external = match(T__23); + setState(315); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__23) { + if (_la==T__22) { { - setState(317); - match(T__23); - setState(318); + setState(313); + match(T__22); + setState(314); exprSingle(); } } @@ -1420,68 +1412,68 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionDeclContext functionDecl() throws RecognitionException { FunctionDeclContext _localctx = new FunctionDeclContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_functionDecl); + enterRule(_localctx, 32, RULE_functionDecl); int _la; try { enterOuterAlt(_localctx, 1); { - setState(323); + setState(319); match(T__4); - setState(324); - match(T__25); - setState(325); + setState(320); + match(T__24); + setState(321); ((FunctionDeclContext)_localctx).fn_name = qname(); - setState(326); - match(T__26); - setState(328); + setState(322); + match(T__25); + setState(324); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__31) { + if (_la==T__30) { { - setState(327); + setState(323); paramList(); } } - setState(330); - match(T__27); - setState(333); + setState(326); + match(T__26); + setState(329); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(331); + setState(327); match(Kas); - setState(332); + setState(328); ((FunctionDeclContext)_localctx).return_type = sequenceType(); } } - setState(341); + setState(337); _errHandler.sync(this); switch (_input.LA(1)) { - case T__28: + case T__27: { - setState(335); - match(T__28); - setState(337); + setState(331); + match(T__27); + setState(333); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(336); + setState(332); ((FunctionDeclContext)_localctx).fn_body = expr(); } } - setState(339); - match(T__29); + setState(335); + match(T__28); } break; - case T__24: + case T__23: { - setState(340); - match(T__24); + setState(336); + match(T__23); } break; default: @@ -1522,19 +1514,19 @@ public T accept(ParseTreeVisitor visitor) { public final TypeDeclContext typeDecl() throws RecognitionException { TypeDeclContext _localctx = new TypeDeclContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_typeDecl); + enterRule(_localctx, 34, RULE_typeDecl); try { enterOuterAlt(_localctx, 1); { - setState(343); + setState(339); match(T__4); - setState(344); - match(T__30); - setState(345); + setState(340); + match(T__29); + setState(341); ((TypeDeclContext)_localctx).type_name = qname(); - setState(346); + setState(342); match(Kas); - setState(347); + setState(343); ((TypeDeclContext)_localctx).type_definition = exprSingle(); } } @@ -1569,26 +1561,26 @@ public T accept(ParseTreeVisitor visitor) { public final ParamListContext paramList() throws RecognitionException { ParamListContext _localctx = new ParamListContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_paramList); + enterRule(_localctx, 36, RULE_paramList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(349); + setState(345); param(); - setState(354); + setState(350); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(350); - match(T__21); - setState(351); + setState(346); + match(T__20); + setState(347); param(); } } - setState(356); + setState(352); _errHandler.sync(this); _la = _input.LA(1); } @@ -1626,23 +1618,23 @@ public T accept(ParseTreeVisitor visitor) { public final ParamContext param() throws RecognitionException { ParamContext _localctx = new ParamContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_param); + enterRule(_localctx, 38, RULE_param); int _la; try { enterOuterAlt(_localctx, 1); { - setState(357); - match(T__31); - setState(358); + setState(353); + match(T__30); + setState(354); qname(); - setState(361); + setState(357); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(359); + setState(355); match(Kas); - setState(360); + setState(356); sequenceType(); } } @@ -1680,26 +1672,26 @@ public T accept(ParseTreeVisitor visitor) { public final ExprContext expr() throws RecognitionException { ExprContext _localctx = new ExprContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_expr); + enterRule(_localctx, 40, RULE_expr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(363); + setState(359); exprSingle(); - setState(368); + setState(364); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(364); - match(T__21); - setState(365); + setState(360); + match(T__20); + setState(361); exprSingle(); } } - setState(370); + setState(366); _errHandler.sync(this); _la = _input.LA(1); } @@ -1751,57 +1743,57 @@ public T accept(ParseTreeVisitor visitor) { public final ExprSingleContext exprSingle() throws RecognitionException { ExprSingleContext _localctx = new ExprSingleContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_exprSingle); + enterRule(_localctx, 42, RULE_exprSingle); try { - setState(378); + setState(374); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(371); + setState(367); flowrExpr(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(372); + setState(368); quantifiedExpr(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(373); + setState(369); switchExpr(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(374); + setState(370); typeSwitchExpr(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(375); + setState(371); ifExpr(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(376); + setState(372); tryCatchExpr(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(377); + setState(373); orExpr(); } break; @@ -1875,71 +1867,71 @@ public T accept(ParseTreeVisitor visitor) { public final FlowrExprContext flowrExpr() throws RecognitionException { FlowrExprContext _localctx = new FlowrExprContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_flowrExpr); + enterRule(_localctx, 44, RULE_flowrExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(382); + setState(378); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(380); + setState(376); ((FlowrExprContext)_localctx).start_for = forClause(); } break; case Klet: { - setState(381); + setState(377); ((FlowrExprContext)_localctx).start_let = letClause(); } break; default: throw new NoViableAltException(this); } - setState(392); + setState(388); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 61)) & ~0x3f) == 0 && ((1L << (_la - 61)) & ((1L << (Kfor - 61)) | (1L << (Klet - 61)) | (1L << (Kwhere - 61)) | (1L << (Kgroup - 61)) | (1L << (Korder - 61)) | (1L << (Kcount - 61)) | (1L << (Kstable - 61)))) != 0)) { + while (((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (Kfor - 60)) | (1L << (Klet - 60)) | (1L << (Kwhere - 60)) | (1L << (Kgroup - 60)) | (1L << (Korder - 60)) | (1L << (Kcount - 60)) | (1L << (Kstable - 60)))) != 0)) { { - setState(390); + setState(386); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(384); + setState(380); forClause(); } break; case Kwhere: { - setState(385); + setState(381); whereClause(); } break; case Klet: { - setState(386); + setState(382); letClause(); } break; case Kgroup: { - setState(387); + setState(383); groupByClause(); } break; case Korder: case Kstable: { - setState(388); + setState(384); orderByClause(); } break; case Kcount: { - setState(389); + setState(385); countClause(); } break; @@ -1947,13 +1939,13 @@ public final FlowrExprContext flowrExpr() throws RecognitionException { throw new NoViableAltException(this); } } - setState(394); + setState(390); _errHandler.sync(this); _la = _input.LA(1); } - setState(395); + setState(391); match(Kreturn); - setState(396); + setState(392); ((FlowrExprContext)_localctx).return_expr = exprSingle(); } } @@ -1991,30 +1983,30 @@ public T accept(ParseTreeVisitor visitor) { public final ForClauseContext forClause() throws RecognitionException { ForClauseContext _localctx = new ForClauseContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_forClause); + enterRule(_localctx, 46, RULE_forClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(398); + setState(394); match(Kfor); - setState(399); + setState(395); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); - setState(404); + setState(400); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(400); - match(T__21); - setState(401); + setState(396); + match(T__20); + setState(397); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); } } - setState(406); + setState(402); _errHandler.sync(this); _la = _input.LA(1); } @@ -2067,52 +2059,52 @@ public T accept(ParseTreeVisitor visitor) { public final ForVarContext forVar() throws RecognitionException { ForVarContext _localctx = new ForVarContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_forVar); + enterRule(_localctx, 48, RULE_forVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(407); + setState(403); ((ForVarContext)_localctx).var_ref = varRef(); - setState(410); + setState(406); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(408); + setState(404); match(Kas); - setState(409); + setState(405); ((ForVarContext)_localctx).seq = sequenceType(); } } - setState(414); + setState(410); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kallowing) { { - setState(412); + setState(408); ((ForVarContext)_localctx).flag = match(Kallowing); - setState(413); + setState(409); match(Kempty); } } - setState(418); + setState(414); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(416); + setState(412); match(Kat); - setState(417); + setState(413); ((ForVarContext)_localctx).at = varRef(); } } - setState(420); + setState(416); match(Kin); - setState(421); + setState(417); ((ForVarContext)_localctx).ex = exprSingle(); } } @@ -2150,30 +2142,30 @@ public T accept(ParseTreeVisitor visitor) { public final LetClauseContext letClause() throws RecognitionException { LetClauseContext _localctx = new LetClauseContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_letClause); + enterRule(_localctx, 50, RULE_letClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(423); + setState(419); match(Klet); - setState(424); + setState(420); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); - setState(429); + setState(425); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(425); - match(T__21); - setState(426); + setState(421); + match(T__20); + setState(422); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); } } - setState(431); + setState(427); _errHandler.sync(this); _la = _input.LA(1); } @@ -2217,28 +2209,28 @@ public T accept(ParseTreeVisitor visitor) { public final LetVarContext letVar() throws RecognitionException { LetVarContext _localctx = new LetVarContext(_ctx, getState()); - enterRule(_localctx, 54, RULE_letVar); + enterRule(_localctx, 52, RULE_letVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(432); + setState(428); ((LetVarContext)_localctx).var_ref = varRef(); - setState(435); + setState(431); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(433); + setState(429); match(Kas); - setState(434); + setState(430); ((LetVarContext)_localctx).seq = sequenceType(); } } - setState(437); - match(T__23); - setState(438); + setState(433); + match(T__22); + setState(434); ((LetVarContext)_localctx).ex = exprSingle(); } } @@ -2271,13 +2263,13 @@ public T accept(ParseTreeVisitor visitor) { public final WhereClauseContext whereClause() throws RecognitionException { WhereClauseContext _localctx = new WhereClauseContext(_ctx, getState()); - enterRule(_localctx, 56, RULE_whereClause); + enterRule(_localctx, 54, RULE_whereClause); try { enterOuterAlt(_localctx, 1); { - setState(440); + setState(436); match(Kwhere); - setState(441); + setState(437); exprSingle(); } } @@ -2316,32 +2308,32 @@ public T accept(ParseTreeVisitor visitor) { public final GroupByClauseContext groupByClause() throws RecognitionException { GroupByClauseContext _localctx = new GroupByClauseContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_groupByClause); + enterRule(_localctx, 56, RULE_groupByClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(443); + setState(439); match(Kgroup); - setState(444); + setState(440); match(Kby); - setState(445); + setState(441); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); - setState(450); + setState(446); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(446); - match(T__21); - setState(447); + setState(442); + match(T__20); + setState(443); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); } } - setState(452); + setState(448); _errHandler.sync(this); _la = _input.LA(1); } @@ -2391,45 +2383,45 @@ public T accept(ParseTreeVisitor visitor) { public final GroupByVarContext groupByVar() throws RecognitionException { GroupByVarContext _localctx = new GroupByVarContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_groupByVar); + enterRule(_localctx, 58, RULE_groupByVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(453); + setState(449); ((GroupByVarContext)_localctx).var_ref = varRef(); - setState(460); + setState(456); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__23 || _la==Kas) { + if (_la==T__22 || _la==Kas) { { - setState(456); + setState(452); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(454); + setState(450); match(Kas); - setState(455); + setState(451); ((GroupByVarContext)_localctx).seq = sequenceType(); } } - setState(458); - ((GroupByVarContext)_localctx).decl = match(T__23); - setState(459); + setState(454); + ((GroupByVarContext)_localctx).decl = match(T__22); + setState(455); ((GroupByVarContext)_localctx).ex = exprSingle(); } } - setState(464); + setState(460); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(462); + setState(458); match(Kcollation); - setState(463); + setState(459); ((GroupByVarContext)_localctx).uri = uriLiteral(); } } @@ -2471,20 +2463,20 @@ public T accept(ParseTreeVisitor visitor) { public final OrderByClauseContext orderByClause() throws RecognitionException { OrderByClauseContext _localctx = new OrderByClauseContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_orderByClause); + enterRule(_localctx, 60, RULE_orderByClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(471); + setState(467); _errHandler.sync(this); switch (_input.LA(1)) { case Korder: { { - setState(466); + setState(462); match(Korder); - setState(467); + setState(463); match(Kby); } } @@ -2492,11 +2484,11 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { case Kstable: { { - setState(468); + setState(464); ((OrderByClauseContext)_localctx).stb = match(Kstable); - setState(469); + setState(465); match(Korder); - setState(470); + setState(466); match(Kby); } } @@ -2504,21 +2496,21 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(473); + setState(469); orderByExpr(); - setState(478); + setState(474); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(474); - match(T__21); - setState(475); + setState(470); + match(T__20); + setState(471); orderByExpr(); } } - setState(480); + setState(476); _errHandler.sync(this); _la = _input.LA(1); } @@ -2566,29 +2558,29 @@ public T accept(ParseTreeVisitor visitor) { public final OrderByExprContext orderByExpr() throws RecognitionException { OrderByExprContext _localctx = new OrderByExprContext(_ctx, getState()); - enterRule(_localctx, 64, RULE_orderByExpr); + enterRule(_localctx, 62, RULE_orderByExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(481); + setState(477); ((OrderByExprContext)_localctx).ex = exprSingle(); - setState(484); + setState(480); _errHandler.sync(this); switch (_input.LA(1)) { case Kascending: { - setState(482); + setState(478); match(Kascending); } break; case Kdescending: { - setState(483); + setState(479); ((OrderByExprContext)_localctx).desc = match(Kdescending); } break; - case T__21: + case T__20: case Kfor: case Klet: case Kwhere: @@ -2603,25 +2595,25 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { default: break; } - setState(491); + setState(487); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kempty) { { - setState(486); + setState(482); match(Kempty); - setState(489); + setState(485); _errHandler.sync(this); switch (_input.LA(1)) { case Kgreatest: { - setState(487); + setState(483); ((OrderByExprContext)_localctx).gr = match(Kgreatest); } break; case Kleast: { - setState(488); + setState(484); ((OrderByExprContext)_localctx).ls = match(Kleast); } break; @@ -2631,14 +2623,14 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { } } - setState(495); + setState(491); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(493); + setState(489); match(Kcollation); - setState(494); + setState(490); ((OrderByExprContext)_localctx).uril = uriLiteral(); } } @@ -2674,13 +2666,13 @@ public T accept(ParseTreeVisitor visitor) { public final CountClauseContext countClause() throws RecognitionException { CountClauseContext _localctx = new CountClauseContext(_ctx, getState()); - enterRule(_localctx, 66, RULE_countClause); + enterRule(_localctx, 64, RULE_countClause); try { enterOuterAlt(_localctx, 1); { - setState(497); + setState(493); match(Kcount); - setState(498); + setState(494); varRef(); } } @@ -2725,52 +2717,52 @@ public T accept(ParseTreeVisitor visitor) { public final QuantifiedExprContext quantifiedExpr() throws RecognitionException { QuantifiedExprContext _localctx = new QuantifiedExprContext(_ctx, getState()); - enterRule(_localctx, 68, RULE_quantifiedExpr); + enterRule(_localctx, 66, RULE_quantifiedExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(502); + setState(498); _errHandler.sync(this); switch (_input.LA(1)) { case Ksome: { - setState(500); + setState(496); ((QuantifiedExprContext)_localctx).so = match(Ksome); } break; case Kevery: { - setState(501); + setState(497); ((QuantifiedExprContext)_localctx).ev = match(Kevery); } break; default: throw new NoViableAltException(this); } - setState(504); + setState(500); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); - setState(509); + setState(505); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(505); - match(T__21); - setState(506); + setState(501); + match(T__20); + setState(502); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); } } - setState(511); + setState(507); _errHandler.sync(this); _la = _input.LA(1); } - setState(512); + setState(508); match(Ksatisfies); - setState(513); + setState(509); exprSingle(); } } @@ -2810,28 +2802,28 @@ public T accept(ParseTreeVisitor visitor) { public final QuantifiedExprVarContext quantifiedExprVar() throws RecognitionException { QuantifiedExprVarContext _localctx = new QuantifiedExprVarContext(_ctx, getState()); - enterRule(_localctx, 70, RULE_quantifiedExprVar); + enterRule(_localctx, 68, RULE_quantifiedExprVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(515); + setState(511); varRef(); - setState(518); + setState(514); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(516); + setState(512); match(Kas); - setState(517); + setState(513); sequenceType(); } } - setState(520); + setState(516); match(Kin); - setState(521); + setState(517); exprSingle(); } } @@ -2879,39 +2871,39 @@ public T accept(ParseTreeVisitor visitor) { public final SwitchExprContext switchExpr() throws RecognitionException { SwitchExprContext _localctx = new SwitchExprContext(_ctx, getState()); - enterRule(_localctx, 72, RULE_switchExpr); + enterRule(_localctx, 70, RULE_switchExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(523); + setState(519); match(Kswitch); - setState(524); - match(T__26); - setState(525); + setState(520); + match(T__25); + setState(521); ((SwitchExprContext)_localctx).cond = expr(); - setState(526); - match(T__27); - setState(528); + setState(522); + match(T__26); + setState(524); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(527); + setState(523); ((SwitchExprContext)_localctx).switchCaseClause = switchCaseClause(); ((SwitchExprContext)_localctx).cases.add(((SwitchExprContext)_localctx).switchCaseClause); } } - setState(530); + setState(526); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(532); + setState(528); match(Kdefault); - setState(533); + setState(529); match(Kreturn); - setState(534); + setState(530); ((SwitchExprContext)_localctx).def = exprSingle(); } } @@ -2954,31 +2946,31 @@ public T accept(ParseTreeVisitor visitor) { public final SwitchCaseClauseContext switchCaseClause() throws RecognitionException { SwitchCaseClauseContext _localctx = new SwitchCaseClauseContext(_ctx, getState()); - enterRule(_localctx, 74, RULE_switchCaseClause); + enterRule(_localctx, 72, RULE_switchCaseClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(538); + setState(534); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(536); + setState(532); match(Kcase); - setState(537); + setState(533); ((SwitchCaseClauseContext)_localctx).exprSingle = exprSingle(); ((SwitchCaseClauseContext)_localctx).cond.add(((SwitchCaseClauseContext)_localctx).exprSingle); } } - setState(540); + setState(536); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(542); + setState(538); match(Kreturn); - setState(543); + setState(539); ((SwitchCaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3030,49 +3022,49 @@ public T accept(ParseTreeVisitor visitor) { public final TypeSwitchExprContext typeSwitchExpr() throws RecognitionException { TypeSwitchExprContext _localctx = new TypeSwitchExprContext(_ctx, getState()); - enterRule(_localctx, 76, RULE_typeSwitchExpr); + enterRule(_localctx, 74, RULE_typeSwitchExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(545); + setState(541); match(Ktypeswitch); - setState(546); - match(T__26); - setState(547); + setState(542); + match(T__25); + setState(543); ((TypeSwitchExprContext)_localctx).cond = expr(); - setState(548); - match(T__27); - setState(550); + setState(544); + match(T__26); + setState(546); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(549); + setState(545); ((TypeSwitchExprContext)_localctx).caseClause = caseClause(); ((TypeSwitchExprContext)_localctx).cses.add(((TypeSwitchExprContext)_localctx).caseClause); } } - setState(552); + setState(548); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(554); + setState(550); match(Kdefault); - setState(556); + setState(552); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__31) { + if (_la==T__30) { { - setState(555); + setState(551); ((TypeSwitchExprContext)_localctx).var_ref = varRef(); } } - setState(558); + setState(554); match(Kreturn); - setState(559); + setState(555); ((TypeSwitchExprContext)_localctx).def = exprSingle(); } } @@ -3120,48 +3112,48 @@ public T accept(ParseTreeVisitor visitor) { public final CaseClauseContext caseClause() throws RecognitionException { CaseClauseContext _localctx = new CaseClauseContext(_ctx, getState()); - enterRule(_localctx, 78, RULE_caseClause); + enterRule(_localctx, 76, RULE_caseClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(561); + setState(557); match(Kcase); - setState(565); + setState(561); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__31) { + if (_la==T__30) { { - setState(562); + setState(558); ((CaseClauseContext)_localctx).var_ref = varRef(); - setState(563); + setState(559); match(Kas); } } - setState(567); + setState(563); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); - setState(572); + setState(568); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__32) { + while (_la==T__31) { { { - setState(568); - match(T__32); - setState(569); + setState(564); + match(T__31); + setState(565); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); } } - setState(574); + setState(570); _errHandler.sync(this); _la = _input.LA(1); } - setState(575); + setState(571); match(Kreturn); - setState(576); + setState(572); ((CaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3205,25 +3197,25 @@ public T accept(ParseTreeVisitor visitor) { public final IfExprContext ifExpr() throws RecognitionException { IfExprContext _localctx = new IfExprContext(_ctx, getState()); - enterRule(_localctx, 80, RULE_ifExpr); + enterRule(_localctx, 78, RULE_ifExpr); try { enterOuterAlt(_localctx, 1); { - setState(578); + setState(574); match(Kif); - setState(579); - match(T__26); - setState(580); + setState(575); + match(T__25); + setState(576); ((IfExprContext)_localctx).test_condition = expr(); - setState(581); - match(T__27); - setState(582); + setState(577); + match(T__26); + setState(578); match(Kthen); - setState(583); + setState(579); ((IfExprContext)_localctx).branch = exprSingle(); - setState(584); + setState(580); match(Kelse); - setState(585); + setState(581); ((IfExprContext)_localctx).else_branch = exprSingle(); } } @@ -3265,20 +3257,20 @@ public T accept(ParseTreeVisitor visitor) { public final TryCatchExprContext tryCatchExpr() throws RecognitionException { TryCatchExprContext _localctx = new TryCatchExprContext(_ctx, getState()); - enterRule(_localctx, 82, RULE_tryCatchExpr); + enterRule(_localctx, 80, RULE_tryCatchExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(587); + setState(583); match(Ktry); - setState(588); - match(T__28); - setState(589); + setState(584); + match(T__27); + setState(585); ((TryCatchExprContext)_localctx).try_expression = expr(); - setState(590); - match(T__29); - setState(592); + setState(586); + match(T__28); + setState(588); _errHandler.sync(this); _alt = 1; do { @@ -3286,7 +3278,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { case 1: { { - setState(591); + setState(587); ((TryCatchExprContext)_localctx).catchClause = catchClause(); ((TryCatchExprContext)_localctx).catches.add(((TryCatchExprContext)_localctx).catchClause); } @@ -3295,7 +3287,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(594); + setState(590); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,54,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); @@ -3313,7 +3305,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { } public static class CatchClauseContext extends ParserRuleContext { - public Token s34; + public Token s33; public List jokers = new ArrayList(); public QnameContext qname; public List errors = new ArrayList(); @@ -3341,21 +3333,21 @@ public T accept(ParseTreeVisitor visitor) { public final CatchClauseContext catchClause() throws RecognitionException { CatchClauseContext _localctx = new CatchClauseContext(_ctx, getState()); - enterRule(_localctx, 84, RULE_catchClause); + enterRule(_localctx, 82, RULE_catchClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(596); + setState(592); match(Kcatch); - setState(599); + setState(595); _errHandler.sync(this); switch (_input.LA(1)) { - case T__33: + case T__32: { - setState(597); - ((CatchClauseContext)_localctx).s34 = match(T__33); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); + setState(593); + ((CatchClauseContext)_localctx).s33 = match(T__32); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s33); } break; case Kfor: @@ -3402,10 +3394,11 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: case NCName: { - setState(598); + setState(594); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3413,22 +3406,22 @@ public final CatchClauseContext catchClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(608); + setState(604); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__32) { + while (_la==T__31) { { { - setState(601); - match(T__32); - setState(604); + setState(597); + match(T__31); + setState(600); _errHandler.sync(this); switch (_input.LA(1)) { - case T__33: + case T__32: { - setState(602); - ((CatchClauseContext)_localctx).s34 = match(T__33); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); + setState(598); + ((CatchClauseContext)_localctx).s33 = match(T__32); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s33); } break; case Kfor: @@ -3475,10 +3468,11 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: case NCName: { - setState(603); + setState(599); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3488,16 +3482,16 @@ public final CatchClauseContext catchClause() throws RecognitionException { } } } - setState(610); + setState(606); _errHandler.sync(this); _la = _input.LA(1); } - setState(611); - match(T__28); - setState(612); + setState(607); + match(T__27); + setState(608); ((CatchClauseContext)_localctx).catch_expression = expr(); - setState(613); - match(T__29); + setState(609); + match(T__28); } } catch (RecognitionException re) { @@ -3538,29 +3532,29 @@ public T accept(ParseTreeVisitor visitor) { public final OrExprContext orExpr() throws RecognitionException { OrExprContext _localctx = new OrExprContext(_ctx, getState()); - enterRule(_localctx, 86, RULE_orExpr); + enterRule(_localctx, 84, RULE_orExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(615); + setState(611); ((OrExprContext)_localctx).main_expr = andExpr(); - setState(620); + setState(616); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,58,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(616); + setState(612); match(Kor); - setState(617); + setState(613); ((OrExprContext)_localctx).andExpr = andExpr(); ((OrExprContext)_localctx).rhs.add(((OrExprContext)_localctx).andExpr); } } } - setState(622); + setState(618); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,58,_ctx); } @@ -3604,29 +3598,29 @@ public T accept(ParseTreeVisitor visitor) { public final AndExprContext andExpr() throws RecognitionException { AndExprContext _localctx = new AndExprContext(_ctx, getState()); - enterRule(_localctx, 88, RULE_andExpr); + enterRule(_localctx, 86, RULE_andExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(623); + setState(619); ((AndExprContext)_localctx).main_expr = notExpr(); - setState(628); + setState(624); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(624); + setState(620); match(Kand); - setState(625); + setState(621); ((AndExprContext)_localctx).notExpr = notExpr(); ((AndExprContext)_localctx).rhs.add(((AndExprContext)_localctx).notExpr); } } } - setState(630); + setState(626); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); } @@ -3664,22 +3658,22 @@ public T accept(ParseTreeVisitor visitor) { public final NotExprContext notExpr() throws RecognitionException { NotExprContext _localctx = new NotExprContext(_ctx, getState()); - enterRule(_localctx, 90, RULE_notExpr); + enterRule(_localctx, 88, RULE_notExpr); try { enterOuterAlt(_localctx, 1); { - setState(632); + setState(628); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,60,_ctx) ) { case 1: { - setState(631); + setState(627); ((NotExprContext)_localctx).Knot = match(Knot); ((NotExprContext)_localctx).op.add(((NotExprContext)_localctx).Knot); } break; } - setState(634); + setState(630); ((NotExprContext)_localctx).main_expr = comparisonExpr(); } } @@ -3696,20 +3690,20 @@ public final NotExprContext notExpr() throws RecognitionException { public static class ComparisonExprContext extends ParserRuleContext { public StringConcatExprContext main_expr; - public Token s35; + public Token s34; public List op = new ArrayList(); + public Token s35; public Token s36; public Token s37; public Token s38; public Token s39; - public Token s40; public Token s4; + public Token s40; public Token s41; public Token s42; public Token s43; public Token s44; - public Token s45; - public Token _tset1194; + public Token _tset1183; public StringConcatExprContext stringConcatExpr; public List rhs = new ArrayList(); public List stringConcatExpr() { @@ -3731,31 +3725,31 @@ public T accept(ParseTreeVisitor visitor) { public final ComparisonExprContext comparisonExpr() throws RecognitionException { ComparisonExprContext _localctx = new ComparisonExprContext(_ctx, getState()); - enterRule(_localctx, 92, RULE_comparisonExpr); + enterRule(_localctx, 90, RULE_comparisonExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(636); + setState(632); ((ComparisonExprContext)_localctx).main_expr = stringConcatExpr(); - setState(639); + setState(635); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) { { - setState(637); - ((ComparisonExprContext)_localctx)._tset1194 = _input.LT(1); + setState(633); + ((ComparisonExprContext)_localctx)._tset1183 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44))) != 0)) ) { - ((ComparisonExprContext)_localctx)._tset1194 = (Token)_errHandler.recoverInline(this); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) ) { + ((ComparisonExprContext)_localctx)._tset1183 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1194); - setState(638); + ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1183); + setState(634); ((ComparisonExprContext)_localctx).stringConcatExpr = stringConcatExpr(); ((ComparisonExprContext)_localctx).rhs.add(((ComparisonExprContext)_localctx).stringConcatExpr); } @@ -3797,27 +3791,27 @@ public T accept(ParseTreeVisitor visitor) { public final StringConcatExprContext stringConcatExpr() throws RecognitionException { StringConcatExprContext _localctx = new StringConcatExprContext(_ctx, getState()); - enterRule(_localctx, 94, RULE_stringConcatExpr); + enterRule(_localctx, 92, RULE_stringConcatExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(641); + setState(637); ((StringConcatExprContext)_localctx).main_expr = rangeExpr(); - setState(646); + setState(642); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__45) { + while (_la==T__44) { { { - setState(642); - match(T__45); - setState(643); + setState(638); + match(T__44); + setState(639); ((StringConcatExprContext)_localctx).rangeExpr = rangeExpr(); ((StringConcatExprContext)_localctx).rhs.add(((StringConcatExprContext)_localctx).rangeExpr); } } - setState(648); + setState(644); _errHandler.sync(this); _la = _input.LA(1); } @@ -3858,20 +3852,20 @@ public T accept(ParseTreeVisitor visitor) { public final RangeExprContext rangeExpr() throws RecognitionException { RangeExprContext _localctx = new RangeExprContext(_ctx, getState()); - enterRule(_localctx, 96, RULE_rangeExpr); + enterRule(_localctx, 94, RULE_rangeExpr); try { enterOuterAlt(_localctx, 1); { - setState(649); + setState(645); ((RangeExprContext)_localctx).main_expr = additiveExpr(); - setState(652); + setState(648); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,63,_ctx) ) { case 1: { - setState(650); + setState(646); match(Kto); - setState(651); + setState(647); ((RangeExprContext)_localctx).additiveExpr = additiveExpr(); ((RangeExprContext)_localctx).rhs.add(((RangeExprContext)_localctx).additiveExpr); } @@ -3892,10 +3886,10 @@ public final RangeExprContext rangeExpr() throws RecognitionException { public static class AdditiveExprContext extends ParserRuleContext { public MultiplicativeExprContext main_expr; - public Token s47; + public Token s46; public List op = new ArrayList(); - public Token s48; - public Token _tset1303; + public Token s47; + public Token _tset1292; public MultiplicativeExprContext multiplicativeExpr; public List rhs = new ArrayList(); public List multiplicativeExpr() { @@ -3917,40 +3911,40 @@ public T accept(ParseTreeVisitor visitor) { public final AdditiveExprContext additiveExpr() throws RecognitionException { AdditiveExprContext _localctx = new AdditiveExprContext(_ctx, getState()); - enterRule(_localctx, 98, RULE_additiveExpr); + enterRule(_localctx, 96, RULE_additiveExpr); int _la; try { int _alt; enterOuterAlt(_localctx, 1); { - setState(654); + setState(650); ((AdditiveExprContext)_localctx).main_expr = multiplicativeExpr(); - setState(659); + setState(655); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,64,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(655); - ((AdditiveExprContext)_localctx)._tset1303 = _input.LT(1); + setState(651); + ((AdditiveExprContext)_localctx)._tset1292 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__46 || _la==T__47) ) { - ((AdditiveExprContext)_localctx)._tset1303 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__45 || _la==T__46) ) { + ((AdditiveExprContext)_localctx)._tset1292 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1303); - setState(656); + ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1292); + setState(652); ((AdditiveExprContext)_localctx).multiplicativeExpr = multiplicativeExpr(); ((AdditiveExprContext)_localctx).rhs.add(((AdditiveExprContext)_localctx).multiplicativeExpr); } } } - setState(661); + setState(657); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,64,_ctx); } @@ -3969,12 +3963,12 @@ public final AdditiveExprContext additiveExpr() throws RecognitionException { public static class MultiplicativeExprContext extends ParserRuleContext { public InstanceOfExprContext main_expr; - public Token s34; + public Token s33; public List op = new ArrayList(); + public Token s48; public Token s49; public Token s50; - public Token s51; - public Token _tset1331; + public Token _tset1320; public InstanceOfExprContext instanceOfExpr; public List rhs = new ArrayList(); public List instanceOfExpr() { @@ -3996,37 +3990,37 @@ public T accept(ParseTreeVisitor visitor) { public final MultiplicativeExprContext multiplicativeExpr() throws RecognitionException { MultiplicativeExprContext _localctx = new MultiplicativeExprContext(_ctx, getState()); - enterRule(_localctx, 100, RULE_multiplicativeExpr); + enterRule(_localctx, 98, RULE_multiplicativeExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(662); + setState(658); ((MultiplicativeExprContext)_localctx).main_expr = instanceOfExpr(); - setState(667); + setState(663); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__49))) != 0)) { { { - setState(663); - ((MultiplicativeExprContext)_localctx)._tset1331 = _input.LT(1); + setState(659); + ((MultiplicativeExprContext)_localctx)._tset1320 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) ) { - ((MultiplicativeExprContext)_localctx)._tset1331 = (Token)_errHandler.recoverInline(this); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__49))) != 0)) ) { + ((MultiplicativeExprContext)_localctx)._tset1320 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1331); - setState(664); + ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1320); + setState(660); ((MultiplicativeExprContext)_localctx).instanceOfExpr = instanceOfExpr(); ((MultiplicativeExprContext)_localctx).rhs.add(((MultiplicativeExprContext)_localctx).instanceOfExpr); } } - setState(669); + setState(665); _errHandler.sync(this); _la = _input.LA(1); } @@ -4067,22 +4061,22 @@ public T accept(ParseTreeVisitor visitor) { public final InstanceOfExprContext instanceOfExpr() throws RecognitionException { InstanceOfExprContext _localctx = new InstanceOfExprContext(_ctx, getState()); - enterRule(_localctx, 102, RULE_instanceOfExpr); + enterRule(_localctx, 100, RULE_instanceOfExpr); try { enterOuterAlt(_localctx, 1); { - setState(670); + setState(666); ((InstanceOfExprContext)_localctx).main_expr = isStaticallyExpr(); - setState(674); + setState(670); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,66,_ctx) ) { case 1: { - setState(671); + setState(667); match(Kinstance); - setState(672); + setState(668); match(Kof); - setState(673); + setState(669); ((InstanceOfExprContext)_localctx).seq = sequenceType(); } break; @@ -4124,22 +4118,22 @@ public T accept(ParseTreeVisitor visitor) { public final IsStaticallyExprContext isStaticallyExpr() throws RecognitionException { IsStaticallyExprContext _localctx = new IsStaticallyExprContext(_ctx, getState()); - enterRule(_localctx, 104, RULE_isStaticallyExpr); + enterRule(_localctx, 102, RULE_isStaticallyExpr); try { enterOuterAlt(_localctx, 1); { - setState(676); + setState(672); ((IsStaticallyExprContext)_localctx).main_expr = treatExpr(); - setState(680); + setState(676); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,67,_ctx) ) { case 1: { - setState(677); + setState(673); match(Kis); - setState(678); + setState(674); match(Kstatically); - setState(679); + setState(675); ((IsStaticallyExprContext)_localctx).seq = sequenceType(); } break; @@ -4181,22 +4175,22 @@ public T accept(ParseTreeVisitor visitor) { public final TreatExprContext treatExpr() throws RecognitionException { TreatExprContext _localctx = new TreatExprContext(_ctx, getState()); - enterRule(_localctx, 106, RULE_treatExpr); + enterRule(_localctx, 104, RULE_treatExpr); try { enterOuterAlt(_localctx, 1); { - setState(682); + setState(678); ((TreatExprContext)_localctx).main_expr = castableExpr(); - setState(686); + setState(682); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { case 1: { - setState(683); + setState(679); match(Ktreat); - setState(684); + setState(680); match(Kas); - setState(685); + setState(681); ((TreatExprContext)_localctx).seq = sequenceType(); } break; @@ -4238,22 +4232,22 @@ public T accept(ParseTreeVisitor visitor) { public final CastableExprContext castableExpr() throws RecognitionException { CastableExprContext _localctx = new CastableExprContext(_ctx, getState()); - enterRule(_localctx, 108, RULE_castableExpr); + enterRule(_localctx, 106, RULE_castableExpr); try { enterOuterAlt(_localctx, 1); { - setState(688); + setState(684); ((CastableExprContext)_localctx).main_expr = castExpr(); - setState(692); + setState(688); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,69,_ctx) ) { case 1: { - setState(689); + setState(685); match(Kcastable); - setState(690); + setState(686); match(Kas); - setState(691); + setState(687); ((CastableExprContext)_localctx).single = singleType(); } break; @@ -4295,22 +4289,22 @@ public T accept(ParseTreeVisitor visitor) { public final CastExprContext castExpr() throws RecognitionException { CastExprContext _localctx = new CastExprContext(_ctx, getState()); - enterRule(_localctx, 110, RULE_castExpr); + enterRule(_localctx, 108, RULE_castExpr); try { enterOuterAlt(_localctx, 1); { - setState(694); + setState(690); ((CastExprContext)_localctx).main_expr = arrowExpr(); - setState(698); + setState(694); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,70,_ctx) ) { case 1: { - setState(695); + setState(691); match(Kcast); - setState(696); + setState(692); match(Kas); - setState(697); + setState(693); ((CastExprContext)_localctx).single = singleType(); } break; @@ -4354,14 +4348,14 @@ public T accept(ParseTreeVisitor visitor) { public final ArrowExprContext arrowExpr() throws RecognitionException { ArrowExprContext _localctx = new ArrowExprContext(_ctx, getState()); - enterRule(_localctx, 112, RULE_arrowExpr); + enterRule(_localctx, 110, RULE_arrowExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(700); + setState(696); ((ArrowExprContext)_localctx).main_expr = unaryExpr(); - setState(707); + setState(703); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -4369,18 +4363,18 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { { { { - setState(701); + setState(697); match(T__3); - setState(702); - match(T__43); + setState(698); + match(T__42); } - setState(704); + setState(700); ((ArrowExprContext)_localctx).functionCall = functionCall(); ((ArrowExprContext)_localctx).function_call_expr.add(((ArrowExprContext)_localctx).functionCall); } } } - setState(709); + setState(705); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); } @@ -4398,10 +4392,10 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { } public static class UnaryExprContext extends ParserRuleContext { - public Token s48; - public List op = new ArrayList(); public Token s47; - public Token _tset1491; + public List op = new ArrayList(); + public Token s46; + public Token _tset1480; public ValueExprContext main_expr; public ValueExprContext valueExpr() { return getRuleContext(ValueExprContext.class,0); @@ -4419,36 +4413,36 @@ public T accept(ParseTreeVisitor visitor) { public final UnaryExprContext unaryExpr() throws RecognitionException { UnaryExprContext _localctx = new UnaryExprContext(_ctx, getState()); - enterRule(_localctx, 114, RULE_unaryExpr); + enterRule(_localctx, 112, RULE_unaryExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(713); + setState(709); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__46 || _la==T__47) { + while (_la==T__45 || _la==T__46) { { { - setState(710); - ((UnaryExprContext)_localctx)._tset1491 = _input.LT(1); + setState(706); + ((UnaryExprContext)_localctx)._tset1480 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__46 || _la==T__47) ) { - ((UnaryExprContext)_localctx)._tset1491 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__45 || _la==T__46) ) { + ((UnaryExprContext)_localctx)._tset1480 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1491); + ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1480); } } - setState(715); + setState(711); _errHandler.sync(this); _la = _input.LA(1); } - setState(716); + setState(712); ((UnaryExprContext)_localctx).main_expr = valueExpr(); } } @@ -4485,20 +4479,19 @@ public T accept(ParseTreeVisitor visitor) { public final ValueExprContext valueExpr() throws RecognitionException { ValueExprContext _localctx = new ValueExprContext(_ctx, getState()); - enterRule(_localctx, 116, RULE_valueExpr); + enterRule(_localctx, 114, RULE_valueExpr); try { - setState(720); + setState(716); _errHandler.sync(this); switch (_input.LA(1)) { case T__6: - case T__7: + case T__24: case T__25: - case T__26: - case T__28: - case T__31: - case T__53: - case T__56: - case T__58: + case T__27: + case T__30: + case T__52: + case T__55: + case T__57: case Kfor: case Klet: case Kwhere: @@ -4543,20 +4536,21 @@ public final ValueExprContext valueExpr() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(718); + setState(714); ((ValueExprContext)_localctx).simpleMap_expr = simpleMapExpr(); } break; - case T__51: + case T__50: enterOuterAlt(_localctx, 2); { - setState(719); + setState(715); ((ValueExprContext)_localctx).validate_expr = validateExpr(); } break; @@ -4595,22 +4589,22 @@ public T accept(ParseTreeVisitor visitor) { public final ValidateExprContext validateExpr() throws RecognitionException { ValidateExprContext _localctx = new ValidateExprContext(_ctx, getState()); - enterRule(_localctx, 118, RULE_validateExpr); + enterRule(_localctx, 116, RULE_validateExpr); try { enterOuterAlt(_localctx, 1); { + setState(718); + match(T__50); + setState(719); + match(T__29); + setState(720); + sequenceType(); + setState(721); + match(T__27); setState(722); - match(T__51); + expr(); setState(723); - match(T__30); - setState(724); - sequenceType(); - setState(725); match(T__28); - setState(726); - expr(); - setState(727); - match(T__29); } } catch (RecognitionException re) { @@ -4647,27 +4641,27 @@ public T accept(ParseTreeVisitor visitor) { public final SimpleMapExprContext simpleMapExpr() throws RecognitionException { SimpleMapExprContext _localctx = new SimpleMapExprContext(_ctx, getState()); - enterRule(_localctx, 120, RULE_simpleMapExpr); + enterRule(_localctx, 118, RULE_simpleMapExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(729); + setState(725); ((SimpleMapExprContext)_localctx).main_expr = postFixExpr(); - setState(734); + setState(730); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__52) { + while (_la==T__51) { { { - setState(730); - match(T__52); - setState(731); + setState(726); + match(T__51); + setState(727); ((SimpleMapExprContext)_localctx).postFixExpr = postFixExpr(); ((SimpleMapExprContext)_localctx).map_expr.add(((SimpleMapExprContext)_localctx).postFixExpr); } } - setState(736); + setState(732); _errHandler.sync(this); _la = _input.LA(1); } @@ -4732,56 +4726,56 @@ public T accept(ParseTreeVisitor visitor) { public final PostFixExprContext postFixExpr() throws RecognitionException { PostFixExprContext _localctx = new PostFixExprContext(_ctx, getState()); - enterRule(_localctx, 122, RULE_postFixExpr); + enterRule(_localctx, 120, RULE_postFixExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(737); + setState(733); ((PostFixExprContext)_localctx).main_expr = primaryExpr(); - setState(745); + setState(741); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { - setState(743); + setState(739); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,75,_ctx) ) { case 1: { - setState(738); + setState(734); arrayLookup(); } break; case 2: { - setState(739); + setState(735); predicate(); } break; case 3: { - setState(740); + setState(736); objectLookup(); } break; case 4: { - setState(741); + setState(737); arrayUnboxing(); } break; case 5: { - setState(742); + setState(738); argumentList(); } break; } } } - setState(747); + setState(743); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); } @@ -4815,20 +4809,20 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayLookupContext arrayLookup() throws RecognitionException { ArrayLookupContext _localctx = new ArrayLookupContext(_ctx, getState()); - enterRule(_localctx, 124, RULE_arrayLookup); + enterRule(_localctx, 122, RULE_arrayLookup); try { enterOuterAlt(_localctx, 1); { - setState(748); + setState(744); + match(T__52); + setState(745); + match(T__52); + setState(746); + expr(); + setState(747); match(T__53); - setState(749); + setState(748); match(T__53); - setState(750); - expr(); - setState(751); - match(T__54); - setState(752); - match(T__54); } } catch (RecognitionException re) { @@ -4856,14 +4850,14 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayUnboxingContext arrayUnboxing() throws RecognitionException { ArrayUnboxingContext _localctx = new ArrayUnboxingContext(_ctx, getState()); - enterRule(_localctx, 126, RULE_arrayUnboxing); + enterRule(_localctx, 124, RULE_arrayUnboxing); try { enterOuterAlt(_localctx, 1); { - setState(754); + setState(750); + match(T__52); + setState(751); match(T__53); - setState(755); - match(T__54); } } catch (RecognitionException re) { @@ -4894,16 +4888,16 @@ public T accept(ParseTreeVisitor visitor) { public final PredicateContext predicate() throws RecognitionException { PredicateContext _localctx = new PredicateContext(_ctx, getState()); - enterRule(_localctx, 128, RULE_predicate); + enterRule(_localctx, 126, RULE_predicate); try { enterOuterAlt(_localctx, 1); { - setState(757); - match(T__53); - setState(758); + setState(753); + match(T__52); + setState(754); expr(); - setState(759); - match(T__54); + setState(755); + match(T__53); } } catch (RecognitionException re) { @@ -4953,13 +4947,13 @@ public T accept(ParseTreeVisitor visitor) { public final ObjectLookupContext objectLookup() throws RecognitionException { ObjectLookupContext _localctx = new ObjectLookupContext(_ctx, getState()); - enterRule(_localctx, 130, RULE_objectLookup); + enterRule(_localctx, 128, RULE_objectLookup); try { enterOuterAlt(_localctx, 1); { - setState(761); - match(T__55); - setState(768); + setState(757); + match(T__54); + setState(764); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -5006,39 +5000,40 @@ public final ObjectLookupContext objectLookup() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: { - setState(762); + setState(758); ((ObjectLookupContext)_localctx).kw = keyWords(); } break; case STRING: { - setState(763); + setState(759); ((ObjectLookupContext)_localctx).lt = stringLiteral(); } break; case NCName: { - setState(764); + setState(760); ((ObjectLookupContext)_localctx).nc = match(NCName); } break; - case T__26: + case T__25: { - setState(765); + setState(761); ((ObjectLookupContext)_localctx).pe = parenthesizedExpr(); } break; - case T__31: + case T__30: { - setState(766); + setState(762); ((ObjectLookupContext)_localctx).vr = varRef(); } break; - case T__56: + case T__55: { - setState(767); + setState(763); ((ObjectLookupContext)_localctx).ci = contextItemExpr(); } break; @@ -5104,92 +5099,92 @@ public T accept(ParseTreeVisitor visitor) { public final PrimaryExprContext primaryExpr() throws RecognitionException { PrimaryExprContext _localctx = new PrimaryExprContext(_ctx, getState()); - enterRule(_localctx, 132, RULE_primaryExpr); + enterRule(_localctx, 130, RULE_primaryExpr); try { - setState(782); + setState(778); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,78,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(770); + setState(766); match(NullLiteral); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(771); + setState(767); match(Literal); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(772); + setState(768); stringLiteral(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(773); + setState(769); varRef(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(774); + setState(770); parenthesizedExpr(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(775); + setState(771); contextItemExpr(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(776); + setState(772); objectConstructor(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(777); + setState(773); functionCall(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(778); + setState(774); orderedExpr(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(779); + setState(775); unorderedExpr(); } break; case 11: enterOuterAlt(_localctx, 11); { - setState(780); + setState(776); arrayConstructor(); } break; case 12: enterOuterAlt(_localctx, 12); { - setState(781); + setState(777); functionItemExpr(); } break; @@ -5224,13 +5219,13 @@ public T accept(ParseTreeVisitor visitor) { public final VarRefContext varRef() throws RecognitionException { VarRefContext _localctx = new VarRefContext(_ctx, getState()); - enterRule(_localctx, 134, RULE_varRef); + enterRule(_localctx, 132, RULE_varRef); try { enterOuterAlt(_localctx, 1); { - setState(784); - match(T__31); - setState(785); + setState(780); + match(T__30); + setState(781); ((VarRefContext)_localctx).var_name = qname(); } } @@ -5262,25 +5257,25 @@ public T accept(ParseTreeVisitor visitor) { public final ParenthesizedExprContext parenthesizedExpr() throws RecognitionException { ParenthesizedExprContext _localctx = new ParenthesizedExprContext(_ctx, getState()); - enterRule(_localctx, 136, RULE_parenthesizedExpr); + enterRule(_localctx, 134, RULE_parenthesizedExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(787); - match(T__26); - setState(789); + setState(783); + match(T__25); + setState(785); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(788); + setState(784); expr(); } } - setState(791); - match(T__27); + setState(787); + match(T__26); } } catch (RecognitionException re) { @@ -5308,12 +5303,12 @@ public T accept(ParseTreeVisitor visitor) { public final ContextItemExprContext contextItemExpr() throws RecognitionException { ContextItemExprContext _localctx = new ContextItemExprContext(_ctx, getState()); - enterRule(_localctx, 138, RULE_contextItemExpr); + enterRule(_localctx, 136, RULE_contextItemExpr); try { enterOuterAlt(_localctx, 1); { - setState(793); - match(T__56); + setState(789); + match(T__55); } } catch (RecognitionException re) { @@ -5344,18 +5339,18 @@ public T accept(ParseTreeVisitor visitor) { public final OrderedExprContext orderedExpr() throws RecognitionException { OrderedExprContext _localctx = new OrderedExprContext(_ctx, getState()); - enterRule(_localctx, 140, RULE_orderedExpr); + enterRule(_localctx, 138, RULE_orderedExpr); try { enterOuterAlt(_localctx, 1); { - setState(795); + setState(791); match(T__6); - setState(796); - match(T__28); - setState(797); + setState(792); + match(T__27); + setState(793); expr(); - setState(798); - match(T__29); + setState(794); + match(T__28); } } catch (RecognitionException re) { @@ -5386,18 +5381,18 @@ public T accept(ParseTreeVisitor visitor) { public final UnorderedExprContext unorderedExpr() throws RecognitionException { UnorderedExprContext _localctx = new UnorderedExprContext(_ctx, getState()); - enterRule(_localctx, 142, RULE_unorderedExpr); + enterRule(_localctx, 140, RULE_unorderedExpr); try { enterOuterAlt(_localctx, 1); { - setState(800); - match(T__7); - setState(801); - match(T__28); - setState(802); + setState(796); + match(Kunordered); + setState(797); + match(T__27); + setState(798); expr(); - setState(803); - match(T__29); + setState(799); + match(T__28); } } catch (RecognitionException re) { @@ -5432,13 +5427,13 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionCallContext functionCall() throws RecognitionException { FunctionCallContext _localctx = new FunctionCallContext(_ctx, getState()); - enterRule(_localctx, 144, RULE_functionCall); + enterRule(_localctx, 142, RULE_functionCall); try { enterOuterAlt(_localctx, 1); { - setState(805); + setState(801); ((FunctionCallContext)_localctx).fn_name = qname(); - setState(806); + setState(802); argumentList(); } } @@ -5475,40 +5470,40 @@ public T accept(ParseTreeVisitor visitor) { public final ArgumentListContext argumentList() throws RecognitionException { ArgumentListContext _localctx = new ArgumentListContext(_ctx, getState()); - enterRule(_localctx, 146, RULE_argumentList); + enterRule(_localctx, 144, RULE_argumentList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(808); - match(T__26); - setState(815); + setState(804); + match(T__25); + setState(811); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (ArgumentPlaceholder - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (ArgumentPlaceholder - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { { - setState(809); + setState(805); ((ArgumentListContext)_localctx).argument = argument(); ((ArgumentListContext)_localctx).args.add(((ArgumentListContext)_localctx).argument); - setState(811); + setState(807); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__21) { + if (_la==T__20) { { - setState(810); - match(T__21); + setState(806); + match(T__20); } } } } - setState(817); + setState(813); _errHandler.sync(this); _la = _input.LA(1); } - setState(818); - match(T__27); + setState(814); + match(T__26); } } catch (RecognitionException re) { @@ -5540,23 +5535,22 @@ public T accept(ParseTreeVisitor visitor) { public final ArgumentContext argument() throws RecognitionException { ArgumentContext _localctx = new ArgumentContext(_ctx, getState()); - enterRule(_localctx, 148, RULE_argument); + enterRule(_localctx, 146, RULE_argument); try { - setState(822); + setState(818); _errHandler.sync(this); switch (_input.LA(1)) { case T__6: - case T__7: + case T__24: case T__25: - case T__26: - case T__28: - case T__31: + case T__27: + case T__30: + case T__45: case T__46: - case T__47: - case T__51: - case T__53: - case T__56: - case T__58: + case T__50: + case T__52: + case T__55: + case T__57: case Kfor: case Klet: case Kwhere: @@ -5601,20 +5595,21 @@ public final ArgumentContext argument() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(820); + setState(816); exprSingle(); } break; case ArgumentPlaceholder: enterOuterAlt(_localctx, 2); { - setState(821); + setState(817); match(ArgumentPlaceholder); } break; @@ -5653,9 +5648,9 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionItemExprContext functionItemExpr() throws RecognitionException { FunctionItemExprContext _localctx = new FunctionItemExprContext(_ctx, getState()); - enterRule(_localctx, 150, RULE_functionItemExpr); + enterRule(_localctx, 148, RULE_functionItemExpr); try { - setState(826); + setState(822); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -5702,18 +5697,19 @@ public final FunctionItemExprContext functionItemExpr() throws RecognitionExcept case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: case NCName: enterOuterAlt(_localctx, 1); { - setState(824); + setState(820); namedFunctionRef(); } break; - case T__25: + case T__24: enterOuterAlt(_localctx, 2); { - setState(825); + setState(821); inlineFunctionExpr(); } break; @@ -5752,15 +5748,15 @@ public T accept(ParseTreeVisitor visitor) { public final NamedFunctionRefContext namedFunctionRef() throws RecognitionException { NamedFunctionRefContext _localctx = new NamedFunctionRefContext(_ctx, getState()); - enterRule(_localctx, 152, RULE_namedFunctionRef); + enterRule(_localctx, 150, RULE_namedFunctionRef); try { enterOuterAlt(_localctx, 1); { - setState(828); + setState(824); ((NamedFunctionRefContext)_localctx).fn_name = qname(); - setState(829); - match(T__57); - setState(830); + setState(825); + match(T__56); + setState(826); ((NamedFunctionRefContext)_localctx).arity = match(Literal); } } @@ -5801,54 +5797,54 @@ public T accept(ParseTreeVisitor visitor) { public final InlineFunctionExprContext inlineFunctionExpr() throws RecognitionException { InlineFunctionExprContext _localctx = new InlineFunctionExprContext(_ctx, getState()); - enterRule(_localctx, 154, RULE_inlineFunctionExpr); + enterRule(_localctx, 152, RULE_inlineFunctionExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(832); + setState(828); + match(T__24); + setState(829); match(T__25); - setState(833); - match(T__26); - setState(835); + setState(831); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__31) { + if (_la==T__30) { { - setState(834); + setState(830); paramList(); } } - setState(837); - match(T__27); - setState(840); + setState(833); + match(T__26); + setState(836); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(838); + setState(834); match(Kas); - setState(839); + setState(835); ((InlineFunctionExprContext)_localctx).return_type = sequenceType(); } } { - setState(842); - match(T__28); - setState(844); + setState(838); + match(T__27); + setState(840); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(843); + setState(839); ((InlineFunctionExprContext)_localctx).fn_body = expr(); } } - setState(846); - match(T__29); + setState(842); + match(T__28); } } } @@ -5867,9 +5863,9 @@ public static class SequenceTypeContext extends ParserRuleContext { public ItemTypeContext item; public Token s106; public List question = new ArrayList(); - public Token s34; + public Token s33; public List star = new ArrayList(); - public Token s47; + public Token s46; public List plus = new ArrayList(); public ItemTypeContext itemType() { return getRuleContext(ItemTypeContext.class,0); @@ -5887,21 +5883,21 @@ public T accept(ParseTreeVisitor visitor) { public final SequenceTypeContext sequenceType() throws RecognitionException { SequenceTypeContext _localctx = new SequenceTypeContext(_ctx, getState()); - enterRule(_localctx, 156, RULE_sequenceType); + enterRule(_localctx, 154, RULE_sequenceType); try { - setState(856); + setState(852); _errHandler.sync(this); switch (_input.LA(1)) { - case T__26: + case T__25: enterOuterAlt(_localctx, 1); { - setState(848); + setState(844); + match(T__25); + setState(845); match(T__26); - setState(849); - match(T__27); } break; - case T__25: + case T__24: case Kfor: case Klet: case Kwhere: @@ -5946,34 +5942,35 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: + case Kunordered: case NullLiteral: case NCName: enterOuterAlt(_localctx, 2); { - setState(850); + setState(846); ((SequenceTypeContext)_localctx).item = itemType(); - setState(854); + setState(850); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,87,_ctx) ) { case 1: { - setState(851); + setState(847); ((SequenceTypeContext)_localctx).s106 = match(ArgumentPlaceholder); ((SequenceTypeContext)_localctx).question.add(((SequenceTypeContext)_localctx).s106); } break; case 2: { - setState(852); - ((SequenceTypeContext)_localctx).s34 = match(T__33); - ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s34); + setState(848); + ((SequenceTypeContext)_localctx).s33 = match(T__32); + ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s33); } break; case 3: { - setState(853); - ((SequenceTypeContext)_localctx).s47 = match(T__46); - ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s47); + setState(849); + ((SequenceTypeContext)_localctx).s46 = match(T__45); + ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s46); } break; } @@ -5995,7 +5992,7 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { } public static class ObjectConstructorContext extends ParserRuleContext { - public Token s59; + public Token s58; public List merge_operator = new ArrayList(); public List pairConstructor() { return getRuleContexts(PairConstructorContext.class); @@ -6019,57 +6016,57 @@ public T accept(ParseTreeVisitor visitor) { public final ObjectConstructorContext objectConstructor() throws RecognitionException { ObjectConstructorContext _localctx = new ObjectConstructorContext(_ctx, getState()); - enterRule(_localctx, 158, RULE_objectConstructor); + enterRule(_localctx, 156, RULE_objectConstructor); int _la; try { - setState(874); + setState(870); _errHandler.sync(this); switch (_input.LA(1)) { - case T__28: + case T__27: enterOuterAlt(_localctx, 1); { - setState(858); - match(T__28); - setState(867); + setState(854); + match(T__27); + setState(863); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(859); + setState(855); pairConstructor(); - setState(864); + setState(860); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(860); - match(T__21); - setState(861); + setState(856); + match(T__20); + setState(857); pairConstructor(); } } - setState(866); + setState(862); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(869); - match(T__29); + setState(865); + match(T__28); } break; - case T__58: + case T__57: enterOuterAlt(_localctx, 2); { - setState(870); - ((ObjectConstructorContext)_localctx).s59 = match(T__58); - ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s59); - setState(871); + setState(866); + ((ObjectConstructorContext)_localctx).s58 = match(T__57); + ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s58); + setState(867); expr(); - setState(872); - match(T__59); + setState(868); + match(T__58); } break; default: @@ -6108,29 +6105,29 @@ public T accept(ParseTreeVisitor visitor) { public final ItemTypeContext itemType() throws RecognitionException { ItemTypeContext _localctx = new ItemTypeContext(_ctx, getState()); - enterRule(_localctx, 160, RULE_itemType); + enterRule(_localctx, 158, RULE_itemType); try { - setState(879); + setState(875); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,92,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(876); + setState(872); qname(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(877); + setState(873); match(NullLiteral); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(878); + setState(874); functionTest(); } break; @@ -6167,22 +6164,22 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionTestContext functionTest() throws RecognitionException { FunctionTestContext _localctx = new FunctionTestContext(_ctx, getState()); - enterRule(_localctx, 162, RULE_functionTest); + enterRule(_localctx, 160, RULE_functionTest); try { enterOuterAlt(_localctx, 1); { - setState(883); + setState(879); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,93,_ctx) ) { case 1: { - setState(881); + setState(877); anyFunctionTest(); } break; case 2: { - setState(882); + setState(878); typedFunctionTest(); } break; @@ -6214,18 +6211,18 @@ public T accept(ParseTreeVisitor visitor) { public final AnyFunctionTestContext anyFunctionTest() throws RecognitionException { AnyFunctionTestContext _localctx = new AnyFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 164, RULE_anyFunctionTest); + enterRule(_localctx, 162, RULE_anyFunctionTest); try { enterOuterAlt(_localctx, 1); { - setState(885); + setState(881); + match(T__24); + setState(882); match(T__25); - setState(886); + setState(883); + match(T__32); + setState(884); match(T__26); - setState(887); - match(T__33); - setState(888); - match(T__27); } } catch (RecognitionException re) { @@ -6262,48 +6259,48 @@ public T accept(ParseTreeVisitor visitor) { public final TypedFunctionTestContext typedFunctionTest() throws RecognitionException { TypedFunctionTestContext _localctx = new TypedFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 166, RULE_typedFunctionTest); + enterRule(_localctx, 164, RULE_typedFunctionTest); int _la; try { enterOuterAlt(_localctx, 1); { - setState(890); + setState(886); + match(T__24); + setState(887); match(T__25); - setState(891); - match(T__26); - setState(900); + setState(896); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__25) | (1L << T__26) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (NullLiteral - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__24) | (1L << T__25) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (NullLiteral - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(892); + setState(888); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); - setState(897); + setState(893); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__21) { + while (_la==T__20) { { { - setState(893); - match(T__21); - setState(894); + setState(889); + match(T__20); + setState(890); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); } } - setState(899); + setState(895); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(902); - match(T__27); - setState(903); + setState(898); + match(T__26); + setState(899); match(Kas); - setState(904); + setState(900); ((TypedFunctionTestContext)_localctx).rt = sequenceType(); } } @@ -6338,18 +6335,18 @@ public T accept(ParseTreeVisitor visitor) { public final SingleTypeContext singleType() throws RecognitionException { SingleTypeContext _localctx = new SingleTypeContext(_ctx, getState()); - enterRule(_localctx, 168, RULE_singleType); + enterRule(_localctx, 166, RULE_singleType); try { enterOuterAlt(_localctx, 1); { - setState(906); + setState(902); ((SingleTypeContext)_localctx).item = itemType(); - setState(908); + setState(904); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,96,_ctx) ) { case 1: { - setState(907); + setState(903); ((SingleTypeContext)_localctx).s106 = match(ArgumentPlaceholder); ((SingleTypeContext)_localctx).question.add(((SingleTypeContext)_localctx).s106); } @@ -6392,30 +6389,30 @@ public T accept(ParseTreeVisitor visitor) { public final PairConstructorContext pairConstructor() throws RecognitionException { PairConstructorContext _localctx = new PairConstructorContext(_ctx, getState()); - enterRule(_localctx, 170, RULE_pairConstructor); + enterRule(_localctx, 168, RULE_pairConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(912); + setState(908); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,97,_ctx) ) { case 1: { - setState(910); + setState(906); ((PairConstructorContext)_localctx).lhs = exprSingle(); } break; case 2: { - setState(911); + setState(907); ((PairConstructorContext)_localctx).name = match(NCName); } break; } - setState(914); + setState(910); _la = _input.LA(1); - if ( !(_la==T__9 || _la==ArgumentPlaceholder) ) { + if ( !(_la==T__8 || _la==ArgumentPlaceholder) ) { _errHandler.recoverInline(this); } else { @@ -6423,7 +6420,7 @@ public final PairConstructorContext pairConstructor() throws RecognitionExceptio _errHandler.reportMatch(this); consume(); } - setState(915); + setState(911); ((PairConstructorContext)_localctx).rhs = exprSingle(); } } @@ -6455,25 +6452,25 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayConstructorContext arrayConstructor() throws RecognitionException { ArrayConstructorContext _localctx = new ArrayConstructorContext(_ctx, getState()); - enterRule(_localctx, 172, RULE_arrayConstructor); + enterRule(_localctx, 170, RULE_arrayConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(917); - match(T__53); - setState(919); + setState(913); + match(T__52); + setState(915); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(918); + setState(914); expr(); } } - setState(921); - match(T__54); + setState(917); + match(T__53); } } catch (RecognitionException re) { @@ -6504,11 +6501,11 @@ public T accept(ParseTreeVisitor visitor) { public final UriLiteralContext uriLiteral() throws RecognitionException { UriLiteralContext _localctx = new UriLiteralContext(_ctx, getState()); - enterRule(_localctx, 174, RULE_uriLiteral); + enterRule(_localctx, 172, RULE_uriLiteral); try { enterOuterAlt(_localctx, 1); { - setState(923); + setState(919); stringLiteral(); } } @@ -6538,11 +6535,11 @@ public T accept(ParseTreeVisitor visitor) { public final StringLiteralContext stringLiteral() throws RecognitionException { StringLiteralContext _localctx = new StringLiteralContext(_ctx, getState()); - enterRule(_localctx, 176, RULE_stringLiteral); + enterRule(_localctx, 174, RULE_stringLiteral); try { enterOuterAlt(_localctx, 1); { - setState(925); + setState(921); match(STRING); } } @@ -6603,6 +6600,7 @@ public static class KeyWordsContext extends ParserRuleContext { public TerminalNode Korder() { return getToken(JsoniqParser.Korder, 0); } public TerminalNode Kcount() { return getToken(JsoniqParser.Kcount, 0); } public TerminalNode Kreturn() { return getToken(JsoniqParser.Kreturn, 0); } + public TerminalNode Kunordered() { return getToken(JsoniqParser.Kunordered, 0); } public KeyWordsContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -6616,14 +6614,14 @@ public T accept(ParseTreeVisitor visitor) { public final KeyWordsContext keyWords() throws RecognitionException { KeyWordsContext _localctx = new KeyWordsContext(_ctx, getState()); - enterRule(_localctx, 178, RULE_keyWords); + enterRule(_localctx, 176, RULE_keyWords); int _la; try { enterOuterAlt(_localctx, 1); { - setState(927); + setState(923); _la = _input.LA(1); - if ( !(((((_la - 61)) & ~0x3f) == 0 && ((1L << (_la - 61)) & ((1L << (Kfor - 61)) | (1L << (Klet - 61)) | (1L << (Kwhere - 61)) | (1L << (Kgroup - 61)) | (1L << (Kby - 61)) | (1L << (Korder - 61)) | (1L << (Kreturn - 61)) | (1L << (Kif - 61)) | (1L << (Kin - 61)) | (1L << (Kas - 61)) | (1L << (Kat - 61)) | (1L << (Kallowing - 61)) | (1L << (Kempty - 61)) | (1L << (Kcount - 61)) | (1L << (Kstable - 61)) | (1L << (Kascending - 61)) | (1L << (Kdescending - 61)) | (1L << (Ksome - 61)) | (1L << (Kevery - 61)) | (1L << (Ksatisfies - 61)) | (1L << (Kcollation - 61)) | (1L << (Kgreatest - 61)) | (1L << (Kleast - 61)) | (1L << (Kswitch - 61)) | (1L << (Kcase - 61)) | (1L << (Ktry - 61)) | (1L << (Kcatch - 61)) | (1L << (Kdefault - 61)) | (1L << (Kthen - 61)) | (1L << (Kelse - 61)) | (1L << (Ktypeswitch - 61)) | (1L << (Kor - 61)) | (1L << (Kand - 61)) | (1L << (Knot - 61)) | (1L << (Kto - 61)) | (1L << (Kinstance - 61)) | (1L << (Kof - 61)) | (1L << (Kstatically - 61)) | (1L << (Kis - 61)) | (1L << (Ktreat - 61)) | (1L << (Kcast - 61)) | (1L << (Kcastable - 61)) | (1L << (Kversion - 61)) | (1L << (Kjsoniq - 61)) | (1L << (NullLiteral - 61)))) != 0)) ) { + if ( !(((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (Kfor - 60)) | (1L << (Klet - 60)) | (1L << (Kwhere - 60)) | (1L << (Kgroup - 60)) | (1L << (Kby - 60)) | (1L << (Korder - 60)) | (1L << (Kreturn - 60)) | (1L << (Kif - 60)) | (1L << (Kin - 60)) | (1L << (Kas - 60)) | (1L << (Kat - 60)) | (1L << (Kallowing - 60)) | (1L << (Kempty - 60)) | (1L << (Kcount - 60)) | (1L << (Kstable - 60)) | (1L << (Kascending - 60)) | (1L << (Kdescending - 60)) | (1L << (Ksome - 60)) | (1L << (Kevery - 60)) | (1L << (Ksatisfies - 60)) | (1L << (Kcollation - 60)) | (1L << (Kgreatest - 60)) | (1L << (Kleast - 60)) | (1L << (Kswitch - 60)) | (1L << (Kcase - 60)) | (1L << (Ktry - 60)) | (1L << (Kcatch - 60)) | (1L << (Kdefault - 60)) | (1L << (Kthen - 60)) | (1L << (Kelse - 60)) | (1L << (Ktypeswitch - 60)) | (1L << (Kor - 60)) | (1L << (Kand - 60)) | (1L << (Knot - 60)) | (1L << (Kto - 60)) | (1L << (Kinstance - 60)) | (1L << (Kof - 60)) | (1L << (Kstatically - 60)) | (1L << (Kis - 60)) | (1L << (Ktreat - 60)) | (1L << (Kcast - 60)) | (1L << (Kcastable - 60)) | (1L << (Kversion - 60)) | (1L << (Kjsoniq - 60)) | (1L << (Kunordered - 60)) | (1L << (NullLiteral - 60)))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -6645,7 +6643,7 @@ public final KeyWordsContext keyWords() throws RecognitionException { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3w\u03a4\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3w\u03a0\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -6655,342 +6653,341 @@ public final KeyWordsContext keyWords() throws RecognitionException { "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+ "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ - "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\3\2\3\2\3\2\3\3\3\3\3\3\3\3"+ - "\3\3\5\3\u00bf\n\3\3\3\3\3\5\3\u00c3\n\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3"+ - "\5\3\5\3\5\3\5\3\6\3\6\3\6\5\6\u00d3\n\6\3\6\3\6\7\6\u00d7\n\6\f\6\16"+ - "\6\u00da\13\6\3\6\3\6\3\6\7\6\u00df\n\6\f\6\16\6\u00e2\13\6\3\7\3\7\3"+ - "\7\3\7\5\7\u00e8\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\t\u00f3\n\t"+ - "\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3"+ - "\r\3\r\3\r\3\r\5\r\u0109\n\r\3\r\3\r\3\r\3\r\7\r\u010f\n\r\f\r\16\r\u0112"+ - "\13\r\3\16\3\16\5\16\u0116\n\16\3\16\5\16\u0119\n\16\3\16\3\16\5\16\u011d"+ - "\n\16\3\17\3\17\3\20\3\20\3\21\3\21\3\21\3\21\3\21\5\21\u0128\n\21\3\21"+ - "\3\21\3\21\3\21\3\21\7\21\u012f\n\21\f\21\16\21\u0132\13\21\5\21\u0134"+ - "\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u013b\n\22\3\22\3\22\3\22\3\22\3\22"+ - "\5\22\u0142\n\22\5\22\u0144\n\22\3\23\3\23\3\23\3\23\3\23\5\23\u014b\n"+ - "\23\3\23\3\23\3\23\5\23\u0150\n\23\3\23\3\23\5\23\u0154\n\23\3\23\3\23"+ - "\5\23\u0158\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\7\25\u0163"+ - "\n\25\f\25\16\25\u0166\13\25\3\26\3\26\3\26\3\26\5\26\u016c\n\26\3\27"+ - "\3\27\3\27\7\27\u0171\n\27\f\27\16\27\u0174\13\27\3\30\3\30\3\30\3\30"+ - "\3\30\3\30\3\30\5\30\u017d\n\30\3\31\3\31\5\31\u0181\n\31\3\31\3\31\3"+ - "\31\3\31\3\31\3\31\7\31\u0189\n\31\f\31\16\31\u018c\13\31\3\31\3\31\3"+ - "\31\3\32\3\32\3\32\3\32\7\32\u0195\n\32\f\32\16\32\u0198\13\32\3\33\3"+ - "\33\3\33\5\33\u019d\n\33\3\33\3\33\5\33\u01a1\n\33\3\33\3\33\5\33\u01a5"+ - "\n\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\7\34\u01ae\n\34\f\34\16\34\u01b1"+ - "\13\34\3\35\3\35\3\35\5\35\u01b6\n\35\3\35\3\35\3\35\3\36\3\36\3\36\3"+ - "\37\3\37\3\37\3\37\3\37\7\37\u01c3\n\37\f\37\16\37\u01c6\13\37\3 \3 \3"+ - " \5 \u01cb\n \3 \3 \5 \u01cf\n \3 \3 \5 \u01d3\n \3!\3!\3!\3!\3!\5!\u01da"+ - "\n!\3!\3!\3!\7!\u01df\n!\f!\16!\u01e2\13!\3\"\3\"\3\"\5\"\u01e7\n\"\3"+ - "\"\3\"\3\"\5\"\u01ec\n\"\5\"\u01ee\n\"\3\"\3\"\5\"\u01f2\n\"\3#\3#\3#"+ - "\3$\3$\5$\u01f9\n$\3$\3$\3$\7$\u01fe\n$\f$\16$\u0201\13$\3$\3$\3$\3%\3"+ - "%\3%\5%\u0209\n%\3%\3%\3%\3&\3&\3&\3&\3&\6&\u0213\n&\r&\16&\u0214\3&\3"+ - "&\3&\3&\3\'\3\'\6\'\u021d\n\'\r\'\16\'\u021e\3\'\3\'\3\'\3(\3(\3(\3(\3"+ - "(\6(\u0229\n(\r(\16(\u022a\3(\3(\5(\u022f\n(\3(\3(\3(\3)\3)\3)\3)\5)\u0238"+ - "\n)\3)\3)\3)\7)\u023d\n)\f)\16)\u0240\13)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3"+ - "*\3*\3*\3+\3+\3+\3+\3+\6+\u0253\n+\r+\16+\u0254\3,\3,\3,\5,\u025a\n,\3"+ - ",\3,\3,\5,\u025f\n,\7,\u0261\n,\f,\16,\u0264\13,\3,\3,\3,\3,\3-\3-\3-"+ - "\7-\u026d\n-\f-\16-\u0270\13-\3.\3.\3.\7.\u0275\n.\f.\16.\u0278\13.\3"+ - "/\5/\u027b\n/\3/\3/\3\60\3\60\3\60\5\60\u0282\n\60\3\61\3\61\3\61\7\61"+ - "\u0287\n\61\f\61\16\61\u028a\13\61\3\62\3\62\3\62\5\62\u028f\n\62\3\63"+ - "\3\63\3\63\7\63\u0294\n\63\f\63\16\63\u0297\13\63\3\64\3\64\3\64\7\64"+ - "\u029c\n\64\f\64\16\64\u029f\13\64\3\65\3\65\3\65\3\65\5\65\u02a5\n\65"+ - "\3\66\3\66\3\66\3\66\5\66\u02ab\n\66\3\67\3\67\3\67\3\67\5\67\u02b1\n"+ - "\67\38\38\38\38\58\u02b7\n8\39\39\39\39\59\u02bd\n9\3:\3:\3:\3:\3:\7:"+ - "\u02c4\n:\f:\16:\u02c7\13:\3;\7;\u02ca\n;\f;\16;\u02cd\13;\3;\3;\3<\3"+ - "<\5<\u02d3\n<\3=\3=\3=\3=\3=\3=\3=\3>\3>\3>\7>\u02df\n>\f>\16>\u02e2\13"+ - ">\3?\3?\3?\3?\3?\3?\7?\u02ea\n?\f?\16?\u02ed\13?\3@\3@\3@\3@\3@\3@\3A"+ - "\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\5C\u0303\nC\3D\3D\3D\3D\3D\3D"+ - "\3D\3D\3D\3D\3D\3D\5D\u0311\nD\3E\3E\3E\3F\3F\5F\u0318\nF\3F\3F\3G\3G"+ - "\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3K\3K\3K\5K\u032e\nK\7K\u0330"+ - "\nK\fK\16K\u0333\13K\3K\3K\3L\3L\5L\u0339\nL\3M\3M\5M\u033d\nM\3N\3N\3"+ - "N\3N\3O\3O\3O\5O\u0346\nO\3O\3O\3O\5O\u034b\nO\3O\3O\5O\u034f\nO\3O\3"+ - "O\3P\3P\3P\3P\3P\3P\5P\u0359\nP\5P\u035b\nP\3Q\3Q\3Q\3Q\7Q\u0361\nQ\f"+ - "Q\16Q\u0364\13Q\5Q\u0366\nQ\3Q\3Q\3Q\3Q\3Q\5Q\u036d\nQ\3R\3R\3R\5R\u0372"+ - "\nR\3S\3S\5S\u0376\nS\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\7U\u0382\nU\fU\16"+ - "U\u0385\13U\5U\u0387\nU\3U\3U\3U\3U\3V\3V\5V\u038f\nV\3W\3W\5W\u0393\n"+ - "W\3W\3W\3W\3X\3X\5X\u039a\nX\3X\3X\3Y\3Y\3Z\3Z\3[\3[\3[\2\2\\\2\4\6\b"+ - "\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVX"+ - "Z\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e\u0090"+ - "\u0092\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6\u00a8"+ - "\u00aa\u00ac\u00ae\u00b0\u00b2\u00b4\2\13\3\2\t\n\3\2TU\4\2mmuu\3\2\r"+ - "\26\4\2\6\6%/\3\2\61\62\4\2$$\63\65\4\2\f\fll\4\2?jmm\2\u03ce\2\u00b6"+ - "\3\2\2\2\4\u00be\3\2\2\2\6\u00c4\3\2\2\2\b\u00c7\3\2\2\2\n\u00d8\3\2\2"+ - "\2\f\u00e7\3\2\2\2\16\u00e9\3\2\2\2\20\u00f2\3\2\2\2\22\u00f4\3\2\2\2"+ - "\24\u00f9\3\2\2\2\26\u00fd\3\2\2\2\30\u0103\3\2\2\2\32\u0118\3\2\2\2\34"+ - "\u011e\3\2\2\2\36\u0120\3\2\2\2 \u0122\3\2\2\2\"\u0135\3\2\2\2$\u0145"+ - "\3\2\2\2&\u0159\3\2\2\2(\u015f\3\2\2\2*\u0167\3\2\2\2,\u016d\3\2\2\2."+ - "\u017c\3\2\2\2\60\u0180\3\2\2\2\62\u0190\3\2\2\2\64\u0199\3\2\2\2\66\u01a9"+ - "\3\2\2\28\u01b2\3\2\2\2:\u01ba\3\2\2\2<\u01bd\3\2\2\2>\u01c7\3\2\2\2@"+ - "\u01d9\3\2\2\2B\u01e3\3\2\2\2D\u01f3\3\2\2\2F\u01f8\3\2\2\2H\u0205\3\2"+ - "\2\2J\u020d\3\2\2\2L\u021c\3\2\2\2N\u0223\3\2\2\2P\u0233\3\2\2\2R\u0244"+ - "\3\2\2\2T\u024d\3\2\2\2V\u0256\3\2\2\2X\u0269\3\2\2\2Z\u0271\3\2\2\2\\"+ - "\u027a\3\2\2\2^\u027e\3\2\2\2`\u0283\3\2\2\2b\u028b\3\2\2\2d\u0290\3\2"+ - "\2\2f\u0298\3\2\2\2h\u02a0\3\2\2\2j\u02a6\3\2\2\2l\u02ac\3\2\2\2n\u02b2"+ - "\3\2\2\2p\u02b8\3\2\2\2r\u02be\3\2\2\2t\u02cb\3\2\2\2v\u02d2\3\2\2\2x"+ - "\u02d4\3\2\2\2z\u02db\3\2\2\2|\u02e3\3\2\2\2~\u02ee\3\2\2\2\u0080\u02f4"+ - "\3\2\2\2\u0082\u02f7\3\2\2\2\u0084\u02fb\3\2\2\2\u0086\u0310\3\2\2\2\u0088"+ - "\u0312\3\2\2\2\u008a\u0315\3\2\2\2\u008c\u031b\3\2\2\2\u008e\u031d\3\2"+ - "\2\2\u0090\u0322\3\2\2\2\u0092\u0327\3\2\2\2\u0094\u032a\3\2\2\2\u0096"+ - "\u0338\3\2\2\2\u0098\u033c\3\2\2\2\u009a\u033e\3\2\2\2\u009c\u0342\3\2"+ - "\2\2\u009e\u035a\3\2\2\2\u00a0\u036c\3\2\2\2\u00a2\u0371\3\2\2\2\u00a4"+ - "\u0375\3\2\2\2\u00a6\u0377\3\2\2\2\u00a8\u037c\3\2\2\2\u00aa\u038c\3\2"+ - "\2\2\u00ac\u0392\3\2\2\2\u00ae\u0397\3\2\2\2\u00b0\u039d\3\2\2\2\u00b2"+ - "\u039f\3\2\2\2\u00b4\u03a1\3\2\2\2\u00b6\u00b7\5\4\3\2\u00b7\u00b8\7\2"+ - "\2\3\u00b8\3\3\2\2\2\u00b9\u00ba\7j\2\2\u00ba\u00bb\7i\2\2\u00bb\u00bc"+ - "\5\u00b2Z\2\u00bc\u00bd\7\3\2\2\u00bd\u00bf\3\2\2\2\u00be\u00b9\3\2\2"+ - "\2\u00be\u00bf\3\2\2\2\u00bf\u00c2\3\2\2\2\u00c0\u00c3\5\b\5\2\u00c1\u00c3"+ - "\5\6\4\2\u00c2\u00c0\3\2\2\2\u00c2\u00c1\3\2\2\2\u00c3\5\3\2\2\2\u00c4"+ - "\u00c5\5\n\6\2\u00c5\u00c6\5,\27\2\u00c6\7\3\2\2\2\u00c7\u00c8\7\4\2\2"+ - "\u00c8\u00c9\7\5\2\2\u00c9\u00ca\7u\2\2\u00ca\u00cb\7\6\2\2\u00cb\u00cc"+ - "\5\u00b0Y\2\u00cc\u00cd\7\3\2\2\u00cd\u00ce\5\n\6\2\u00ce\t\3\2\2\2\u00cf"+ - "\u00d3\5\f\7\2\u00d0\u00d3\5\16\b\2\u00d1\u00d3\5 \21\2\u00d2\u00cf\3"+ - "\2\2\2\u00d2\u00d0\3\2\2\2\u00d2\u00d1\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4"+ - "\u00d5\7\3\2\2\u00d5\u00d7\3\2\2\2\u00d6\u00d2\3\2\2\2\u00d7\u00da\3\2"+ - "\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9\3\2\2\2\u00d9\u00e0\3\2\2\2\u00da"+ - "\u00d8\3\2\2\2\u00db\u00dc\5\20\t\2\u00dc\u00dd\7\3\2\2\u00dd\u00df\3"+ - "\2\2\2\u00de\u00db\3\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0"+ - "\u00e1\3\2\2\2\u00e1\13\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e8\5\22\n"+ - "\2\u00e4\u00e8\5\24\13\2\u00e5\u00e8\5\26\f\2\u00e6\u00e8\5\30\r\2\u00e7"+ - "\u00e3\3\2\2\2\u00e7\u00e4\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e7\u00e6\3\2"+ - "\2\2\u00e8\r\3\2\2\2\u00e9\u00ea\7\7\2\2\u00ea\u00eb\7\5\2\2\u00eb\u00ec"+ - "\7u\2\2\u00ec\u00ed\7\6\2\2\u00ed\u00ee\5\u00b0Y\2\u00ee\17\3\2\2\2\u00ef"+ - "\u00f3\5$\23\2\u00f0\u00f3\5\"\22\2\u00f1\u00f3\5&\24\2\u00f2\u00ef\3"+ - "\2\2\2\u00f2\u00f0\3\2\2\2\u00f2\u00f1\3\2\2\2\u00f3\21\3\2\2\2\u00f4"+ - "\u00f5\7\7\2\2\u00f5\u00f6\7Z\2\2\u00f6\u00f7\7S\2\2\u00f7\u00f8\5\u00b0"+ - "Y\2\u00f8\23\3\2\2\2\u00f9\u00fa\7\7\2\2\u00fa\u00fb\7\b\2\2\u00fb\u00fc"+ - "\t\2\2\2\u00fc\25\3\2\2\2\u00fd\u00fe\7\7\2\2\u00fe\u00ff\7Z\2\2\u00ff"+ - "\u0100\7D\2\2\u0100\u0101\7K\2\2\u0101\u0102\t\3\2\2\u0102\27\3\2\2\2"+ - "\u0103\u0108\7\7\2\2\u0104\u0105\7\13\2\2\u0105\u0109\5\32\16\2\u0106"+ - "\u0107\7Z\2\2\u0107\u0109\7\13\2\2\u0108\u0104\3\2\2\2\u0108\u0106\3\2"+ - "\2\2\u0109\u0110\3\2\2\2\u010a\u010b\5\36\20\2\u010b\u010c\7\6\2\2\u010c"+ - "\u010d\5\u00b2Z\2\u010d\u010f\3\2\2\2\u010e\u010a\3\2\2\2\u010f\u0112"+ - "\3\2\2\2\u0110\u010e\3\2\2\2\u0110\u0111\3\2\2\2\u0111\31\3\2\2\2\u0112"+ - "\u0110\3\2\2\2\u0113\u0116\7u\2\2\u0114\u0116\5\u00b4[\2\u0115\u0113\3"+ - "\2\2\2\u0115\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u0119\7\f\2\2\u0118"+ - "\u0115\3\2\2\2\u0118\u0119\3\2\2\2\u0119\u011c\3\2\2\2\u011a\u011d\5\34"+ - "\17\2\u011b\u011d\5\u00b4[\2\u011c\u011a\3\2\2\2\u011c\u011b\3\2\2\2\u011d"+ - "\33\3\2\2\2\u011e\u011f\t\4\2\2\u011f\35\3\2\2\2\u0120\u0121\t\5\2\2\u0121"+ - "\37\3\2\2\2\u0122\u0123\7\27\2\2\u0123\u0127\7\4\2\2\u0124\u0125\7\5\2"+ - "\2\u0125\u0126\7u\2\2\u0126\u0128\7\6\2\2\u0127\u0124\3\2\2\2\u0127\u0128"+ - "\3\2\2\2\u0128\u0129\3\2\2\2\u0129\u0133\5\u00b0Y\2\u012a\u012b\7I\2\2"+ - "\u012b\u0130\5\u00b0Y\2\u012c\u012d\7\30\2\2\u012d\u012f\5\u00b0Y\2\u012e"+ - "\u012c\3\2\2\2\u012f\u0132\3\2\2\2\u0130\u012e\3\2\2\2\u0130\u0131\3\2"+ - "\2\2\u0131\u0134\3\2\2\2\u0132\u0130\3\2\2\2\u0133\u012a\3\2\2\2\u0133"+ - "\u0134\3\2\2\2\u0134!\3\2\2\2\u0135\u0136\7\7\2\2\u0136\u0137\7\31\2\2"+ - "\u0137\u013a\5\u0088E\2\u0138\u0139\7H\2\2\u0139\u013b\5\u009eP\2\u013a"+ - "\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u0143\3\2\2\2\u013c\u013d\7\32"+ - "\2\2\u013d\u0144\5.\30\2\u013e\u0141\7\33\2\2\u013f\u0140\7\32\2\2\u0140"+ - "\u0142\5.\30\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2\2\2\u0142\u0144\3\2"+ - "\2\2\u0143\u013c\3\2\2\2\u0143\u013e\3\2\2\2\u0144#\3\2\2\2\u0145\u0146"+ - "\7\7\2\2\u0146\u0147\7\34\2\2\u0147\u0148\5\32\16\2\u0148\u014a\7\35\2"+ - "\2\u0149\u014b\5(\25\2\u014a\u0149\3\2\2\2\u014a\u014b\3\2\2\2\u014b\u014c"+ - "\3\2\2\2\u014c\u014f\7\36\2\2\u014d\u014e\7H\2\2\u014e\u0150\5\u009eP"+ - "\2\u014f\u014d\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u0157\3\2\2\2\u0151\u0153"+ - "\7\37\2\2\u0152\u0154\5,\27\2\u0153\u0152\3\2\2\2\u0153\u0154\3\2\2\2"+ - "\u0154\u0155\3\2\2\2\u0155\u0158\7 \2\2\u0156\u0158\7\33\2\2\u0157\u0151"+ - "\3\2\2\2\u0157\u0156\3\2\2\2\u0158%\3\2\2\2\u0159\u015a\7\7\2\2\u015a"+ - "\u015b\7!\2\2\u015b\u015c\5\32\16\2\u015c\u015d\7H\2\2\u015d\u015e\5."+ - "\30\2\u015e\'\3\2\2\2\u015f\u0164\5*\26\2\u0160\u0161\7\30\2\2\u0161\u0163"+ - "\5*\26\2\u0162\u0160\3\2\2\2\u0163\u0166\3\2\2\2\u0164\u0162\3\2\2\2\u0164"+ - "\u0165\3\2\2\2\u0165)\3\2\2\2\u0166\u0164\3\2\2\2\u0167\u0168\7\"\2\2"+ - "\u0168\u016b\5\32\16\2\u0169\u016a\7H\2\2\u016a\u016c\5\u009eP\2\u016b"+ - "\u0169\3\2\2\2\u016b\u016c\3\2\2\2\u016c+\3\2\2\2\u016d\u0172\5.\30\2"+ - "\u016e\u016f\7\30\2\2\u016f\u0171\5.\30\2\u0170\u016e\3\2\2\2\u0171\u0174"+ - "\3\2\2\2\u0172\u0170\3\2\2\2\u0172\u0173\3\2\2\2\u0173-\3\2\2\2\u0174"+ - "\u0172\3\2\2\2\u0175\u017d\5\60\31\2\u0176\u017d\5F$\2\u0177\u017d\5J"+ - "&\2\u0178\u017d\5N(\2\u0179\u017d\5R*\2\u017a\u017d\5T+\2\u017b\u017d"+ - "\5X-\2\u017c\u0175\3\2\2\2\u017c\u0176\3\2\2\2\u017c\u0177\3\2\2\2\u017c"+ - "\u0178\3\2\2\2\u017c\u0179\3\2\2\2\u017c\u017a\3\2\2\2\u017c\u017b\3\2"+ - "\2\2\u017d/\3\2\2\2\u017e\u0181\5\62\32\2\u017f\u0181\5\66\34\2\u0180"+ - "\u017e\3\2\2\2\u0180\u017f\3\2\2\2\u0181\u018a\3\2\2\2\u0182\u0189\5\62"+ - "\32\2\u0183\u0189\5:\36\2\u0184\u0189\5\66\34\2\u0185\u0189\5<\37\2\u0186"+ - "\u0189\5@!\2\u0187\u0189\5D#\2\u0188\u0182\3\2\2\2\u0188\u0183\3\2\2\2"+ - "\u0188\u0184\3\2\2\2\u0188\u0185\3\2\2\2\u0188\u0186\3\2\2\2\u0188\u0187"+ - "\3\2\2\2\u0189\u018c\3\2\2\2\u018a\u0188\3\2\2\2\u018a\u018b\3\2\2\2\u018b"+ - "\u018d\3\2\2\2\u018c\u018a\3\2\2\2\u018d\u018e\7E\2\2\u018e\u018f\5.\30"+ - "\2\u018f\61\3\2\2\2\u0190\u0191\7?\2\2\u0191\u0196\5\64\33\2\u0192\u0193"+ - "\7\30\2\2\u0193\u0195\5\64\33\2\u0194\u0192\3\2\2\2\u0195\u0198\3\2\2"+ - "\2\u0196\u0194\3\2\2\2\u0196\u0197\3\2\2\2\u0197\63\3\2\2\2\u0198\u0196"+ - "\3\2\2\2\u0199\u019c\5\u0088E\2\u019a\u019b\7H\2\2\u019b\u019d\5\u009e"+ - "P\2\u019c\u019a\3\2\2\2\u019c\u019d\3\2\2\2\u019d\u01a0\3\2\2\2\u019e"+ - "\u019f\7J\2\2\u019f\u01a1\7K\2\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2\2"+ - "\2\u01a1\u01a4\3\2\2\2\u01a2\u01a3\7I\2\2\u01a3\u01a5\5\u0088E\2\u01a4"+ - "\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a7\7G"+ - "\2\2\u01a7\u01a8\5.\30\2\u01a8\65\3\2\2\2\u01a9\u01aa\7@\2\2\u01aa\u01af"+ - "\58\35\2\u01ab\u01ac\7\30\2\2\u01ac\u01ae\58\35\2\u01ad\u01ab\3\2\2\2"+ - "\u01ae\u01b1\3\2\2\2\u01af\u01ad\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\67"+ - "\3\2\2\2\u01b1\u01af\3\2\2\2\u01b2\u01b5\5\u0088E\2\u01b3\u01b4\7H\2\2"+ - "\u01b4\u01b6\5\u009eP\2\u01b5\u01b3\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6"+ - "\u01b7\3\2\2\2\u01b7\u01b8\7\32\2\2\u01b8\u01b9\5.\30\2\u01b99\3\2\2\2"+ - "\u01ba\u01bb\7A\2\2\u01bb\u01bc\5.\30\2\u01bc;\3\2\2\2\u01bd\u01be\7B"+ - "\2\2\u01be\u01bf\7C\2\2\u01bf\u01c4\5> \2\u01c0\u01c1\7\30\2\2\u01c1\u01c3"+ - "\5> \2\u01c2\u01c0\3\2\2\2\u01c3\u01c6\3\2\2\2\u01c4\u01c2\3\2\2\2\u01c4"+ - "\u01c5\3\2\2\2\u01c5=\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c7\u01ce\5\u0088"+ - "E\2\u01c8\u01c9\7H\2\2\u01c9\u01cb\5\u009eP\2\u01ca\u01c8\3\2\2\2\u01ca"+ - "\u01cb\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01cd\7\32\2\2\u01cd\u01cf\5"+ - ".\30\2\u01ce\u01ca\3\2\2\2\u01ce\u01cf\3\2\2\2\u01cf\u01d2\3\2\2\2\u01d0"+ - "\u01d1\7S\2\2\u01d1\u01d3\5\u00b0Y\2\u01d2\u01d0\3\2\2\2\u01d2\u01d3\3"+ - "\2\2\2\u01d3?\3\2\2\2\u01d4\u01d5\7D\2\2\u01d5\u01da\7C\2\2\u01d6\u01d7"+ - "\7M\2\2\u01d7\u01d8\7D\2\2\u01d8\u01da\7C\2\2\u01d9\u01d4\3\2\2\2\u01d9"+ - "\u01d6\3\2\2\2\u01da\u01db\3\2\2\2\u01db\u01e0\5B\"\2\u01dc\u01dd\7\30"+ - "\2\2\u01dd\u01df\5B\"\2\u01de\u01dc\3\2\2\2\u01df\u01e2\3\2\2\2\u01e0"+ - "\u01de\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1A\3\2\2\2\u01e2\u01e0\3\2\2\2"+ - "\u01e3\u01e6\5.\30\2\u01e4\u01e7\7N\2\2\u01e5\u01e7\7O\2\2\u01e6\u01e4"+ - "\3\2\2\2\u01e6\u01e5\3\2\2\2\u01e6\u01e7\3\2\2\2\u01e7\u01ed\3\2\2\2\u01e8"+ - "\u01eb\7K\2\2\u01e9\u01ec\7T\2\2\u01ea\u01ec\7U\2\2\u01eb\u01e9\3\2\2"+ - "\2\u01eb\u01ea\3\2\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01e8\3\2\2\2\u01ed\u01ee"+ - "\3\2\2\2\u01ee\u01f1\3\2\2\2\u01ef\u01f0\7S\2\2\u01f0\u01f2\5\u00b0Y\2"+ - "\u01f1\u01ef\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2C\3\2\2\2\u01f3\u01f4\7"+ - "L\2\2\u01f4\u01f5\5\u0088E\2\u01f5E\3\2\2\2\u01f6\u01f9\7P\2\2\u01f7\u01f9"+ - "\7Q\2\2\u01f8\u01f6\3\2\2\2\u01f8\u01f7\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fa"+ - "\u01ff\5H%\2\u01fb\u01fc\7\30\2\2\u01fc\u01fe\5H%\2\u01fd\u01fb\3\2\2"+ - "\2\u01fe\u0201\3\2\2\2\u01ff\u01fd\3\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0202"+ - "\3\2\2\2\u0201\u01ff\3\2\2\2\u0202\u0203\7R\2\2\u0203\u0204\5.\30\2\u0204"+ - "G\3\2\2\2\u0205\u0208\5\u0088E\2\u0206\u0207\7H\2\2\u0207\u0209\5\u009e"+ - "P\2\u0208\u0206\3\2\2\2\u0208\u0209\3\2\2\2\u0209\u020a\3\2\2\2\u020a"+ - "\u020b\7G\2\2\u020b\u020c\5.\30\2\u020cI\3\2\2\2\u020d\u020e\7V\2\2\u020e"+ - "\u020f\7\35\2\2\u020f\u0210\5,\27\2\u0210\u0212\7\36\2\2\u0211\u0213\5"+ - "L\'\2\u0212\u0211\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0212\3\2\2\2\u0214"+ - "\u0215\3\2\2\2\u0215\u0216\3\2\2\2\u0216\u0217\7Z\2\2\u0217\u0218\7E\2"+ - "\2\u0218\u0219\5.\30\2\u0219K\3\2\2\2\u021a\u021b\7W\2\2\u021b\u021d\5"+ - ".\30\2\u021c\u021a\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u021c\3\2\2\2\u021e"+ - "\u021f\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0221\7E\2\2\u0221\u0222\5.\30"+ - "\2\u0222M\3\2\2\2\u0223\u0224\7]\2\2\u0224\u0225\7\35\2\2\u0225\u0226"+ - "\5,\27\2\u0226\u0228\7\36\2\2\u0227\u0229\5P)\2\u0228\u0227\3\2\2\2\u0229"+ - "\u022a\3\2\2\2\u022a\u0228\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u022c\3\2"+ - "\2\2\u022c\u022e\7Z\2\2\u022d\u022f\5\u0088E\2\u022e\u022d\3\2\2\2\u022e"+ - "\u022f\3\2\2\2\u022f\u0230\3\2\2\2\u0230\u0231\7E\2\2\u0231\u0232\5.\30"+ - "\2\u0232O\3\2\2\2\u0233\u0237\7W\2\2\u0234\u0235\5\u0088E\2\u0235\u0236"+ - "\7H\2\2\u0236\u0238\3\2\2\2\u0237\u0234\3\2\2\2\u0237\u0238\3\2\2\2\u0238"+ - "\u0239\3\2\2\2\u0239\u023e\5\u009eP\2\u023a\u023b\7#\2\2\u023b\u023d\5"+ - "\u009eP\2\u023c\u023a\3\2\2\2\u023d\u0240\3\2\2\2\u023e\u023c\3\2\2\2"+ - "\u023e\u023f\3\2\2\2\u023f\u0241\3\2\2\2\u0240\u023e\3\2\2\2\u0241\u0242"+ - "\7E\2\2\u0242\u0243\5.\30\2\u0243Q\3\2\2\2\u0244\u0245\7F\2\2\u0245\u0246"+ - "\7\35\2\2\u0246\u0247\5,\27\2\u0247\u0248\7\36\2\2\u0248\u0249\7[\2\2"+ - "\u0249\u024a\5.\30\2\u024a\u024b\7\\\2\2\u024b\u024c\5.\30\2\u024cS\3"+ - "\2\2\2\u024d\u024e\7X\2\2\u024e\u024f\7\37\2\2\u024f\u0250\5,\27\2\u0250"+ - "\u0252\7 \2\2\u0251\u0253\5V,\2\u0252\u0251\3\2\2\2\u0253\u0254\3\2\2"+ - "\2\u0254\u0252\3\2\2\2\u0254\u0255\3\2\2\2\u0255U\3\2\2\2\u0256\u0259"+ - "\7Y\2\2\u0257\u025a\7$\2\2\u0258\u025a\5\32\16\2\u0259\u0257\3\2\2\2\u0259"+ - "\u0258\3\2\2\2\u025a\u0262\3\2\2\2\u025b\u025e\7#\2\2\u025c\u025f\7$\2"+ - "\2\u025d\u025f\5\32\16\2\u025e\u025c\3\2\2\2\u025e\u025d\3\2\2\2\u025f"+ - "\u0261\3\2\2\2\u0260\u025b\3\2\2\2\u0261\u0264\3\2\2\2\u0262\u0260\3\2"+ - "\2\2\u0262\u0263\3\2\2\2\u0263\u0265\3\2\2\2\u0264\u0262\3\2\2\2\u0265"+ - "\u0266\7\37\2\2\u0266\u0267\5,\27\2\u0267\u0268\7 \2\2\u0268W\3\2\2\2"+ - "\u0269\u026e\5Z.\2\u026a\u026b\7^\2\2\u026b\u026d\5Z.\2\u026c\u026a\3"+ - "\2\2\2\u026d\u0270\3\2\2\2\u026e\u026c\3\2\2\2\u026e\u026f\3\2\2\2\u026f"+ - "Y\3\2\2\2\u0270\u026e\3\2\2\2\u0271\u0276\5\\/\2\u0272\u0273\7_\2\2\u0273"+ - "\u0275\5\\/\2\u0274\u0272\3\2\2\2\u0275\u0278\3\2\2\2\u0276\u0274\3\2"+ - "\2\2\u0276\u0277\3\2\2\2\u0277[\3\2\2\2\u0278\u0276\3\2\2\2\u0279\u027b"+ - "\7`\2\2\u027a\u0279\3\2\2\2\u027a\u027b\3\2\2\2\u027b\u027c\3\2\2\2\u027c"+ - "\u027d\5^\60\2\u027d]\3\2\2\2\u027e\u0281\5`\61\2\u027f\u0280\t\6\2\2"+ - "\u0280\u0282\5`\61\2\u0281\u027f\3\2\2\2\u0281\u0282\3\2\2\2\u0282_\3"+ - "\2\2\2\u0283\u0288\5b\62\2\u0284\u0285\7\60\2\2\u0285\u0287\5b\62\2\u0286"+ - "\u0284\3\2\2\2\u0287\u028a\3\2\2\2\u0288\u0286\3\2\2\2\u0288\u0289\3\2"+ - "\2\2\u0289a\3\2\2\2\u028a\u0288\3\2\2\2\u028b\u028e\5d\63\2\u028c\u028d"+ - "\7a\2\2\u028d\u028f\5d\63\2\u028e\u028c\3\2\2\2\u028e\u028f\3\2\2\2\u028f"+ - "c\3\2\2\2\u0290\u0295\5f\64\2\u0291\u0292\t\7\2\2\u0292\u0294\5f\64\2"+ - "\u0293\u0291\3\2\2\2\u0294\u0297\3\2\2\2\u0295\u0293\3\2\2\2\u0295\u0296"+ - "\3\2\2\2\u0296e\3\2\2\2\u0297\u0295\3\2\2\2\u0298\u029d\5h\65\2\u0299"+ - "\u029a\t\b\2\2\u029a\u029c\5h\65\2\u029b\u0299\3\2\2\2\u029c\u029f\3\2"+ - "\2\2\u029d\u029b\3\2\2\2\u029d\u029e\3\2\2\2\u029eg\3\2\2\2\u029f\u029d"+ - "\3\2\2\2\u02a0\u02a4\5j\66\2\u02a1\u02a2\7b\2\2\u02a2\u02a3\7c\2\2\u02a3"+ - "\u02a5\5\u009eP\2\u02a4\u02a1\3\2\2\2\u02a4\u02a5\3\2\2\2\u02a5i\3\2\2"+ - "\2\u02a6\u02aa\5l\67\2\u02a7\u02a8\7e\2\2\u02a8\u02a9\7d\2\2\u02a9\u02ab"+ - "\5\u009eP\2\u02aa\u02a7\3\2\2\2\u02aa\u02ab\3\2\2\2\u02abk\3\2\2\2\u02ac"+ - "\u02b0\5n8\2\u02ad\u02ae\7f\2\2\u02ae\u02af\7H\2\2\u02af\u02b1\5\u009e"+ - "P\2\u02b0\u02ad\3\2\2\2\u02b0\u02b1\3\2\2\2\u02b1m\3\2\2\2\u02b2\u02b6"+ - "\5p9\2\u02b3\u02b4\7h\2\2\u02b4\u02b5\7H\2\2\u02b5\u02b7\5\u00aaV\2\u02b6"+ - "\u02b3\3\2\2\2\u02b6\u02b7\3\2\2\2\u02b7o\3\2\2\2\u02b8\u02bc\5r:\2\u02b9"+ - "\u02ba\7g\2\2\u02ba\u02bb\7H\2\2\u02bb\u02bd\5\u00aaV\2\u02bc\u02b9\3"+ - "\2\2\2\u02bc\u02bd\3\2\2\2\u02bdq\3\2\2\2\u02be\u02c5\5t;\2\u02bf\u02c0"+ - "\7\6\2\2\u02c0\u02c1\7.\2\2\u02c1\u02c2\3\2\2\2\u02c2\u02c4\5\u0092J\2"+ - "\u02c3\u02bf\3\2\2\2\u02c4\u02c7\3\2\2\2\u02c5\u02c3\3\2\2\2\u02c5\u02c6"+ - "\3\2\2\2\u02c6s\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c8\u02ca\t\7\2\2\u02c9"+ - "\u02c8\3\2\2\2\u02ca\u02cd\3\2\2\2\u02cb\u02c9\3\2\2\2\u02cb\u02cc\3\2"+ - "\2\2\u02cc\u02ce\3\2\2\2\u02cd\u02cb\3\2\2\2\u02ce\u02cf\5v<\2\u02cfu"+ - "\3\2\2\2\u02d0\u02d3\5z>\2\u02d1\u02d3\5x=\2\u02d2\u02d0\3\2\2\2\u02d2"+ - "\u02d1\3\2\2\2\u02d3w\3\2\2\2\u02d4\u02d5\7\66\2\2\u02d5\u02d6\7!\2\2"+ - "\u02d6\u02d7\5\u009eP\2\u02d7\u02d8\7\37\2\2\u02d8\u02d9\5,\27\2\u02d9"+ - "\u02da\7 \2\2\u02day\3\2\2\2\u02db\u02e0\5|?\2\u02dc\u02dd\7\67\2\2\u02dd"+ - "\u02df\5|?\2\u02de\u02dc\3\2\2\2\u02df\u02e2\3\2\2\2\u02e0\u02de\3\2\2"+ - "\2\u02e0\u02e1\3\2\2\2\u02e1{\3\2\2\2\u02e2\u02e0\3\2\2\2\u02e3\u02eb"+ - "\5\u0086D\2\u02e4\u02ea\5~@\2\u02e5\u02ea\5\u0082B\2\u02e6\u02ea\5\u0084"+ - "C\2\u02e7\u02ea\5\u0080A\2\u02e8\u02ea\5\u0094K\2\u02e9\u02e4\3\2\2\2"+ - "\u02e9\u02e5\3\2\2\2\u02e9\u02e6\3\2\2\2\u02e9\u02e7\3\2\2\2\u02e9\u02e8"+ - "\3\2\2\2\u02ea\u02ed\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ec\3\2\2\2\u02ec"+ - "}\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ee\u02ef\78\2\2\u02ef\u02f0\78\2\2\u02f0"+ - "\u02f1\5,\27\2\u02f1\u02f2\79\2\2\u02f2\u02f3\79\2\2\u02f3\177\3\2\2\2"+ - "\u02f4\u02f5\78\2\2\u02f5\u02f6\79\2\2\u02f6\u0081\3\2\2\2\u02f7\u02f8"+ - "\78\2\2\u02f8\u02f9\5,\27\2\u02f9\u02fa\79\2\2\u02fa\u0083\3\2\2\2\u02fb"+ - "\u0302\7:\2\2\u02fc\u0303\5\u00b4[\2\u02fd\u0303\5\u00b2Z\2\u02fe\u0303"+ - "\7u\2\2\u02ff\u0303\5\u008aF\2\u0300\u0303\5\u0088E\2\u0301\u0303\5\u008c"+ - "G\2\u0302\u02fc\3\2\2\2\u0302\u02fd\3\2\2\2\u0302\u02fe\3\2\2\2\u0302"+ - "\u02ff\3\2\2\2\u0302\u0300\3\2\2\2\u0302\u0301\3\2\2\2\u0303\u0085\3\2"+ - "\2\2\u0304\u0311\7m\2\2\u0305\u0311\7n\2\2\u0306\u0311\5\u00b2Z\2\u0307"+ - "\u0311\5\u0088E\2\u0308\u0311\5\u008aF\2\u0309\u0311\5\u008cG\2\u030a"+ - "\u0311\5\u00a0Q\2\u030b\u0311\5\u0092J\2\u030c\u0311\5\u008eH\2\u030d"+ - "\u0311\5\u0090I\2\u030e\u0311\5\u00aeX\2\u030f\u0311\5\u0098M\2\u0310"+ - "\u0304\3\2\2\2\u0310\u0305\3\2\2\2\u0310\u0306\3\2\2\2\u0310\u0307\3\2"+ - "\2\2\u0310\u0308\3\2\2\2\u0310\u0309\3\2\2\2\u0310\u030a\3\2\2\2\u0310"+ - "\u030b\3\2\2\2\u0310\u030c\3\2\2\2\u0310\u030d\3\2\2\2\u0310\u030e\3\2"+ - "\2\2\u0310\u030f\3\2\2\2\u0311\u0087\3\2\2\2\u0312\u0313\7\"\2\2\u0313"+ - "\u0314\5\32\16\2\u0314\u0089\3\2\2\2\u0315\u0317\7\35\2\2\u0316\u0318"+ - "\5,\27\2\u0317\u0316\3\2\2\2\u0317\u0318\3\2\2\2\u0318\u0319\3\2\2\2\u0319"+ - "\u031a\7\36\2\2\u031a\u008b\3\2\2\2\u031b\u031c\7;\2\2\u031c\u008d\3\2"+ - "\2\2\u031d\u031e\7\t\2\2\u031e\u031f\7\37\2\2\u031f\u0320\5,\27\2\u0320"+ - "\u0321\7 \2\2\u0321\u008f\3\2\2\2\u0322\u0323\7\n\2\2\u0323\u0324\7\37"+ - "\2\2\u0324\u0325\5,\27\2\u0325\u0326\7 \2\2\u0326\u0091\3\2\2\2\u0327"+ - "\u0328\5\32\16\2\u0328\u0329\5\u0094K\2\u0329\u0093\3\2\2\2\u032a\u0331"+ - "\7\35\2\2\u032b\u032d\5\u0096L\2\u032c\u032e\7\30\2\2\u032d\u032c\3\2"+ - "\2\2\u032d\u032e\3\2\2\2\u032e\u0330\3\2\2\2\u032f\u032b\3\2\2\2\u0330"+ - "\u0333\3\2\2\2\u0331\u032f\3\2\2\2\u0331\u0332\3\2\2\2\u0332\u0334\3\2"+ - "\2\2\u0333\u0331\3\2\2\2\u0334\u0335\7\36\2\2\u0335\u0095\3\2\2\2\u0336"+ - "\u0339\5.\30\2\u0337\u0339\7l\2\2\u0338\u0336\3\2\2\2\u0338\u0337\3\2"+ - "\2\2\u0339\u0097\3\2\2\2\u033a\u033d\5\u009aN\2\u033b\u033d\5\u009cO\2"+ - "\u033c\u033a\3\2\2\2\u033c\u033b\3\2\2\2\u033d\u0099\3\2\2\2\u033e\u033f"+ - "\5\32\16\2\u033f\u0340\7<\2\2\u0340\u0341\7n\2\2\u0341\u009b\3\2\2\2\u0342"+ - "\u0343\7\34\2\2\u0343\u0345\7\35\2\2\u0344\u0346\5(\25\2\u0345\u0344\3"+ - "\2\2\2\u0345\u0346\3\2\2\2\u0346\u0347\3\2\2\2\u0347\u034a\7\36\2\2\u0348"+ - "\u0349\7H\2\2\u0349\u034b\5\u009eP\2\u034a\u0348\3\2\2\2\u034a\u034b\3"+ - "\2\2\2\u034b\u034c\3\2\2\2\u034c\u034e\7\37\2\2\u034d\u034f\5,\27\2\u034e"+ - "\u034d\3\2\2\2\u034e\u034f\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0351\7 "+ - "\2\2\u0351\u009d\3\2\2\2\u0352\u0353\7\35\2\2\u0353\u035b\7\36\2\2\u0354"+ - "\u0358\5\u00a2R\2\u0355\u0359\7l\2\2\u0356\u0359\7$\2\2\u0357\u0359\7"+ - "\61\2\2\u0358\u0355\3\2\2\2\u0358\u0356\3\2\2\2\u0358\u0357\3\2\2\2\u0358"+ - "\u0359\3\2\2\2\u0359\u035b\3\2\2\2\u035a\u0352\3\2\2\2\u035a\u0354\3\2"+ - "\2\2\u035b\u009f\3\2\2\2\u035c\u0365\7\37\2\2\u035d\u0362\5\u00acW\2\u035e"+ - "\u035f\7\30\2\2\u035f\u0361\5\u00acW\2\u0360\u035e\3\2\2\2\u0361\u0364"+ - "\3\2\2\2\u0362\u0360\3\2\2\2\u0362\u0363\3\2\2\2\u0363\u0366\3\2\2\2\u0364"+ - "\u0362\3\2\2\2\u0365\u035d\3\2\2\2\u0365\u0366\3\2\2\2\u0366\u0367\3\2"+ - "\2\2\u0367\u036d\7 \2\2\u0368\u0369\7=\2\2\u0369\u036a\5,\27\2\u036a\u036b"+ - "\7>\2\2\u036b\u036d\3\2\2\2\u036c\u035c\3\2\2\2\u036c\u0368\3\2\2\2\u036d"+ - "\u00a1\3\2\2\2\u036e\u0372\5\32\16\2\u036f\u0372\7m\2\2\u0370\u0372\5"+ - "\u00a4S\2\u0371\u036e\3\2\2\2\u0371\u036f\3\2\2\2\u0371\u0370\3\2\2\2"+ - "\u0372\u00a3\3\2\2\2\u0373\u0376\5\u00a6T\2\u0374\u0376\5\u00a8U\2\u0375"+ - "\u0373\3\2\2\2\u0375\u0374\3\2\2\2\u0376\u00a5\3\2\2\2\u0377\u0378\7\34"+ - "\2\2\u0378\u0379\7\35\2\2\u0379\u037a\7$\2\2\u037a\u037b\7\36\2\2\u037b"+ - "\u00a7\3\2\2\2\u037c\u037d\7\34\2\2\u037d\u0386\7\35\2\2\u037e\u0383\5"+ - "\u009eP\2\u037f\u0380\7\30\2\2\u0380\u0382\5\u009eP\2\u0381\u037f\3\2"+ - "\2\2\u0382\u0385\3\2\2\2\u0383\u0381\3\2\2\2\u0383\u0384\3\2\2\2\u0384"+ - "\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0386\u037e\3\2\2\2\u0386\u0387\3\2"+ - "\2\2\u0387\u0388\3\2\2\2\u0388\u0389\7\36\2\2\u0389\u038a\7H\2\2\u038a"+ - "\u038b\5\u009eP\2\u038b\u00a9\3\2\2\2\u038c\u038e\5\u00a2R\2\u038d\u038f"+ - "\7l\2\2\u038e\u038d\3\2\2\2\u038e\u038f\3\2\2\2\u038f\u00ab\3\2\2\2\u0390"+ - "\u0393\5.\30\2\u0391\u0393\7u\2\2\u0392\u0390\3\2\2\2\u0392\u0391\3\2"+ - "\2\2\u0393\u0394\3\2\2\2\u0394\u0395\t\t\2\2\u0395\u0396\5.\30\2\u0396"+ - "\u00ad\3\2\2\2\u0397\u0399\78\2\2\u0398\u039a\5,\27\2\u0399\u0398\3\2"+ - "\2\2\u0399\u039a\3\2\2\2\u039a\u039b\3\2\2\2\u039b\u039c\79\2\2\u039c"+ - "\u00af\3\2\2\2\u039d\u039e\5\u00b2Z\2\u039e\u00b1\3\2\2\2\u039f\u03a0"+ - "\7k\2\2\u03a0\u00b3\3\2\2\2\u03a1\u03a2\t\n\2\2\u03a2\u00b5\3\2\2\2e\u00be"+ - "\u00c2\u00d2\u00d8\u00e0\u00e7\u00f2\u0108\u0110\u0115\u0118\u011c\u0127"+ - "\u0130\u0133\u013a\u0141\u0143\u014a\u014f\u0153\u0157\u0164\u016b\u0172"+ - "\u017c\u0180\u0188\u018a\u0196\u019c\u01a0\u01a4\u01af\u01b5\u01c4\u01ca"+ - "\u01ce\u01d2\u01d9\u01e0\u01e6\u01eb\u01ed\u01f1\u01f8\u01ff\u0208\u0214"+ - "\u021e\u022a\u022e\u0237\u023e\u0254\u0259\u025e\u0262\u026e\u0276\u027a"+ - "\u0281\u0288\u028e\u0295\u029d\u02a4\u02aa\u02b0\u02b6\u02bc\u02c5\u02cb"+ - "\u02d2\u02e0\u02e9\u02eb\u0302\u0310\u0317\u032d\u0331\u0338\u033c\u0345"+ - "\u034a\u034e\u0358\u035a\u0362\u0365\u036c\u0371\u0375\u0383\u0386\u038e"+ - "\u0392\u0399"; + "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\5"+ + "\3\u00bd\n\3\3\3\3\3\5\3\u00c1\n\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5"+ + "\3\5\3\5\3\6\3\6\3\6\5\6\u00d1\n\6\3\6\3\6\7\6\u00d5\n\6\f\6\16\6\u00d8"+ + "\13\6\3\6\3\6\3\6\7\6\u00dd\n\6\f\6\16\6\u00e0\13\6\3\7\3\7\3\7\3\7\5"+ + "\7\u00e6\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\t\u00f1\n\t\3\n\3\n"+ + "\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3"+ + "\r\3\r\5\r\u0107\n\r\3\r\3\r\3\r\3\r\7\r\u010d\n\r\f\r\16\r\u0110\13\r"+ + "\3\16\3\16\5\16\u0114\n\16\3\16\5\16\u0117\n\16\3\16\3\16\5\16\u011b\n"+ + "\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\5\20\u0124\n\20\3\20\3\20\3\20"+ + "\3\20\3\20\7\20\u012b\n\20\f\20\16\20\u012e\13\20\5\20\u0130\n\20\3\21"+ + "\3\21\3\21\3\21\3\21\5\21\u0137\n\21\3\21\3\21\3\21\3\21\3\21\5\21\u013e"+ + "\n\21\5\21\u0140\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u0147\n\22\3\22\3"+ + "\22\3\22\5\22\u014c\n\22\3\22\3\22\5\22\u0150\n\22\3\22\3\22\5\22\u0154"+ + "\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\7\24\u015f\n\24\f\24"+ + "\16\24\u0162\13\24\3\25\3\25\3\25\3\25\5\25\u0168\n\25\3\26\3\26\3\26"+ + "\7\26\u016d\n\26\f\26\16\26\u0170\13\26\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\5\27\u0179\n\27\3\30\3\30\5\30\u017d\n\30\3\30\3\30\3\30\3\30\3"+ + "\30\3\30\7\30\u0185\n\30\f\30\16\30\u0188\13\30\3\30\3\30\3\30\3\31\3"+ + "\31\3\31\3\31\7\31\u0191\n\31\f\31\16\31\u0194\13\31\3\32\3\32\3\32\5"+ + "\32\u0199\n\32\3\32\3\32\5\32\u019d\n\32\3\32\3\32\5\32\u01a1\n\32\3\32"+ + "\3\32\3\32\3\33\3\33\3\33\3\33\7\33\u01aa\n\33\f\33\16\33\u01ad\13\33"+ + "\3\34\3\34\3\34\5\34\u01b2\n\34\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36"+ + "\3\36\3\36\3\36\7\36\u01bf\n\36\f\36\16\36\u01c2\13\36\3\37\3\37\3\37"+ + "\5\37\u01c7\n\37\3\37\3\37\5\37\u01cb\n\37\3\37\3\37\5\37\u01cf\n\37\3"+ + " \3 \3 \3 \3 \5 \u01d6\n \3 \3 \3 \7 \u01db\n \f \16 \u01de\13 \3!\3!"+ + "\3!\5!\u01e3\n!\3!\3!\3!\5!\u01e8\n!\5!\u01ea\n!\3!\3!\5!\u01ee\n!\3\""+ + "\3\"\3\"\3#\3#\5#\u01f5\n#\3#\3#\3#\7#\u01fa\n#\f#\16#\u01fd\13#\3#\3"+ + "#\3#\3$\3$\3$\5$\u0205\n$\3$\3$\3$\3%\3%\3%\3%\3%\6%\u020f\n%\r%\16%\u0210"+ + "\3%\3%\3%\3%\3&\3&\6&\u0219\n&\r&\16&\u021a\3&\3&\3&\3\'\3\'\3\'\3\'\3"+ + "\'\6\'\u0225\n\'\r\'\16\'\u0226\3\'\3\'\5\'\u022b\n\'\3\'\3\'\3\'\3(\3"+ + "(\3(\3(\5(\u0234\n(\3(\3(\3(\7(\u0239\n(\f(\16(\u023c\13(\3(\3(\3(\3)"+ + "\3)\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\6*\u024f\n*\r*\16*\u0250\3+\3"+ + "+\3+\5+\u0256\n+\3+\3+\3+\5+\u025b\n+\7+\u025d\n+\f+\16+\u0260\13+\3+"+ + "\3+\3+\3+\3,\3,\3,\7,\u0269\n,\f,\16,\u026c\13,\3-\3-\3-\7-\u0271\n-\f"+ + "-\16-\u0274\13-\3.\5.\u0277\n.\3.\3.\3/\3/\3/\5/\u027e\n/\3\60\3\60\3"+ + "\60\7\60\u0283\n\60\f\60\16\60\u0286\13\60\3\61\3\61\3\61\5\61\u028b\n"+ + "\61\3\62\3\62\3\62\7\62\u0290\n\62\f\62\16\62\u0293\13\62\3\63\3\63\3"+ + "\63\7\63\u0298\n\63\f\63\16\63\u029b\13\63\3\64\3\64\3\64\3\64\5\64\u02a1"+ + "\n\64\3\65\3\65\3\65\3\65\5\65\u02a7\n\65\3\66\3\66\3\66\3\66\5\66\u02ad"+ + "\n\66\3\67\3\67\3\67\3\67\5\67\u02b3\n\67\38\38\38\38\58\u02b9\n8\39\3"+ + "9\39\39\39\79\u02c0\n9\f9\169\u02c3\139\3:\7:\u02c6\n:\f:\16:\u02c9\13"+ + ":\3:\3:\3;\3;\5;\u02cf\n;\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\7=\u02db\n=\f"+ + "=\16=\u02de\13=\3>\3>\3>\3>\3>\3>\7>\u02e6\n>\f>\16>\u02e9\13>\3?\3?\3"+ + "?\3?\3?\3?\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\5B\u02ff\nB\3C\3"+ + "C\3C\3C\3C\3C\3C\3C\3C\3C\3C\3C\5C\u030d\nC\3D\3D\3D\3E\3E\5E\u0314\n"+ + "E\3E\3E\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3J\3J\3J\5J\u032a"+ + "\nJ\7J\u032c\nJ\fJ\16J\u032f\13J\3J\3J\3K\3K\5K\u0335\nK\3L\3L\5L\u0339"+ + "\nL\3M\3M\3M\3M\3N\3N\3N\5N\u0342\nN\3N\3N\3N\5N\u0347\nN\3N\3N\5N\u034b"+ + "\nN\3N\3N\3O\3O\3O\3O\3O\3O\5O\u0355\nO\5O\u0357\nO\3P\3P\3P\3P\7P\u035d"+ + "\nP\fP\16P\u0360\13P\5P\u0362\nP\3P\3P\3P\3P\3P\5P\u0369\nP\3Q\3Q\3Q\5"+ + "Q\u036e\nQ\3R\3R\5R\u0372\nR\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\7T\u037e\n"+ + "T\fT\16T\u0381\13T\5T\u0383\nT\3T\3T\3T\3T\3U\3U\5U\u038b\nU\3V\3V\5V"+ + "\u038f\nV\3V\3V\3V\3W\3W\5W\u0396\nW\3W\3W\3X\3X\3Y\3Y\3Z\3Z\3Z\2\2[\2"+ + "\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL"+ + "NPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e"+ + "\u0090\u0092\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6"+ + "\u00a8\u00aa\u00ac\u00ae\u00b0\u00b2\2\n\4\2\t\tjj\3\2ST\3\2\f\25\4\2"+ + "\6\6$.\3\2\60\61\4\2##\62\64\4\2\13\13ll\4\2>jmm\2\u03cb\2\u00b4\3\2\2"+ + "\2\4\u00bc\3\2\2\2\6\u00c2\3\2\2\2\b\u00c5\3\2\2\2\n\u00d6\3\2\2\2\f\u00e5"+ + "\3\2\2\2\16\u00e7\3\2\2\2\20\u00f0\3\2\2\2\22\u00f2\3\2\2\2\24\u00f7\3"+ + "\2\2\2\26\u00fb\3\2\2\2\30\u0101\3\2\2\2\32\u0116\3\2\2\2\34\u011c\3\2"+ + "\2\2\36\u011e\3\2\2\2 \u0131\3\2\2\2\"\u0141\3\2\2\2$\u0155\3\2\2\2&\u015b"+ + "\3\2\2\2(\u0163\3\2\2\2*\u0169\3\2\2\2,\u0178\3\2\2\2.\u017c\3\2\2\2\60"+ + "\u018c\3\2\2\2\62\u0195\3\2\2\2\64\u01a5\3\2\2\2\66\u01ae\3\2\2\28\u01b6"+ + "\3\2\2\2:\u01b9\3\2\2\2<\u01c3\3\2\2\2>\u01d5\3\2\2\2@\u01df\3\2\2\2B"+ + "\u01ef\3\2\2\2D\u01f4\3\2\2\2F\u0201\3\2\2\2H\u0209\3\2\2\2J\u0218\3\2"+ + "\2\2L\u021f\3\2\2\2N\u022f\3\2\2\2P\u0240\3\2\2\2R\u0249\3\2\2\2T\u0252"+ + "\3\2\2\2V\u0265\3\2\2\2X\u026d\3\2\2\2Z\u0276\3\2\2\2\\\u027a\3\2\2\2"+ + "^\u027f\3\2\2\2`\u0287\3\2\2\2b\u028c\3\2\2\2d\u0294\3\2\2\2f\u029c\3"+ + "\2\2\2h\u02a2\3\2\2\2j\u02a8\3\2\2\2l\u02ae\3\2\2\2n\u02b4\3\2\2\2p\u02ba"+ + "\3\2\2\2r\u02c7\3\2\2\2t\u02ce\3\2\2\2v\u02d0\3\2\2\2x\u02d7\3\2\2\2z"+ + "\u02df\3\2\2\2|\u02ea\3\2\2\2~\u02f0\3\2\2\2\u0080\u02f3\3\2\2\2\u0082"+ + "\u02f7\3\2\2\2\u0084\u030c\3\2\2\2\u0086\u030e\3\2\2\2\u0088\u0311\3\2"+ + "\2\2\u008a\u0317\3\2\2\2\u008c\u0319\3\2\2\2\u008e\u031e\3\2\2\2\u0090"+ + "\u0323\3\2\2\2\u0092\u0326\3\2\2\2\u0094\u0334\3\2\2\2\u0096\u0338\3\2"+ + "\2\2\u0098\u033a\3\2\2\2\u009a\u033e\3\2\2\2\u009c\u0356\3\2\2\2\u009e"+ + "\u0368\3\2\2\2\u00a0\u036d\3\2\2\2\u00a2\u0371\3\2\2\2\u00a4\u0373\3\2"+ + "\2\2\u00a6\u0378\3\2\2\2\u00a8\u0388\3\2\2\2\u00aa\u038e\3\2\2\2\u00ac"+ + "\u0393\3\2\2\2\u00ae\u0399\3\2\2\2\u00b0\u039b\3\2\2\2\u00b2\u039d\3\2"+ + "\2\2\u00b4\u00b5\5\4\3\2\u00b5\u00b6\7\2\2\3\u00b6\3\3\2\2\2\u00b7\u00b8"+ + "\7i\2\2\u00b8\u00b9\7h\2\2\u00b9\u00ba\5\u00b0Y\2\u00ba\u00bb\7\3\2\2"+ + "\u00bb\u00bd\3\2\2\2\u00bc\u00b7\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00c0"+ + "\3\2\2\2\u00be\u00c1\5\b\5\2\u00bf\u00c1\5\6\4\2\u00c0\u00be\3\2\2\2\u00c0"+ + "\u00bf\3\2\2\2\u00c1\5\3\2\2\2\u00c2\u00c3\5\n\6\2\u00c3\u00c4\5*\26\2"+ + "\u00c4\7\3\2\2\2\u00c5\u00c6\7\4\2\2\u00c6\u00c7\7\5\2\2\u00c7\u00c8\7"+ + "u\2\2\u00c8\u00c9\7\6\2\2\u00c9\u00ca\5\u00aeX\2\u00ca\u00cb\7\3\2\2\u00cb"+ + "\u00cc\5\n\6\2\u00cc\t\3\2\2\2\u00cd\u00d1\5\f\7\2\u00ce\u00d1\5\16\b"+ + "\2\u00cf\u00d1\5\36\20\2\u00d0\u00cd\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d0"+ + "\u00cf\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\7\3\2\2\u00d3\u00d5\3\2"+ + "\2\2\u00d4\u00d0\3\2\2\2\u00d5\u00d8\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6"+ + "\u00d7\3\2\2\2\u00d7\u00de\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d9\u00da\5\20"+ + "\t\2\u00da\u00db\7\3\2\2\u00db\u00dd\3\2\2\2\u00dc\u00d9\3\2\2\2\u00dd"+ + "\u00e0\3\2\2\2\u00de\u00dc\3\2\2\2\u00de\u00df\3\2\2\2\u00df\13\3\2\2"+ + "\2\u00e0\u00de\3\2\2\2\u00e1\u00e6\5\22\n\2\u00e2\u00e6\5\24\13\2\u00e3"+ + "\u00e6\5\26\f\2\u00e4\u00e6\5\30\r\2\u00e5\u00e1\3\2\2\2\u00e5\u00e2\3"+ + "\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e4\3\2\2\2\u00e6\r\3\2\2\2\u00e7\u00e8"+ + "\7\7\2\2\u00e8\u00e9\7\5\2\2\u00e9\u00ea\7u\2\2\u00ea\u00eb\7\6\2\2\u00eb"+ + "\u00ec\5\u00aeX\2\u00ec\17\3\2\2\2\u00ed\u00f1\5\"\22\2\u00ee\u00f1\5"+ + " \21\2\u00ef\u00f1\5$\23\2\u00f0\u00ed\3\2\2\2\u00f0\u00ee\3\2\2\2\u00f0"+ + "\u00ef\3\2\2\2\u00f1\21\3\2\2\2\u00f2\u00f3\7\7\2\2\u00f3\u00f4\7Y\2\2"+ + "\u00f4\u00f5\7R\2\2\u00f5\u00f6\5\u00aeX\2\u00f6\23\3\2\2\2\u00f7\u00f8"+ + "\7\7\2\2\u00f8\u00f9\7\b\2\2\u00f9\u00fa\t\2\2\2\u00fa\25\3\2\2\2\u00fb"+ + "\u00fc\7\7\2\2\u00fc\u00fd\7Y\2\2\u00fd\u00fe\7C\2\2\u00fe\u00ff\7J\2"+ + "\2\u00ff\u0100\t\3\2\2\u0100\27\3\2\2\2\u0101\u0106\7\7\2\2\u0102\u0103"+ + "\7\n\2\2\u0103\u0107\5\32\16\2\u0104\u0105\7Y\2\2\u0105\u0107\7\n\2\2"+ + "\u0106\u0102\3\2\2\2\u0106\u0104\3\2\2\2\u0107\u010e\3\2\2\2\u0108\u0109"+ + "\5\34\17\2\u0109\u010a\7\6\2\2\u010a\u010b\5\u00b0Y\2\u010b\u010d\3\2"+ + "\2\2\u010c\u0108\3\2\2\2\u010d\u0110\3\2\2\2\u010e\u010c\3\2\2\2\u010e"+ + "\u010f\3\2\2\2\u010f\31\3\2\2\2\u0110\u010e\3\2\2\2\u0111\u0114\7u\2\2"+ + "\u0112\u0114\5\u00b2Z\2\u0113\u0111\3\2\2\2\u0113\u0112\3\2\2\2\u0114"+ + "\u0115\3\2\2\2\u0115\u0117\7\13\2\2\u0116\u0113\3\2\2\2\u0116\u0117\3"+ + "\2\2\2\u0117\u011a\3\2\2\2\u0118\u011b\7u\2\2\u0119\u011b\5\u00b2Z\2\u011a"+ + "\u0118\3\2\2\2\u011a\u0119\3\2\2\2\u011b\33\3\2\2\2\u011c\u011d\t\4\2"+ + "\2\u011d\35\3\2\2\2\u011e\u011f\7\26\2\2\u011f\u0123\7\4\2\2\u0120\u0121"+ + "\7\5\2\2\u0121\u0122\7u\2\2\u0122\u0124\7\6\2\2\u0123\u0120\3\2\2\2\u0123"+ + "\u0124\3\2\2\2\u0124\u0125\3\2\2\2\u0125\u012f\5\u00aeX\2\u0126\u0127"+ + "\7H\2\2\u0127\u012c\5\u00aeX\2\u0128\u0129\7\27\2\2\u0129\u012b\5\u00ae"+ + "X\2\u012a\u0128\3\2\2\2\u012b\u012e\3\2\2\2\u012c\u012a\3\2\2\2\u012c"+ + "\u012d\3\2\2\2\u012d\u0130\3\2\2\2\u012e\u012c\3\2\2\2\u012f\u0126\3\2"+ + "\2\2\u012f\u0130\3\2\2\2\u0130\37\3\2\2\2\u0131\u0132\7\7\2\2\u0132\u0133"+ + "\7\30\2\2\u0133\u0136\5\u0086D\2\u0134\u0135\7G\2\2\u0135\u0137\5\u009c"+ + "O\2\u0136\u0134\3\2\2\2\u0136\u0137\3\2\2\2\u0137\u013f\3\2\2\2\u0138"+ + "\u0139\7\31\2\2\u0139\u0140\5,\27\2\u013a\u013d\7\32\2\2\u013b\u013c\7"+ + "\31\2\2\u013c\u013e\5,\27\2\u013d\u013b\3\2\2\2\u013d\u013e\3\2\2\2\u013e"+ + "\u0140\3\2\2\2\u013f\u0138\3\2\2\2\u013f\u013a\3\2\2\2\u0140!\3\2\2\2"+ + "\u0141\u0142\7\7\2\2\u0142\u0143\7\33\2\2\u0143\u0144\5\32\16\2\u0144"+ + "\u0146\7\34\2\2\u0145\u0147\5&\24\2\u0146\u0145\3\2\2\2\u0146\u0147\3"+ + "\2\2\2\u0147\u0148\3\2\2\2\u0148\u014b\7\35\2\2\u0149\u014a\7G\2\2\u014a"+ + "\u014c\5\u009cO\2\u014b\u0149\3\2\2\2\u014b\u014c\3\2\2\2\u014c\u0153"+ + "\3\2\2\2\u014d\u014f\7\36\2\2\u014e\u0150\5*\26\2\u014f\u014e\3\2\2\2"+ + "\u014f\u0150\3\2\2\2\u0150\u0151\3\2\2\2\u0151\u0154\7\37\2\2\u0152\u0154"+ + "\7\32\2\2\u0153\u014d\3\2\2\2\u0153\u0152\3\2\2\2\u0154#\3\2\2\2\u0155"+ + "\u0156\7\7\2\2\u0156\u0157\7 \2\2\u0157\u0158\5\32\16\2\u0158\u0159\7"+ + "G\2\2\u0159\u015a\5,\27\2\u015a%\3\2\2\2\u015b\u0160\5(\25\2\u015c\u015d"+ + "\7\27\2\2\u015d\u015f\5(\25\2\u015e\u015c\3\2\2\2\u015f\u0162\3\2\2\2"+ + "\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161\'\3\2\2\2\u0162\u0160\3"+ + "\2\2\2\u0163\u0164\7!\2\2\u0164\u0167\5\32\16\2\u0165\u0166\7G\2\2\u0166"+ + "\u0168\5\u009cO\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168)\3\2\2"+ + "\2\u0169\u016e\5,\27\2\u016a\u016b\7\27\2\2\u016b\u016d\5,\27\2\u016c"+ + "\u016a\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2"+ + "\2\2\u016f+\3\2\2\2\u0170\u016e\3\2\2\2\u0171\u0179\5.\30\2\u0172\u0179"+ + "\5D#\2\u0173\u0179\5H%\2\u0174\u0179\5L\'\2\u0175\u0179\5P)\2\u0176\u0179"+ + "\5R*\2\u0177\u0179\5V,\2\u0178\u0171\3\2\2\2\u0178\u0172\3\2\2\2\u0178"+ + "\u0173\3\2\2\2\u0178\u0174\3\2\2\2\u0178\u0175\3\2\2\2\u0178\u0176\3\2"+ + "\2\2\u0178\u0177\3\2\2\2\u0179-\3\2\2\2\u017a\u017d\5\60\31\2\u017b\u017d"+ + "\5\64\33\2\u017c\u017a\3\2\2\2\u017c\u017b\3\2\2\2\u017d\u0186\3\2\2\2"+ + "\u017e\u0185\5\60\31\2\u017f\u0185\58\35\2\u0180\u0185\5\64\33\2\u0181"+ + "\u0185\5:\36\2\u0182\u0185\5> \2\u0183\u0185\5B\"\2\u0184\u017e\3\2\2"+ + "\2\u0184\u017f\3\2\2\2\u0184\u0180\3\2\2\2\u0184\u0181\3\2\2\2\u0184\u0182"+ + "\3\2\2\2\u0184\u0183\3\2\2\2\u0185\u0188\3\2\2\2\u0186\u0184\3\2\2\2\u0186"+ + "\u0187\3\2\2\2\u0187\u0189\3\2\2\2\u0188\u0186\3\2\2\2\u0189\u018a\7D"+ + "\2\2\u018a\u018b\5,\27\2\u018b/\3\2\2\2\u018c\u018d\7>\2\2\u018d\u0192"+ + "\5\62\32\2\u018e\u018f\7\27\2\2\u018f\u0191\5\62\32\2\u0190\u018e\3\2"+ + "\2\2\u0191\u0194\3\2\2\2\u0192\u0190\3\2\2\2\u0192\u0193\3\2\2\2\u0193"+ + "\61\3\2\2\2\u0194\u0192\3\2\2\2\u0195\u0198\5\u0086D\2\u0196\u0197\7G"+ + "\2\2\u0197\u0199\5\u009cO\2\u0198\u0196\3\2\2\2\u0198\u0199\3\2\2\2\u0199"+ + "\u019c\3\2\2\2\u019a\u019b\7I\2\2\u019b\u019d\7J\2\2\u019c\u019a\3\2\2"+ + "\2\u019c\u019d\3\2\2\2\u019d\u01a0\3\2\2\2\u019e\u019f\7H\2\2\u019f\u01a1"+ + "\5\u0086D\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2\2\2\u01a1\u01a2\3\2\2"+ + "\2\u01a2\u01a3\7F\2\2\u01a3\u01a4\5,\27\2\u01a4\63\3\2\2\2\u01a5\u01a6"+ + "\7?\2\2\u01a6\u01ab\5\66\34\2\u01a7\u01a8\7\27\2\2\u01a8\u01aa\5\66\34"+ + "\2\u01a9\u01a7\3\2\2\2\u01aa\u01ad\3\2\2\2\u01ab\u01a9\3\2\2\2\u01ab\u01ac"+ + "\3\2\2\2\u01ac\65\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ae\u01b1\5\u0086D\2\u01af"+ + "\u01b0\7G\2\2\u01b0\u01b2\5\u009cO\2\u01b1\u01af\3\2\2\2\u01b1\u01b2\3"+ + "\2\2\2\u01b2\u01b3\3\2\2\2\u01b3\u01b4\7\31\2\2\u01b4\u01b5\5,\27\2\u01b5"+ + "\67\3\2\2\2\u01b6\u01b7\7@\2\2\u01b7\u01b8\5,\27\2\u01b89\3\2\2\2\u01b9"+ + "\u01ba\7A\2\2\u01ba\u01bb\7B\2\2\u01bb\u01c0\5<\37\2\u01bc\u01bd\7\27"+ + "\2\2\u01bd\u01bf\5<\37\2\u01be\u01bc\3\2\2\2\u01bf\u01c2\3\2\2\2\u01c0"+ + "\u01be\3\2\2\2\u01c0\u01c1\3\2\2\2\u01c1;\3\2\2\2\u01c2\u01c0\3\2\2\2"+ + "\u01c3\u01ca\5\u0086D\2\u01c4\u01c5\7G\2\2\u01c5\u01c7\5\u009cO\2\u01c6"+ + "\u01c4\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01c9\7\31"+ + "\2\2\u01c9\u01cb\5,\27\2\u01ca\u01c6\3\2\2\2\u01ca\u01cb\3\2\2\2\u01cb"+ + "\u01ce\3\2\2\2\u01cc\u01cd\7R\2\2\u01cd\u01cf\5\u00aeX\2\u01ce\u01cc\3"+ + "\2\2\2\u01ce\u01cf\3\2\2\2\u01cf=\3\2\2\2\u01d0\u01d1\7C\2\2\u01d1\u01d6"+ + "\7B\2\2\u01d2\u01d3\7L\2\2\u01d3\u01d4\7C\2\2\u01d4\u01d6\7B\2\2\u01d5"+ + "\u01d0\3\2\2\2\u01d5\u01d2\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u01dc\5@"+ + "!\2\u01d8\u01d9\7\27\2\2\u01d9\u01db\5@!\2\u01da\u01d8\3\2\2\2\u01db\u01de"+ + "\3\2\2\2\u01dc\u01da\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd?\3\2\2\2\u01de"+ + "\u01dc\3\2\2\2\u01df\u01e2\5,\27\2\u01e0\u01e3\7M\2\2\u01e1\u01e3\7N\2"+ + "\2\u01e2\u01e0\3\2\2\2\u01e2\u01e1\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3\u01e9"+ + "\3\2\2\2\u01e4\u01e7\7J\2\2\u01e5\u01e8\7S\2\2\u01e6\u01e8\7T\2\2\u01e7"+ + "\u01e5\3\2\2\2\u01e7\u01e6\3\2\2\2\u01e8\u01ea\3\2\2\2\u01e9\u01e4\3\2"+ + "\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\7R\2\2\u01ec"+ + "\u01ee\5\u00aeX\2\u01ed\u01eb\3\2\2\2\u01ed\u01ee\3\2\2\2\u01eeA\3\2\2"+ + "\2\u01ef\u01f0\7K\2\2\u01f0\u01f1\5\u0086D\2\u01f1C\3\2\2\2\u01f2\u01f5"+ + "\7O\2\2\u01f3\u01f5\7P\2\2\u01f4\u01f2\3\2\2\2\u01f4\u01f3\3\2\2\2\u01f5"+ + "\u01f6\3\2\2\2\u01f6\u01fb\5F$\2\u01f7\u01f8\7\27\2\2\u01f8\u01fa\5F$"+ + "\2\u01f9\u01f7\3\2\2\2\u01fa\u01fd\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fb\u01fc"+ + "\3\2\2\2\u01fc\u01fe\3\2\2\2\u01fd\u01fb\3\2\2\2\u01fe\u01ff\7Q\2\2\u01ff"+ + "\u0200\5,\27\2\u0200E\3\2\2\2\u0201\u0204\5\u0086D\2\u0202\u0203\7G\2"+ + "\2\u0203\u0205\5\u009cO\2\u0204\u0202\3\2\2\2\u0204\u0205\3\2\2\2\u0205"+ + "\u0206\3\2\2\2\u0206\u0207\7F\2\2\u0207\u0208\5,\27\2\u0208G\3\2\2\2\u0209"+ + "\u020a\7U\2\2\u020a\u020b\7\34\2\2\u020b\u020c\5*\26\2\u020c\u020e\7\35"+ + "\2\2\u020d\u020f\5J&\2\u020e\u020d\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u020e"+ + "\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u0212\3\2\2\2\u0212\u0213\7Y\2\2\u0213"+ + "\u0214\7D\2\2\u0214\u0215\5,\27\2\u0215I\3\2\2\2\u0216\u0217\7V\2\2\u0217"+ + "\u0219\5,\27\2\u0218\u0216\3\2\2\2\u0219\u021a\3\2\2\2\u021a\u0218\3\2"+ + "\2\2\u021a\u021b\3\2\2\2\u021b\u021c\3\2\2\2\u021c\u021d\7D\2\2\u021d"+ + "\u021e\5,\27\2\u021eK\3\2\2\2\u021f\u0220\7\\\2\2\u0220\u0221\7\34\2\2"+ + "\u0221\u0222\5*\26\2\u0222\u0224\7\35\2\2\u0223\u0225\5N(\2\u0224\u0223"+ + "\3\2\2\2\u0225\u0226\3\2\2\2\u0226\u0224\3\2\2\2\u0226\u0227\3\2\2\2\u0227"+ + "\u0228\3\2\2\2\u0228\u022a\7Y\2\2\u0229\u022b\5\u0086D\2\u022a\u0229\3"+ + "\2\2\2\u022a\u022b\3\2\2\2\u022b\u022c\3\2\2\2\u022c\u022d\7D\2\2\u022d"+ + "\u022e\5,\27\2\u022eM\3\2\2\2\u022f\u0233\7V\2\2\u0230\u0231\5\u0086D"+ + "\2\u0231\u0232\7G\2\2\u0232\u0234\3\2\2\2\u0233\u0230\3\2\2\2\u0233\u0234"+ + "\3\2\2\2\u0234\u0235\3\2\2\2\u0235\u023a\5\u009cO\2\u0236\u0237\7\"\2"+ + "\2\u0237\u0239\5\u009cO\2\u0238\u0236\3\2\2\2\u0239\u023c\3\2\2\2\u023a"+ + "\u0238\3\2\2\2\u023a\u023b\3\2\2\2\u023b\u023d\3\2\2\2\u023c\u023a\3\2"+ + "\2\2\u023d\u023e\7D\2\2\u023e\u023f\5,\27\2\u023fO\3\2\2\2\u0240\u0241"+ + "\7E\2\2\u0241\u0242\7\34\2\2\u0242\u0243\5*\26\2\u0243\u0244\7\35\2\2"+ + "\u0244\u0245\7Z\2\2\u0245\u0246\5,\27\2\u0246\u0247\7[\2\2\u0247\u0248"+ + "\5,\27\2\u0248Q\3\2\2\2\u0249\u024a\7W\2\2\u024a\u024b\7\36\2\2\u024b"+ + "\u024c\5*\26\2\u024c\u024e\7\37\2\2\u024d\u024f\5T+\2\u024e\u024d\3\2"+ + "\2\2\u024f\u0250\3\2\2\2\u0250\u024e\3\2\2\2\u0250\u0251\3\2\2\2\u0251"+ + "S\3\2\2\2\u0252\u0255\7X\2\2\u0253\u0256\7#\2\2\u0254\u0256\5\32\16\2"+ + "\u0255\u0253\3\2\2\2\u0255\u0254\3\2\2\2\u0256\u025e\3\2\2\2\u0257\u025a"+ + "\7\"\2\2\u0258\u025b\7#\2\2\u0259\u025b\5\32\16\2\u025a\u0258\3\2\2\2"+ + "\u025a\u0259\3\2\2\2\u025b\u025d\3\2\2\2\u025c\u0257\3\2\2\2\u025d\u0260"+ + "\3\2\2\2\u025e\u025c\3\2\2\2\u025e\u025f\3\2\2\2\u025f\u0261\3\2\2\2\u0260"+ + "\u025e\3\2\2\2\u0261\u0262\7\36\2\2\u0262\u0263\5*\26\2\u0263\u0264\7"+ + "\37\2\2\u0264U\3\2\2\2\u0265\u026a\5X-\2\u0266\u0267\7]\2\2\u0267\u0269"+ + "\5X-\2\u0268\u0266\3\2\2\2\u0269\u026c\3\2\2\2\u026a\u0268\3\2\2\2\u026a"+ + "\u026b\3\2\2\2\u026bW\3\2\2\2\u026c\u026a\3\2\2\2\u026d\u0272\5Z.\2\u026e"+ + "\u026f\7^\2\2\u026f\u0271\5Z.\2\u0270\u026e\3\2\2\2\u0271\u0274\3\2\2"+ + "\2\u0272\u0270\3\2\2\2\u0272\u0273\3\2\2\2\u0273Y\3\2\2\2\u0274\u0272"+ + "\3\2\2\2\u0275\u0277\7_\2\2\u0276\u0275\3\2\2\2\u0276\u0277\3\2\2\2\u0277"+ + "\u0278\3\2\2\2\u0278\u0279\5\\/\2\u0279[\3\2\2\2\u027a\u027d\5^\60\2\u027b"+ + "\u027c\t\5\2\2\u027c\u027e\5^\60\2\u027d\u027b\3\2\2\2\u027d\u027e\3\2"+ + "\2\2\u027e]\3\2\2\2\u027f\u0284\5`\61\2\u0280\u0281\7/\2\2\u0281\u0283"+ + "\5`\61\2\u0282\u0280\3\2\2\2\u0283\u0286\3\2\2\2\u0284\u0282\3\2\2\2\u0284"+ + "\u0285\3\2\2\2\u0285_\3\2\2\2\u0286\u0284\3\2\2\2\u0287\u028a\5b\62\2"+ + "\u0288\u0289\7`\2\2\u0289\u028b\5b\62\2\u028a\u0288\3\2\2\2\u028a\u028b"+ + "\3\2\2\2\u028ba\3\2\2\2\u028c\u0291\5d\63\2\u028d\u028e\t\6\2\2\u028e"+ + "\u0290\5d\63\2\u028f\u028d\3\2\2\2\u0290\u0293\3\2\2\2\u0291\u028f\3\2"+ + "\2\2\u0291\u0292\3\2\2\2\u0292c\3\2\2\2\u0293\u0291\3\2\2\2\u0294\u0299"+ + "\5f\64\2\u0295\u0296\t\7\2\2\u0296\u0298\5f\64\2\u0297\u0295\3\2\2\2\u0298"+ + "\u029b\3\2\2\2\u0299\u0297\3\2\2\2\u0299\u029a\3\2\2\2\u029ae\3\2\2\2"+ + "\u029b\u0299\3\2\2\2\u029c\u02a0\5h\65\2\u029d\u029e\7a\2\2\u029e\u029f"+ + "\7b\2\2\u029f\u02a1\5\u009cO\2\u02a0\u029d\3\2\2\2\u02a0\u02a1\3\2\2\2"+ + "\u02a1g\3\2\2\2\u02a2\u02a6\5j\66\2\u02a3\u02a4\7d\2\2\u02a4\u02a5\7c"+ + "\2\2\u02a5\u02a7\5\u009cO\2\u02a6\u02a3\3\2\2\2\u02a6\u02a7\3\2\2\2\u02a7"+ + "i\3\2\2\2\u02a8\u02ac\5l\67\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7G\2\2\u02ab"+ + "\u02ad\5\u009cO\2\u02ac\u02a9\3\2\2\2\u02ac\u02ad\3\2\2\2\u02adk\3\2\2"+ + "\2\u02ae\u02b2\5n8\2\u02af\u02b0\7g\2\2\u02b0\u02b1\7G\2\2\u02b1\u02b3"+ + "\5\u00a8U\2\u02b2\u02af\3\2\2\2\u02b2\u02b3\3\2\2\2\u02b3m\3\2\2\2\u02b4"+ + "\u02b8\5p9\2\u02b5\u02b6\7f\2\2\u02b6\u02b7\7G\2\2\u02b7\u02b9\5\u00a8"+ + "U\2\u02b8\u02b5\3\2\2\2\u02b8\u02b9\3\2\2\2\u02b9o\3\2\2\2\u02ba\u02c1"+ + "\5r:\2\u02bb\u02bc\7\6\2\2\u02bc\u02bd\7-\2\2\u02bd\u02be\3\2\2\2\u02be"+ + "\u02c0\5\u0090I\2\u02bf\u02bb\3\2\2\2\u02c0\u02c3\3\2\2\2\u02c1\u02bf"+ + "\3\2\2\2\u02c1\u02c2\3\2\2\2\u02c2q\3\2\2\2\u02c3\u02c1\3\2\2\2\u02c4"+ + "\u02c6\t\6\2\2\u02c5\u02c4\3\2\2\2\u02c6\u02c9\3\2\2\2\u02c7\u02c5\3\2"+ + "\2\2\u02c7\u02c8\3\2\2\2\u02c8\u02ca\3\2\2\2\u02c9\u02c7\3\2\2\2\u02ca"+ + "\u02cb\5t;\2\u02cbs\3\2\2\2\u02cc\u02cf\5x=\2\u02cd\u02cf\5v<\2\u02ce"+ + "\u02cc\3\2\2\2\u02ce\u02cd\3\2\2\2\u02cfu\3\2\2\2\u02d0\u02d1\7\65\2\2"+ + "\u02d1\u02d2\7 \2\2\u02d2\u02d3\5\u009cO\2\u02d3\u02d4\7\36\2\2\u02d4"+ + "\u02d5\5*\26\2\u02d5\u02d6\7\37\2\2\u02d6w\3\2\2\2\u02d7\u02dc\5z>\2\u02d8"+ + "\u02d9\7\66\2\2\u02d9\u02db\5z>\2\u02da\u02d8\3\2\2\2\u02db\u02de\3\2"+ + "\2\2\u02dc\u02da\3\2\2\2\u02dc\u02dd\3\2\2\2\u02ddy\3\2\2\2\u02de\u02dc"+ + "\3\2\2\2\u02df\u02e7\5\u0084C\2\u02e0\u02e6\5|?\2\u02e1\u02e6\5\u0080"+ + "A\2\u02e2\u02e6\5\u0082B\2\u02e3\u02e6\5~@\2\u02e4\u02e6\5\u0092J\2\u02e5"+ + "\u02e0\3\2\2\2\u02e5\u02e1\3\2\2\2\u02e5\u02e2\3\2\2\2\u02e5\u02e3\3\2"+ + "\2\2\u02e5\u02e4\3\2\2\2\u02e6\u02e9\3\2\2\2\u02e7\u02e5\3\2\2\2\u02e7"+ + "\u02e8\3\2\2\2\u02e8{\3\2\2\2\u02e9\u02e7\3\2\2\2\u02ea\u02eb\7\67\2\2"+ + "\u02eb\u02ec\7\67\2\2\u02ec\u02ed\5*\26\2\u02ed\u02ee\78\2\2\u02ee\u02ef"+ + "\78\2\2\u02ef}\3\2\2\2\u02f0\u02f1\7\67\2\2\u02f1\u02f2\78\2\2\u02f2\177"+ + "\3\2\2\2\u02f3\u02f4\7\67\2\2\u02f4\u02f5\5*\26\2\u02f5\u02f6\78\2\2\u02f6"+ + "\u0081\3\2\2\2\u02f7\u02fe\79\2\2\u02f8\u02ff\5\u00b2Z\2\u02f9\u02ff\5"+ + "\u00b0Y\2\u02fa\u02ff\7u\2\2\u02fb\u02ff\5\u0088E\2\u02fc\u02ff\5\u0086"+ + "D\2\u02fd\u02ff\5\u008aF\2\u02fe\u02f8\3\2\2\2\u02fe\u02f9\3\2\2\2\u02fe"+ + "\u02fa\3\2\2\2\u02fe\u02fb\3\2\2\2\u02fe\u02fc\3\2\2\2\u02fe\u02fd\3\2"+ + "\2\2\u02ff\u0083\3\2\2\2\u0300\u030d\7m\2\2\u0301\u030d\7n\2\2\u0302\u030d"+ + "\5\u00b0Y\2\u0303\u030d\5\u0086D\2\u0304\u030d\5\u0088E\2\u0305\u030d"+ + "\5\u008aF\2\u0306\u030d\5\u009eP\2\u0307\u030d\5\u0090I\2\u0308\u030d"+ + "\5\u008cG\2\u0309\u030d\5\u008eH\2\u030a\u030d\5\u00acW\2\u030b\u030d"+ + "\5\u0096L\2\u030c\u0300\3\2\2\2\u030c\u0301\3\2\2\2\u030c\u0302\3\2\2"+ + "\2\u030c\u0303\3\2\2\2\u030c\u0304\3\2\2\2\u030c\u0305\3\2\2\2\u030c\u0306"+ + "\3\2\2\2\u030c\u0307\3\2\2\2\u030c\u0308\3\2\2\2\u030c\u0309\3\2\2\2\u030c"+ + "\u030a\3\2\2\2\u030c\u030b\3\2\2\2\u030d\u0085\3\2\2\2\u030e\u030f\7!"+ + "\2\2\u030f\u0310\5\32\16\2\u0310\u0087\3\2\2\2\u0311\u0313\7\34\2\2\u0312"+ + "\u0314\5*\26\2\u0313\u0312\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0315\3\2"+ + "\2\2\u0315\u0316\7\35\2\2\u0316\u0089\3\2\2\2\u0317\u0318\7:\2\2\u0318"+ + "\u008b\3\2\2\2\u0319\u031a\7\t\2\2\u031a\u031b\7\36\2\2\u031b\u031c\5"+ + "*\26\2\u031c\u031d\7\37\2\2\u031d\u008d\3\2\2\2\u031e\u031f\7j\2\2\u031f"+ + "\u0320\7\36\2\2\u0320\u0321\5*\26\2\u0321\u0322\7\37\2\2\u0322\u008f\3"+ + "\2\2\2\u0323\u0324\5\32\16\2\u0324\u0325\5\u0092J\2\u0325\u0091\3\2\2"+ + "\2\u0326\u032d\7\34\2\2\u0327\u0329\5\u0094K\2\u0328\u032a\7\27\2\2\u0329"+ + "\u0328\3\2\2\2\u0329\u032a\3\2\2\2\u032a\u032c\3\2\2\2\u032b\u0327\3\2"+ + "\2\2\u032c\u032f\3\2\2\2\u032d\u032b\3\2\2\2\u032d\u032e\3\2\2\2\u032e"+ + "\u0330\3\2\2\2\u032f\u032d\3\2\2\2\u0330\u0331\7\35\2\2\u0331\u0093\3"+ + "\2\2\2\u0332\u0335\5,\27\2\u0333\u0335\7l\2\2\u0334\u0332\3\2\2\2\u0334"+ + "\u0333\3\2\2\2\u0335\u0095\3\2\2\2\u0336\u0339\5\u0098M\2\u0337\u0339"+ + "\5\u009aN\2\u0338\u0336\3\2\2\2\u0338\u0337\3\2\2\2\u0339\u0097\3\2\2"+ + "\2\u033a\u033b\5\32\16\2\u033b\u033c\7;\2\2\u033c\u033d\7n\2\2\u033d\u0099"+ + "\3\2\2\2\u033e\u033f\7\33\2\2\u033f\u0341\7\34\2\2\u0340\u0342\5&\24\2"+ + "\u0341\u0340\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\3\2\2\2\u0343\u0346"+ + "\7\35\2\2\u0344\u0345\7G\2\2\u0345\u0347\5\u009cO\2\u0346\u0344\3\2\2"+ + "\2\u0346\u0347\3\2\2\2\u0347\u0348\3\2\2\2\u0348\u034a\7\36\2\2\u0349"+ + "\u034b\5*\26\2\u034a\u0349\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ + "\2\2\u034c\u034d\7\37\2\2\u034d\u009b\3\2\2\2\u034e\u034f\7\34\2\2\u034f"+ + "\u0357\7\35\2\2\u0350\u0354\5\u00a0Q\2\u0351\u0355\7l\2\2\u0352\u0355"+ + "\7#\2\2\u0353\u0355\7\60\2\2\u0354\u0351\3\2\2\2\u0354\u0352\3\2\2\2\u0354"+ + "\u0353\3\2\2\2\u0354\u0355\3\2\2\2\u0355\u0357\3\2\2\2\u0356\u034e\3\2"+ + "\2\2\u0356\u0350\3\2\2\2\u0357\u009d\3\2\2\2\u0358\u0361\7\36\2\2\u0359"+ + "\u035e\5\u00aaV\2\u035a\u035b\7\27\2\2\u035b\u035d\5\u00aaV\2\u035c\u035a"+ + "\3\2\2\2\u035d\u0360\3\2\2\2\u035e\u035c\3\2\2\2\u035e\u035f\3\2\2\2\u035f"+ + "\u0362\3\2\2\2\u0360\u035e\3\2\2\2\u0361\u0359\3\2\2\2\u0361\u0362\3\2"+ + "\2\2\u0362\u0363\3\2\2\2\u0363\u0369\7\37\2\2\u0364\u0365\7<\2\2\u0365"+ + "\u0366\5*\26\2\u0366\u0367\7=\2\2\u0367\u0369\3\2\2\2\u0368\u0358\3\2"+ + "\2\2\u0368\u0364\3\2\2\2\u0369\u009f\3\2\2\2\u036a\u036e\5\32\16\2\u036b"+ + "\u036e\7m\2\2\u036c\u036e\5\u00a2R\2\u036d\u036a\3\2\2\2\u036d\u036b\3"+ + "\2\2\2\u036d\u036c\3\2\2\2\u036e\u00a1\3\2\2\2\u036f\u0372\5\u00a4S\2"+ + "\u0370\u0372\5\u00a6T\2\u0371\u036f\3\2\2\2\u0371\u0370\3\2\2\2\u0372"+ + "\u00a3\3\2\2\2\u0373\u0374\7\33\2\2\u0374\u0375\7\34\2\2\u0375\u0376\7"+ + "#\2\2\u0376\u0377\7\35\2\2\u0377\u00a5\3\2\2\2\u0378\u0379\7\33\2\2\u0379"+ + "\u0382\7\34\2\2\u037a\u037f\5\u009cO\2\u037b\u037c\7\27\2\2\u037c\u037e"+ + "\5\u009cO\2\u037d\u037b\3\2\2\2\u037e\u0381\3\2\2\2\u037f\u037d\3\2\2"+ + "\2\u037f\u0380\3\2\2\2\u0380\u0383\3\2\2\2\u0381\u037f\3\2\2\2\u0382\u037a"+ + "\3\2\2\2\u0382\u0383\3\2\2\2\u0383\u0384\3\2\2\2\u0384\u0385\7\35\2\2"+ + "\u0385\u0386\7G\2\2\u0386\u0387\5\u009cO\2\u0387\u00a7\3\2\2\2\u0388\u038a"+ + "\5\u00a0Q\2\u0389\u038b\7l\2\2\u038a\u0389\3\2\2\2\u038a\u038b\3\2\2\2"+ + "\u038b\u00a9\3\2\2\2\u038c\u038f\5,\27\2\u038d\u038f\7u\2\2\u038e\u038c"+ + "\3\2\2\2\u038e\u038d\3\2\2\2\u038f\u0390\3\2\2\2\u0390\u0391\t\b\2\2\u0391"+ + "\u0392\5,\27\2\u0392\u00ab\3\2\2\2\u0393\u0395\7\67\2\2\u0394\u0396\5"+ + "*\26\2\u0395\u0394\3\2\2\2\u0395\u0396\3\2\2\2\u0396\u0397\3\2\2\2\u0397"+ + "\u0398\78\2\2\u0398\u00ad\3\2\2\2\u0399\u039a\5\u00b0Y\2\u039a\u00af\3"+ + "\2\2\2\u039b\u039c\7k\2\2\u039c\u00b1\3\2\2\2\u039d\u039e\t\t\2\2\u039e"+ + "\u00b3\3\2\2\2e\u00bc\u00c0\u00d0\u00d6\u00de\u00e5\u00f0\u0106\u010e"+ + "\u0113\u0116\u011a\u0123\u012c\u012f\u0136\u013d\u013f\u0146\u014b\u014f"+ + "\u0153\u0160\u0167\u016e\u0178\u017c\u0184\u0186\u0192\u0198\u019c\u01a0"+ + "\u01ab\u01b1\u01c0\u01c6\u01ca\u01ce\u01d5\u01dc\u01e2\u01e7\u01e9\u01ed"+ + "\u01f4\u01fb\u0204\u0210\u021a\u0226\u022a\u0233\u023a\u0250\u0255\u025a"+ + "\u025e\u026a\u0272\u0276\u027d\u0284\u028a\u0291\u0299\u02a0\u02a6\u02ac"+ + "\u02b2\u02b8\u02c1\u02c7\u02ce\u02dc\u02e5\u02e7\u02fe\u030c\u0313\u0329"+ + "\u032d\u0334\u0338\u0341\u0346\u034a\u0354\u0356\u035e\u0361\u0368\u036d"+ + "\u0371\u037f\u0382\u038a\u038e\u0395"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/org/rumbledb/parser/JsoniqVisitor.java b/src/main/java/org/rumbledb/parser/JsoniqVisitor.java index 18c0597d98..9fcfac0333 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqVisitor.java @@ -91,12 +91,6 @@ public interface JsoniqVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitQname(JsoniqParser.QnameContext ctx); - /** - * Visit a parse tree produced by {@link JsoniqParser#nCNameOrKeyWord}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitNCNameOrKeyWord(JsoniqParser.NCNameOrKeyWordContext ctx); /** * Visit a parse tree produced by {@link JsoniqParser#dfPropertyName}. * @param ctx the parse tree From dc6ebb23dd6b37edb2f5bf623f5df2d92a16c945 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 17:01:44 +0200 Subject: [PATCH 090/142] Revert "fn:unordered allowed + clean grammar file." This reverts commit df3efba4eb36ae85e147c0cb9e21a4181a46a87b. --- .../context/BuiltinFunctionCatalogue.java | 2 +- .../java/org/rumbledb/parser/Jsoniq.tokens | 284 +- .../rumbledb/parser/JsoniqBaseVisitor.java | 7 + .../java/org/rumbledb/parser/JsoniqLexer.java | 597 ++-- .../org/rumbledb/parser/JsoniqLexer.tokens | 284 +- .../org/rumbledb/parser/JsoniqParser.java | 2593 +++++++++-------- .../org/rumbledb/parser/JsoniqVisitor.java | 6 + 7 files changed, 1896 insertions(+), 1877 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 5311155886..cf34dbda09 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -622,7 +622,7 @@ private static BuiltinFunction createBuiltinFunction( new Name( Name.FN_NS, "fn", - "unordered" + "unorder" ), "item*", "item*", diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.tokens b/src/main/java/org/rumbledb/parser/Jsoniq.tokens index ced2126dd5..d1974c069c 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.tokens +++ b/src/main/java/org/rumbledb/parser/Jsoniq.tokens @@ -57,51 +57,51 @@ T__55=56 T__56=57 T__57=58 T__58=59 -Kfor=60 -Klet=61 -Kwhere=62 -Kgroup=63 -Kby=64 -Korder=65 -Kreturn=66 -Kif=67 -Kin=68 -Kas=69 -Kat=70 -Kallowing=71 -Kempty=72 -Kcount=73 -Kstable=74 -Kascending=75 -Kdescending=76 -Ksome=77 -Kevery=78 -Ksatisfies=79 -Kcollation=80 -Kgreatest=81 -Kleast=82 -Kswitch=83 -Kcase=84 -Ktry=85 -Kcatch=86 -Kdefault=87 -Kthen=88 -Kelse=89 -Ktypeswitch=90 -Kor=91 -Kand=92 -Knot=93 -Kto=94 -Kinstance=95 -Kof=96 -Kstatically=97 -Kis=98 -Ktreat=99 -Kcast=100 -Kcastable=101 -Kversion=102 -Kjsoniq=103 -Kunordered=104 +T__59=60 +Kfor=61 +Klet=62 +Kwhere=63 +Kgroup=64 +Kby=65 +Korder=66 +Kreturn=67 +Kif=68 +Kin=69 +Kas=70 +Kat=71 +Kallowing=72 +Kempty=73 +Kcount=74 +Kstable=75 +Kascending=76 +Kdescending=77 +Ksome=78 +Kevery=79 +Ksatisfies=80 +Kcollation=81 +Kgreatest=82 +Kleast=83 +Kswitch=84 +Kcase=85 +Ktry=86 +Kcatch=87 +Kdefault=88 +Kthen=89 +Kelse=90 +Ktypeswitch=91 +Kor=92 +Kand=93 +Knot=94 +Kto=95 +Kinstance=96 +Kof=97 +Kstatically=98 +Kis=99 +Ktreat=100 +Kcast=101 +Kcastable=102 +Kversion=103 +Kjsoniq=104 STRING=105 ArgumentPlaceholder=106 NullLiteral=107 @@ -122,102 +122,102 @@ ContentChar=117 'declare'=5 'ordering'=6 'ordered'=7 -'decimal-format'=8 -':'=9 -'decimal-separator'=10 -'grouping-separator'=11 -'infinity'=12 -'minus-sign'=13 -'NaN'=14 -'percent'=15 -'per-mille'=16 -'zero-digit'=17 -'digit'=18 -'pattern-separator'=19 -'import'=20 -','=21 -'variable'=22 -':='=23 -'external'=24 -'function'=25 -'('=26 -')'=27 -'{'=28 -'}'=29 -'type'=30 -'$'=31 -'|'=32 -'*'=33 -'eq'=34 -'ne'=35 -'lt'=36 -'le'=37 -'gt'=38 -'ge'=39 -'!='=40 -'<'=41 -'<='=42 -'>'=43 -'>='=44 -'||'=45 -'+'=46 -'-'=47 -'div'=48 -'idiv'=49 -'mod'=50 -'validate'=51 -'!'=52 -'['=53 -']'=54 -'.'=55 -'$$'=56 -'#'=57 -'{|'=58 -'|}'=59 -'for'=60 -'let'=61 -'where'=62 -'group'=63 -'by'=64 -'order'=65 -'return'=66 -'if'=67 -'in'=68 -'as'=69 -'at'=70 -'allowing'=71 -'empty'=72 -'count'=73 -'stable'=74 -'ascending'=75 -'descending'=76 -'some'=77 -'every'=78 -'satisfies'=79 -'collation'=80 -'greatest'=81 -'least'=82 -'switch'=83 -'case'=84 -'try'=85 -'catch'=86 -'default'=87 -'then'=88 -'else'=89 -'typeswitch'=90 -'or'=91 -'and'=92 -'not'=93 -'to'=94 -'instance'=95 -'of'=96 -'statically'=97 -'is'=98 -'treat'=99 -'cast'=100 -'castable'=101 -'version'=102 -'jsoniq'=103 -'unordered'=104 +'unordered'=8 +'decimal-format'=9 +':'=10 +'decimal-separator'=11 +'grouping-separator'=12 +'infinity'=13 +'minus-sign'=14 +'NaN'=15 +'percent'=16 +'per-mille'=17 +'zero-digit'=18 +'digit'=19 +'pattern-separator'=20 +'import'=21 +','=22 +'variable'=23 +':='=24 +'external'=25 +'function'=26 +'('=27 +')'=28 +'{'=29 +'}'=30 +'type'=31 +'$'=32 +'|'=33 +'*'=34 +'eq'=35 +'ne'=36 +'lt'=37 +'le'=38 +'gt'=39 +'ge'=40 +'!='=41 +'<'=42 +'<='=43 +'>'=44 +'>='=45 +'||'=46 +'+'=47 +'-'=48 +'div'=49 +'idiv'=50 +'mod'=51 +'validate'=52 +'!'=53 +'['=54 +']'=55 +'.'=56 +'$$'=57 +'#'=58 +'{|'=59 +'|}'=60 +'for'=61 +'let'=62 +'where'=63 +'group'=64 +'by'=65 +'order'=66 +'return'=67 +'if'=68 +'in'=69 +'as'=70 +'at'=71 +'allowing'=72 +'empty'=73 +'count'=74 +'stable'=75 +'ascending'=76 +'descending'=77 +'some'=78 +'every'=79 +'satisfies'=80 +'collation'=81 +'greatest'=82 +'least'=83 +'switch'=84 +'case'=85 +'try'=86 +'catch'=87 +'default'=88 +'then'=89 +'else'=90 +'typeswitch'=91 +'or'=92 +'and'=93 +'not'=94 +'to'=95 +'instance'=96 +'of'=97 +'statically'=98 +'is'=99 +'treat'=100 +'cast'=101 +'castable'=102 +'version'=103 +'jsoniq'=104 '?'=106 'null'=107 diff --git a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java index 83170d5853..92740acf74 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java @@ -105,6 +105,13 @@ public class JsoniqBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitQname(JsoniqParser.QnameContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitNCNameOrKeyWord(JsoniqParser.NCNameOrKeyWordContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/src/main/java/org/rumbledb/parser/JsoniqLexer.java b/src/main/java/org/rumbledb/parser/JsoniqLexer.java index fa1e474817..cef633b58c 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.java +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.java @@ -3,14 +3,16 @@ // Java header package org.rumbledb.parser; -import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class JsoniqLexer extends Lexer { @@ -28,16 +30,16 @@ public class JsoniqLexer extends Lexer { T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, - Kfor=60, Klet=61, Kwhere=62, Kgroup=63, Kby=64, Korder=65, Kreturn=66, - Kif=67, Kin=68, Kas=69, Kat=70, Kallowing=71, Kempty=72, Kcount=73, Kstable=74, - Kascending=75, Kdescending=76, Ksome=77, Kevery=78, Ksatisfies=79, Kcollation=80, - Kgreatest=81, Kleast=82, Kswitch=83, Kcase=84, Ktry=85, Kcatch=86, Kdefault=87, - Kthen=88, Kelse=89, Ktypeswitch=90, Kor=91, Kand=92, Knot=93, Kto=94, - Kinstance=95, Kof=96, Kstatically=97, Kis=98, Ktreat=99, Kcast=100, Kcastable=101, - Kversion=102, Kjsoniq=103, Kunordered=104, STRING=105, ArgumentPlaceholder=106, - NullLiteral=107, Literal=108, NumericLiteral=109, BooleanLiteral=110, - IntegerLiteral=111, DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, - XQComment=116, ContentChar=117; + T__59=60, Kfor=61, Klet=62, Kwhere=63, Kgroup=64, Kby=65, Korder=66, Kreturn=67, + Kif=68, Kin=69, Kas=70, Kat=71, Kallowing=72, Kempty=73, Kcount=74, Kstable=75, + Kascending=76, Kdescending=77, Ksome=78, Kevery=79, Ksatisfies=80, Kcollation=81, + Kgreatest=82, Kleast=83, Kswitch=84, Kcase=85, Ktry=86, Kcatch=87, Kdefault=88, + Kthen=89, Kelse=90, Ktypeswitch=91, Kor=92, Kand=93, Knot=94, Kto=95, + Kinstance=96, Kof=97, Kstatically=98, Kis=99, Ktreat=100, Kcast=101, Kcastable=102, + Kversion=103, Kjsoniq=104, STRING=105, ArgumentPlaceholder=106, NullLiteral=107, + Literal=108, NumericLiteral=109, BooleanLiteral=110, IntegerLiteral=111, + DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, XQComment=116, + ContentChar=117; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -54,34 +56,35 @@ public class JsoniqLexer extends Lexer { "T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40", "T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48", "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", - "T__57", "T__58", "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", - "Kreturn", "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", - "Kstable", "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", + "T__57", "T__58", "T__59", "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", + "Korder", "Kreturn", "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", + "Kcount", "Kstable", "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", - "Kversion", "Kjsoniq", "Kunordered", "STRING", "ESC", "UNICODE", "HEX", - "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", "BooleanLiteral", - "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", "Digits", "WS", "NCName", - "NameStartChar", "NameChar", "XQComment", "ContentChar" + "Kversion", "Kjsoniq", "STRING", "ESC", "UNICODE", "HEX", "ArgumentPlaceholder", + "NullLiteral", "Literal", "NumericLiteral", "BooleanLiteral", "IntegerLiteral", + "DecimalLiteral", "DoubleLiteral", "Digits", "WS", "NCName", "NameStartChar", + "NameChar", "XQComment", "ContentChar" }; private static final String[] _LITERAL_NAMES = { null, "';'", "'module'", "'namespace'", "'='", "'declare'", "'ordering'", - "'ordered'", "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", - "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", - "'digit'", "'pattern-separator'", "'import'", "','", "'variable'", "':='", - "'external'", "'function'", "'('", "')'", "'{'", "'}'", "'type'", "'$'", - "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", "'gt'", "'ge'", "'!='", - "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", "'div'", "'idiv'", - "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", "'$$'", "'#'", "'{|'", - "'|}'", "'for'", "'let'", "'where'", "'group'", "'by'", "'order'", "'return'", - "'if'", "'in'", "'as'", "'at'", "'allowing'", "'empty'", "'count'", "'stable'", - "'ascending'", "'descending'", "'some'", "'every'", "'satisfies'", "'collation'", - "'greatest'", "'least'", "'switch'", "'case'", "'try'", "'catch'", "'default'", - "'then'", "'else'", "'typeswitch'", "'or'", "'and'", "'not'", "'to'", - "'instance'", "'of'", "'statically'", "'is'", "'treat'", "'cast'", "'castable'", - "'version'", "'jsoniq'", "'unordered'", null, "'?'", "'null'" + "'ordered'", "'unordered'", "'decimal-format'", "':'", "'decimal-separator'", + "'grouping-separator'", "'infinity'", "'minus-sign'", "'NaN'", "'percent'", + "'per-mille'", "'zero-digit'", "'digit'", "'pattern-separator'", "'import'", + "','", "'variable'", "':='", "'external'", "'function'", "'('", "')'", + "'{'", "'}'", "'type'", "'$'", "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", + "'gt'", "'ge'", "'!='", "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", + "'div'", "'idiv'", "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", + "'$$'", "'#'", "'{|'", "'|}'", "'for'", "'let'", "'where'", "'group'", + "'by'", "'order'", "'return'", "'if'", "'in'", "'as'", "'at'", "'allowing'", + "'empty'", "'count'", "'stable'", "'ascending'", "'descending'", "'some'", + "'every'", "'satisfies'", "'collation'", "'greatest'", "'least'", "'switch'", + "'case'", "'try'", "'catch'", "'default'", "'then'", "'else'", "'typeswitch'", + "'or'", "'and'", "'not'", "'to'", "'instance'", "'of'", "'statically'", + "'is'", "'treat'", "'cast'", "'castable'", "'version'", "'jsoniq'", null, + "'?'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -89,15 +92,15 @@ public class JsoniqLexer extends Lexer { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", "Kif", - "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", "Kascending", - "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", - "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", - "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", - "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", "Kjsoniq", "Kunordered", - "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", - "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", - "WS", "NCName", "XQComment", "ContentChar" + null, "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", + "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", + "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", + "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", + "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", + "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", + "Kjsoniq", "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", + "NumericLiteral", "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", + "DoubleLiteral", "WS", "NCName", "XQComment", "ContentChar" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -173,41 +176,41 @@ public JsoniqLexer(CharStream input) { "w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+ "\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3"+ "\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b"+ - "\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+ - "\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+ - "\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f"+ - "\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+ - "\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3"+ - "\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3"+ - "\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3"+ - "\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3"+ - "\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3"+ - "\25\3\25\3\25\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3"+ - "\27\3\27\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3"+ - "\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3"+ - "\35\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3 \3 \3!\3!\3\"\3\"\3#\3#\3#\3"+ - "$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3+\3+\3"+ - "+\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3\62"+ - "\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64\3\64"+ - "\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\38\38\39\39\39\3:\3:\3;\3;\3"+ - ";\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3@\3@\3"+ - "@\3A\3A\3A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\3D\3D\3D\3E\3E\3E\3"+ - "F\3F\3F\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3J\3J\3"+ - "J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3L\3L\3L\3M\3M\3"+ - "M\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3P\3P\3P\3"+ - "P\3P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3"+ - "R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3"+ - "V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3"+ - "Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\\3]\3]\3]\3]\3^\3"+ - "^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3`\3`\3`\3`\3`\3a\3a\3a\3b\3b\3b\3b\3b\3"+ - "b\3b\3b\3b\3b\3b\3c\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3f\3f\3f\3"+ - "f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3i\3i\3"+ - "i\3i\3i\3i\3i\3i\3i\3i\3j\3j\3j\7j\u034e\nj\fj\16j\u0351\13j\3j\3j\3k"+ - "\3k\3k\5k\u0358\nk\3l\3l\3l\3l\3l\3l\3m\3m\3n\3n\3o\3o\3o\3o\3o\3p\3p"+ - "\5p\u036b\np\3q\3q\3q\5q\u0370\nq\3r\3r\3r\3r\3r\3r\3r\3r\3r\5r\u037b"+ - "\nr\3s\3s\3t\3t\3t\3t\3t\7t\u0384\nt\ft\16t\u0387\13t\5t\u0389\nt\3u\3"+ - "u\3u\3u\3u\7u\u0390\nu\fu\16u\u0393\13u\5u\u0395\nu\5u\u0397\nu\3u\3u"+ - "\5u\u039b\nu\3u\3u\3v\6v\u03a0\nv\rv\16v\u03a1\3w\3w\3w\3w\3x\3x\7x\u03aa"+ + "\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3"+ + "\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3"+ + "\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r"+ + "\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16"+ + "\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ + "\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ + "\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24"+ + "\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25"+ + "\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\30"+ + "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\32\3\32\3\32"+ + "\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37\3\37\3 \3 \3 \3 \3 \3!\3!\3\""+ + "\3\"\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3"+ + "*\3*\3*\3+\3+\3,\3,\3,\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\62"+ + "\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65"+ + "\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\67\3\67\38\38\39\39\3"+ + ":\3:\3:\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3"+ + "@\3@\3A\3A\3A\3A\3A\3A\3B\3B\3B\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3"+ + "D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3I\3I\3J\3"+ + "J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3"+ + "M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3P\3P\3"+ + "P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3R\3"+ + "R\3S\3S\3S\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3U\3"+ + "V\3V\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3"+ + "Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3\\\3"+ + "\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3a\3a\3a\3a\3a\3a\3a\3a\3"+ + "a\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3d\3d\3d\3e\3e\3e\3e\3e\3"+ + "e\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3h\3"+ + "i\3i\3i\3i\3i\3i\3i\3j\3j\3j\7j\u034e\nj\fj\16j\u0351\13j\3j\3j\3k\3k"+ + "\3k\5k\u0358\nk\3l\3l\3l\3l\3l\3l\3m\3m\3n\3n\3o\3o\3o\3o\3o\3p\3p\5p"+ + "\u036b\np\3q\3q\3q\5q\u0370\nq\3r\3r\3r\3r\3r\3r\3r\3r\3r\5r\u037b\nr"+ + "\3s\3s\3t\3t\3t\3t\3t\7t\u0384\nt\ft\16t\u0387\13t\5t\u0389\nt\3u\3u\3"+ + "u\3u\3u\7u\u0390\nu\fu\16u\u0393\13u\5u\u0395\nu\5u\u0397\nu\3u\3u\5u"+ + "\u039b\nu\3u\3u\3v\6v\u03a0\nv\rv\16v\u03a1\3w\3w\3w\3w\3x\3x\7x\u03aa"+ "\nx\fx\16x\u03ad\13x\3y\5y\u03b0\ny\3z\3z\5z\u03b4\nz\3{\3{\3{\3{\3{\3"+ "{\3{\3{\7{\u03be\n{\f{\16{\u03c1\13{\3{\6{\u03c4\n{\r{\16{\u03c5\3{\3"+ "{\3{\3{\3|\3|\2\2}\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r"+ @@ -248,31 +251,31 @@ public JsoniqLexer(CharStream input) { "\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00ed"+ "\3\2\2\2\2\u00ef\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\3\u00f9\3\2\2"+ "\2\5\u00fb\3\2\2\2\7\u0102\3\2\2\2\t\u010c\3\2\2\2\13\u010e\3\2\2\2\r"+ - "\u0116\3\2\2\2\17\u011f\3\2\2\2\21\u0127\3\2\2\2\23\u0136\3\2\2\2\25\u0138"+ - "\3\2\2\2\27\u014a\3\2\2\2\31\u015d\3\2\2\2\33\u0166\3\2\2\2\35\u0171\3"+ - "\2\2\2\37\u0175\3\2\2\2!\u017d\3\2\2\2#\u0187\3\2\2\2%\u0192\3\2\2\2\'"+ - "\u0198\3\2\2\2)\u01aa\3\2\2\2+\u01b1\3\2\2\2-\u01b3\3\2\2\2/\u01bc\3\2"+ - "\2\2\61\u01bf\3\2\2\2\63\u01c8\3\2\2\2\65\u01d1\3\2\2\2\67\u01d3\3\2\2"+ - "\29\u01d5\3\2\2\2;\u01d7\3\2\2\2=\u01d9\3\2\2\2?\u01de\3\2\2\2A\u01e0"+ - "\3\2\2\2C\u01e2\3\2\2\2E\u01e4\3\2\2\2G\u01e7\3\2\2\2I\u01ea\3\2\2\2K"+ - "\u01ed\3\2\2\2M\u01f0\3\2\2\2O\u01f3\3\2\2\2Q\u01f6\3\2\2\2S\u01f9\3\2"+ - "\2\2U\u01fb\3\2\2\2W\u01fe\3\2\2\2Y\u0200\3\2\2\2[\u0203\3\2\2\2]\u0206"+ - "\3\2\2\2_\u0208\3\2\2\2a\u020a\3\2\2\2c\u020e\3\2\2\2e\u0213\3\2\2\2g"+ - "\u0217\3\2\2\2i\u0220\3\2\2\2k\u0222\3\2\2\2m\u0224\3\2\2\2o\u0226\3\2"+ - "\2\2q\u0228\3\2\2\2s\u022b\3\2\2\2u\u022d\3\2\2\2w\u0230\3\2\2\2y\u0233"+ - "\3\2\2\2{\u0237\3\2\2\2}\u023b\3\2\2\2\177\u0241\3\2\2\2\u0081\u0247\3"+ - "\2\2\2\u0083\u024a\3\2\2\2\u0085\u0250\3\2\2\2\u0087\u0257\3\2\2\2\u0089"+ - "\u025a\3\2\2\2\u008b\u025d\3\2\2\2\u008d\u0260\3\2\2\2\u008f\u0263\3\2"+ - "\2\2\u0091\u026c\3\2\2\2\u0093\u0272\3\2\2\2\u0095\u0278\3\2\2\2\u0097"+ - "\u027f\3\2\2\2\u0099\u0289\3\2\2\2\u009b\u0294\3\2\2\2\u009d\u0299\3\2"+ - "\2\2\u009f\u029f\3\2\2\2\u00a1\u02a9\3\2\2\2\u00a3\u02b3\3\2\2\2\u00a5"+ - "\u02bc\3\2\2\2\u00a7\u02c2\3\2\2\2\u00a9\u02c9\3\2\2\2\u00ab\u02ce\3\2"+ - "\2\2\u00ad\u02d2\3\2\2\2\u00af\u02d8\3\2\2\2\u00b1\u02e0\3\2\2\2\u00b3"+ - "\u02e5\3\2\2\2\u00b5\u02ea\3\2\2\2\u00b7\u02f5\3\2\2\2\u00b9\u02f8\3\2"+ - "\2\2\u00bb\u02fc\3\2\2\2\u00bd\u0300\3\2\2\2\u00bf\u0303\3\2\2\2\u00c1"+ - "\u030c\3\2\2\2\u00c3\u030f\3\2\2\2\u00c5\u031a\3\2\2\2\u00c7\u031d\3\2"+ - "\2\2\u00c9\u0323\3\2\2\2\u00cb\u0328\3\2\2\2\u00cd\u0331\3\2\2\2\u00cf"+ - "\u0339\3\2\2\2\u00d1\u0340\3\2\2\2\u00d3\u034a\3\2\2\2\u00d5\u0354\3\2"+ + "\u0116\3\2\2\2\17\u011f\3\2\2\2\21\u0127\3\2\2\2\23\u0131\3\2\2\2\25\u0140"+ + "\3\2\2\2\27\u0142\3\2\2\2\31\u0154\3\2\2\2\33\u0167\3\2\2\2\35\u0170\3"+ + "\2\2\2\37\u017b\3\2\2\2!\u017f\3\2\2\2#\u0187\3\2\2\2%\u0191\3\2\2\2\'"+ + "\u019c\3\2\2\2)\u01a2\3\2\2\2+\u01b4\3\2\2\2-\u01bb\3\2\2\2/\u01bd\3\2"+ + "\2\2\61\u01c6\3\2\2\2\63\u01c9\3\2\2\2\65\u01d2\3\2\2\2\67\u01db\3\2\2"+ + "\29\u01dd\3\2\2\2;\u01df\3\2\2\2=\u01e1\3\2\2\2?\u01e3\3\2\2\2A\u01e8"+ + "\3\2\2\2C\u01ea\3\2\2\2E\u01ec\3\2\2\2G\u01ee\3\2\2\2I\u01f1\3\2\2\2K"+ + "\u01f4\3\2\2\2M\u01f7\3\2\2\2O\u01fa\3\2\2\2Q\u01fd\3\2\2\2S\u0200\3\2"+ + "\2\2U\u0203\3\2\2\2W\u0205\3\2\2\2Y\u0208\3\2\2\2[\u020a\3\2\2\2]\u020d"+ + "\3\2\2\2_\u0210\3\2\2\2a\u0212\3\2\2\2c\u0214\3\2\2\2e\u0218\3\2\2\2g"+ + "\u021d\3\2\2\2i\u0221\3\2\2\2k\u022a\3\2\2\2m\u022c\3\2\2\2o\u022e\3\2"+ + "\2\2q\u0230\3\2\2\2s\u0232\3\2\2\2u\u0235\3\2\2\2w\u0237\3\2\2\2y\u023a"+ + "\3\2\2\2{\u023d\3\2\2\2}\u0241\3\2\2\2\177\u0245\3\2\2\2\u0081\u024b\3"+ + "\2\2\2\u0083\u0251\3\2\2\2\u0085\u0254\3\2\2\2\u0087\u025a\3\2\2\2\u0089"+ + "\u0261\3\2\2\2\u008b\u0264\3\2\2\2\u008d\u0267\3\2\2\2\u008f\u026a\3\2"+ + "\2\2\u0091\u026d\3\2\2\2\u0093\u0276\3\2\2\2\u0095\u027c\3\2\2\2\u0097"+ + "\u0282\3\2\2\2\u0099\u0289\3\2\2\2\u009b\u0293\3\2\2\2\u009d\u029e\3\2"+ + "\2\2\u009f\u02a3\3\2\2\2\u00a1\u02a9\3\2\2\2\u00a3\u02b3\3\2\2\2\u00a5"+ + "\u02bd\3\2\2\2\u00a7\u02c6\3\2\2\2\u00a9\u02cc\3\2\2\2\u00ab\u02d3\3\2"+ + "\2\2\u00ad\u02d8\3\2\2\2\u00af\u02dc\3\2\2\2\u00b1\u02e2\3\2\2\2\u00b3"+ + "\u02ea\3\2\2\2\u00b5\u02ef\3\2\2\2\u00b7\u02f4\3\2\2\2\u00b9\u02ff\3\2"+ + "\2\2\u00bb\u0302\3\2\2\2\u00bd\u0306\3\2\2\2\u00bf\u030a\3\2\2\2\u00c1"+ + "\u030d\3\2\2\2\u00c3\u0316\3\2\2\2\u00c5\u0319\3\2\2\2\u00c7\u0324\3\2"+ + "\2\2\u00c9\u0327\3\2\2\2\u00cb\u032d\3\2\2\2\u00cd\u0332\3\2\2\2\u00cf"+ + "\u033b\3\2\2\2\u00d1\u0343\3\2\2\2\u00d3\u034a\3\2\2\2\u00d5\u0354\3\2"+ "\2\2\u00d7\u0359\3\2\2\2\u00d9\u035f\3\2\2\2\u00db\u0361\3\2\2\2\u00dd"+ "\u0363\3\2\2\2\u00df\u036a\3\2\2\2\u00e1\u036f\3\2\2\2\u00e3\u037a\3\2"+ "\2\2\u00e5\u037c\3\2\2\2\u00e7\u0388\3\2\2\2\u00e9\u0396\3\2\2\2\u00eb"+ @@ -290,197 +293,197 @@ public JsoniqLexer(CharStream input) { "\u011c\u011d\7p\2\2\u011d\u011e\7i\2\2\u011e\16\3\2\2\2\u011f\u0120\7"+ "q\2\2\u0120\u0121\7t\2\2\u0121\u0122\7f\2\2\u0122\u0123\7g\2\2\u0123\u0124"+ "\7t\2\2\u0124\u0125\7g\2\2\u0125\u0126\7f\2\2\u0126\20\3\2\2\2\u0127\u0128"+ - "\7f\2\2\u0128\u0129\7g\2\2\u0129\u012a\7e\2\2\u012a\u012b\7k\2\2\u012b"+ - "\u012c\7o\2\2\u012c\u012d\7c\2\2\u012d\u012e\7n\2\2\u012e\u012f\7/\2\2"+ - "\u012f\u0130\7h\2\2\u0130\u0131\7q\2\2\u0131\u0132\7t\2\2\u0132\u0133"+ - "\7o\2\2\u0133\u0134\7c\2\2\u0134\u0135\7v\2\2\u0135\22\3\2\2\2\u0136\u0137"+ - "\7<\2\2\u0137\24\3\2\2\2\u0138\u0139\7f\2\2\u0139\u013a\7g\2\2\u013a\u013b"+ - "\7e\2\2\u013b\u013c\7k\2\2\u013c\u013d\7o\2\2\u013d\u013e\7c\2\2\u013e"+ - "\u013f\7n\2\2\u013f\u0140\7/\2\2\u0140\u0141\7u\2\2\u0141\u0142\7g\2\2"+ - "\u0142\u0143\7r\2\2\u0143\u0144\7c\2\2\u0144\u0145\7t\2\2\u0145\u0146"+ - "\7c\2\2\u0146\u0147\7v\2\2\u0147\u0148\7q\2\2\u0148\u0149\7t\2\2\u0149"+ - "\26\3\2\2\2\u014a\u014b\7i\2\2\u014b\u014c\7t\2\2\u014c\u014d\7q\2\2\u014d"+ - "\u014e\7w\2\2\u014e\u014f\7r\2\2\u014f\u0150\7k\2\2\u0150\u0151\7p\2\2"+ - "\u0151\u0152\7i\2\2\u0152\u0153\7/\2\2\u0153\u0154\7u\2\2\u0154\u0155"+ - "\7g\2\2\u0155\u0156\7r\2\2\u0156\u0157\7c\2\2\u0157\u0158\7t\2\2\u0158"+ - "\u0159\7c\2\2\u0159\u015a\7v\2\2\u015a\u015b\7q\2\2\u015b\u015c\7t\2\2"+ - "\u015c\30\3\2\2\2\u015d\u015e\7k\2\2\u015e\u015f\7p\2\2\u015f\u0160\7"+ - "h\2\2\u0160\u0161\7k\2\2\u0161\u0162\7p\2\2\u0162\u0163\7k\2\2\u0163\u0164"+ - "\7v\2\2\u0164\u0165\7{\2\2\u0165\32\3\2\2\2\u0166\u0167\7o\2\2\u0167\u0168"+ - "\7k\2\2\u0168\u0169\7p\2\2\u0169\u016a\7w\2\2\u016a\u016b\7u\2\2\u016b"+ - "\u016c\7/\2\2\u016c\u016d\7u\2\2\u016d\u016e\7k\2\2\u016e\u016f\7i\2\2"+ - "\u016f\u0170\7p\2\2\u0170\34\3\2\2\2\u0171\u0172\7P\2\2\u0172\u0173\7"+ - "c\2\2\u0173\u0174\7P\2\2\u0174\36\3\2\2\2\u0175\u0176\7r\2\2\u0176\u0177"+ - "\7g\2\2\u0177\u0178\7t\2\2\u0178\u0179\7e\2\2\u0179\u017a\7g\2\2\u017a"+ - "\u017b\7p\2\2\u017b\u017c\7v\2\2\u017c \3\2\2\2\u017d\u017e\7r\2\2\u017e"+ - "\u017f\7g\2\2\u017f\u0180\7t\2\2\u0180\u0181\7/\2\2\u0181\u0182\7o\2\2"+ - "\u0182\u0183\7k\2\2\u0183\u0184\7n\2\2\u0184\u0185\7n\2\2\u0185\u0186"+ - "\7g\2\2\u0186\"\3\2\2\2\u0187\u0188\7|\2\2\u0188\u0189\7g\2\2\u0189\u018a"+ - "\7t\2\2\u018a\u018b\7q\2\2\u018b\u018c\7/\2\2\u018c\u018d\7f\2\2\u018d"+ - "\u018e\7k\2\2\u018e\u018f\7i\2\2\u018f\u0190\7k\2\2\u0190\u0191\7v\2\2"+ - "\u0191$\3\2\2\2\u0192\u0193\7f\2\2\u0193\u0194\7k\2\2\u0194\u0195\7i\2"+ - "\2\u0195\u0196\7k\2\2\u0196\u0197\7v\2\2\u0197&\3\2\2\2\u0198\u0199\7"+ - "r\2\2\u0199\u019a\7c\2\2\u019a\u019b\7v\2\2\u019b\u019c\7v\2\2\u019c\u019d"+ - "\7g\2\2\u019d\u019e\7t\2\2\u019e\u019f\7p\2\2\u019f\u01a0\7/\2\2\u01a0"+ - "\u01a1\7u\2\2\u01a1\u01a2\7g\2\2\u01a2\u01a3\7r\2\2\u01a3\u01a4\7c\2\2"+ - "\u01a4\u01a5\7t\2\2\u01a5\u01a6\7c\2\2\u01a6\u01a7\7v\2\2\u01a7\u01a8"+ - "\7q\2\2\u01a8\u01a9\7t\2\2\u01a9(\3\2\2\2\u01aa\u01ab\7k\2\2\u01ab\u01ac"+ - "\7o\2\2\u01ac\u01ad\7r\2\2\u01ad\u01ae\7q\2\2\u01ae\u01af\7t\2\2\u01af"+ - "\u01b0\7v\2\2\u01b0*\3\2\2\2\u01b1\u01b2\7.\2\2\u01b2,\3\2\2\2\u01b3\u01b4"+ - "\7x\2\2\u01b4\u01b5\7c\2\2\u01b5\u01b6\7t\2\2\u01b6\u01b7\7k\2\2\u01b7"+ - "\u01b8\7c\2\2\u01b8\u01b9\7d\2\2\u01b9\u01ba\7n\2\2\u01ba\u01bb\7g\2\2"+ - "\u01bb.\3\2\2\2\u01bc\u01bd\7<\2\2\u01bd\u01be\7?\2\2\u01be\60\3\2\2\2"+ - "\u01bf\u01c0\7g\2\2\u01c0\u01c1\7z\2\2\u01c1\u01c2\7v\2\2\u01c2\u01c3"+ - "\7g\2\2\u01c3\u01c4\7t\2\2\u01c4\u01c5\7p\2\2\u01c5\u01c6\7c\2\2\u01c6"+ - "\u01c7\7n\2\2\u01c7\62\3\2\2\2\u01c8\u01c9\7h\2\2\u01c9\u01ca\7w\2\2\u01ca"+ - "\u01cb\7p\2\2\u01cb\u01cc\7e\2\2\u01cc\u01cd\7v\2\2\u01cd\u01ce\7k\2\2"+ - "\u01ce\u01cf\7q\2\2\u01cf\u01d0\7p\2\2\u01d0\64\3\2\2\2\u01d1\u01d2\7"+ - "*\2\2\u01d2\66\3\2\2\2\u01d3\u01d4\7+\2\2\u01d48\3\2\2\2\u01d5\u01d6\7"+ - "}\2\2\u01d6:\3\2\2\2\u01d7\u01d8\7\177\2\2\u01d8<\3\2\2\2\u01d9\u01da"+ - "\7v\2\2\u01da\u01db\7{\2\2\u01db\u01dc\7r\2\2\u01dc\u01dd\7g\2\2\u01dd"+ - ">\3\2\2\2\u01de\u01df\7&\2\2\u01df@\3\2\2\2\u01e0\u01e1\7~\2\2\u01e1B"+ - "\3\2\2\2\u01e2\u01e3\7,\2\2\u01e3D\3\2\2\2\u01e4\u01e5\7g\2\2\u01e5\u01e6"+ - "\7s\2\2\u01e6F\3\2\2\2\u01e7\u01e8\7p\2\2\u01e8\u01e9\7g\2\2\u01e9H\3"+ - "\2\2\2\u01ea\u01eb\7n\2\2\u01eb\u01ec\7v\2\2\u01ecJ\3\2\2\2\u01ed\u01ee"+ - "\7n\2\2\u01ee\u01ef\7g\2\2\u01efL\3\2\2\2\u01f0\u01f1\7i\2\2\u01f1\u01f2"+ - "\7v\2\2\u01f2N\3\2\2\2\u01f3\u01f4\7i\2\2\u01f4\u01f5\7g\2\2\u01f5P\3"+ - "\2\2\2\u01f6\u01f7\7#\2\2\u01f7\u01f8\7?\2\2\u01f8R\3\2\2\2\u01f9\u01fa"+ - "\7>\2\2\u01faT\3\2\2\2\u01fb\u01fc\7>\2\2\u01fc\u01fd\7?\2\2\u01fdV\3"+ - "\2\2\2\u01fe\u01ff\7@\2\2\u01ffX\3\2\2\2\u0200\u0201\7@\2\2\u0201\u0202"+ - "\7?\2\2\u0202Z\3\2\2\2\u0203\u0204\7~\2\2\u0204\u0205\7~\2\2\u0205\\\3"+ - "\2\2\2\u0206\u0207\7-\2\2\u0207^\3\2\2\2\u0208\u0209\7/\2\2\u0209`\3\2"+ - "\2\2\u020a\u020b\7f\2\2\u020b\u020c\7k\2\2\u020c\u020d\7x\2\2\u020db\3"+ - "\2\2\2\u020e\u020f\7k\2\2\u020f\u0210\7f\2\2\u0210\u0211\7k\2\2\u0211"+ - "\u0212\7x\2\2\u0212d\3\2\2\2\u0213\u0214\7o\2\2\u0214\u0215\7q\2\2\u0215"+ - "\u0216\7f\2\2\u0216f\3\2\2\2\u0217\u0218\7x\2\2\u0218\u0219\7c\2\2\u0219"+ - "\u021a\7n\2\2\u021a\u021b\7k\2\2\u021b\u021c\7f\2\2\u021c\u021d\7c\2\2"+ - "\u021d\u021e\7v\2\2\u021e\u021f\7g\2\2\u021fh\3\2\2\2\u0220\u0221\7#\2"+ - "\2\u0221j\3\2\2\2\u0222\u0223\7]\2\2\u0223l\3\2\2\2\u0224\u0225\7_\2\2"+ - "\u0225n\3\2\2\2\u0226\u0227\7\60\2\2\u0227p\3\2\2\2\u0228\u0229\7&\2\2"+ - "\u0229\u022a\7&\2\2\u022ar\3\2\2\2\u022b\u022c\7%\2\2\u022ct\3\2\2\2\u022d"+ - "\u022e\7}\2\2\u022e\u022f\7~\2\2\u022fv\3\2\2\2\u0230\u0231\7~\2\2\u0231"+ - "\u0232\7\177\2\2\u0232x\3\2\2\2\u0233\u0234\7h\2\2\u0234\u0235\7q\2\2"+ - "\u0235\u0236\7t\2\2\u0236z\3\2\2\2\u0237\u0238\7n\2\2\u0238\u0239\7g\2"+ - "\2\u0239\u023a\7v\2\2\u023a|\3\2\2\2\u023b\u023c\7y\2\2\u023c\u023d\7"+ - "j\2\2\u023d\u023e\7g\2\2\u023e\u023f\7t\2\2\u023f\u0240\7g\2\2\u0240~"+ - "\3\2\2\2\u0241\u0242\7i\2\2\u0242\u0243\7t\2\2\u0243\u0244\7q\2\2\u0244"+ - "\u0245\7w\2\2\u0245\u0246\7r\2\2\u0246\u0080\3\2\2\2\u0247\u0248\7d\2"+ - "\2\u0248\u0249\7{\2\2\u0249\u0082\3\2\2\2\u024a\u024b\7q\2\2\u024b\u024c"+ - "\7t\2\2\u024c\u024d\7f\2\2\u024d\u024e\7g\2\2\u024e\u024f\7t\2\2\u024f"+ - "\u0084\3\2\2\2\u0250\u0251\7t\2\2\u0251\u0252\7g\2\2\u0252\u0253\7v\2"+ - "\2\u0253\u0254\7w\2\2\u0254\u0255\7t\2\2\u0255\u0256\7p\2\2\u0256\u0086"+ - "\3\2\2\2\u0257\u0258\7k\2\2\u0258\u0259\7h\2\2\u0259\u0088\3\2\2\2\u025a"+ - "\u025b\7k\2\2\u025b\u025c\7p\2\2\u025c\u008a\3\2\2\2\u025d\u025e\7c\2"+ - "\2\u025e\u025f\7u\2\2\u025f\u008c\3\2\2\2\u0260\u0261\7c\2\2\u0261\u0262"+ - "\7v\2\2\u0262\u008e\3\2\2\2\u0263\u0264\7c\2\2\u0264\u0265\7n\2\2\u0265"+ - "\u0266\7n\2\2\u0266\u0267\7q\2\2\u0267\u0268\7y\2\2\u0268\u0269\7k\2\2"+ - "\u0269\u026a\7p\2\2\u026a\u026b\7i\2\2\u026b\u0090\3\2\2\2\u026c\u026d"+ - "\7g\2\2\u026d\u026e\7o\2\2\u026e\u026f\7r\2\2\u026f\u0270\7v\2\2\u0270"+ - "\u0271\7{\2\2\u0271\u0092\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7q\2"+ - "\2\u0274\u0275\7w\2\2\u0275\u0276\7p\2\2\u0276\u0277\7v\2\2\u0277\u0094"+ - "\3\2\2\2\u0278\u0279\7u\2\2\u0279\u027a\7v\2\2\u027a\u027b\7c\2\2\u027b"+ - "\u027c\7d\2\2\u027c\u027d\7n\2\2\u027d\u027e\7g\2\2\u027e\u0096\3\2\2"+ - "\2\u027f\u0280\7c\2\2\u0280\u0281\7u\2\2\u0281\u0282\7e\2\2\u0282\u0283"+ - "\7g\2\2\u0283\u0284\7p\2\2\u0284\u0285\7f\2\2\u0285\u0286\7k\2\2\u0286"+ - "\u0287\7p\2\2\u0287\u0288\7i\2\2\u0288\u0098\3\2\2\2\u0289\u028a\7f\2"+ - "\2\u028a\u028b\7g\2\2\u028b\u028c\7u\2\2\u028c\u028d\7e\2\2\u028d\u028e"+ - "\7g\2\2\u028e\u028f\7p\2\2\u028f\u0290\7f\2\2\u0290\u0291\7k\2\2\u0291"+ - "\u0292\7p\2\2\u0292\u0293\7i\2\2\u0293\u009a\3\2\2\2\u0294\u0295\7u\2"+ - "\2\u0295\u0296\7q\2\2\u0296\u0297\7o\2\2\u0297\u0298\7g\2\2\u0298\u009c"+ - "\3\2\2\2\u0299\u029a\7g\2\2\u029a\u029b\7x\2\2\u029b\u029c\7g\2\2\u029c"+ - "\u029d\7t\2\2\u029d\u029e\7{\2\2\u029e\u009e\3\2\2\2\u029f\u02a0\7u\2"+ - "\2\u02a0\u02a1\7c\2\2\u02a1\u02a2\7v\2\2\u02a2\u02a3\7k\2\2\u02a3\u02a4"+ - "\7u\2\2\u02a4\u02a5\7h\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a7\7g\2\2\u02a7"+ - "\u02a8\7u\2\2\u02a8\u00a0\3\2\2\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7q\2"+ - "\2\u02ab\u02ac\7n\2\2\u02ac\u02ad\7n\2\2\u02ad\u02ae\7c\2\2\u02ae\u02af"+ - "\7v\2\2\u02af\u02b0\7k\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7p\2\2\u02b2"+ - "\u00a2\3\2\2\2\u02b3\u02b4\7i\2\2\u02b4\u02b5\7t\2\2\u02b5\u02b6\7g\2"+ - "\2\u02b6\u02b7\7c\2\2\u02b7\u02b8\7v\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba"+ - "\7u\2\2\u02ba\u02bb\7v\2\2\u02bb\u00a4\3\2\2\2\u02bc\u02bd\7n\2\2\u02bd"+ - "\u02be\7g\2\2\u02be\u02bf\7c\2\2\u02bf\u02c0\7u\2\2\u02c0\u02c1\7v\2\2"+ - "\u02c1\u00a6\3\2\2\2\u02c2\u02c3\7u\2\2\u02c3\u02c4\7y\2\2\u02c4\u02c5"+ - "\7k\2\2\u02c5\u02c6\7v\2\2\u02c6\u02c7\7e\2\2\u02c7\u02c8\7j\2\2\u02c8"+ - "\u00a8\3\2\2\2\u02c9\u02ca\7e\2\2\u02ca\u02cb\7c\2\2\u02cb\u02cc\7u\2"+ - "\2\u02cc\u02cd\7g\2\2\u02cd\u00aa\3\2\2\2\u02ce\u02cf\7v\2\2\u02cf\u02d0"+ - "\7t\2\2\u02d0\u02d1\7{\2\2\u02d1\u00ac\3\2\2\2\u02d2\u02d3\7e\2\2\u02d3"+ - "\u02d4\7c\2\2\u02d4\u02d5\7v\2\2\u02d5\u02d6\7e\2\2\u02d6\u02d7\7j\2\2"+ - "\u02d7\u00ae\3\2\2\2\u02d8\u02d9\7f\2\2\u02d9\u02da\7g\2\2\u02da\u02db"+ - "\7h\2\2\u02db\u02dc\7c\2\2\u02dc\u02dd\7w\2\2\u02dd\u02de\7n\2\2\u02de"+ - "\u02df\7v\2\2\u02df\u00b0\3\2\2\2\u02e0\u02e1\7v\2\2\u02e1\u02e2\7j\2"+ - "\2\u02e2\u02e3\7g\2\2\u02e3\u02e4\7p\2\2\u02e4\u00b2\3\2\2\2\u02e5\u02e6"+ - "\7g\2\2\u02e6\u02e7\7n\2\2\u02e7\u02e8\7u\2\2\u02e8\u02e9\7g\2\2\u02e9"+ - "\u00b4\3\2\2\2\u02ea\u02eb\7v\2\2\u02eb\u02ec\7{\2\2\u02ec\u02ed\7r\2"+ - "\2\u02ed\u02ee\7g\2\2\u02ee\u02ef\7u\2\2\u02ef\u02f0\7y\2\2\u02f0\u02f1"+ - "\7k\2\2\u02f1\u02f2\7v\2\2\u02f2\u02f3\7e\2\2\u02f3\u02f4\7j\2\2\u02f4"+ - "\u00b6\3\2\2\2\u02f5\u02f6\7q\2\2\u02f6\u02f7\7t\2\2\u02f7\u00b8\3\2\2"+ - "\2\u02f8\u02f9\7c\2\2\u02f9\u02fa\7p\2\2\u02fa\u02fb\7f\2\2\u02fb\u00ba"+ - "\3\2\2\2\u02fc\u02fd\7p\2\2\u02fd\u02fe\7q\2\2\u02fe\u02ff\7v\2\2\u02ff"+ - "\u00bc\3\2\2\2\u0300\u0301\7v\2\2\u0301\u0302\7q\2\2\u0302\u00be\3\2\2"+ - "\2\u0303\u0304\7k\2\2\u0304\u0305\7p\2\2\u0305\u0306\7u\2\2\u0306\u0307"+ - "\7v\2\2\u0307\u0308\7c\2\2\u0308\u0309\7p\2\2\u0309\u030a\7e\2\2\u030a"+ - "\u030b\7g\2\2\u030b\u00c0\3\2\2\2\u030c\u030d\7q\2\2\u030d\u030e\7h\2"+ - "\2\u030e\u00c2\3\2\2\2\u030f\u0310\7u\2\2\u0310\u0311\7v\2\2\u0311\u0312"+ - "\7c\2\2\u0312\u0313\7v\2\2\u0313\u0314\7k\2\2\u0314\u0315\7e\2\2\u0315"+ - "\u0316\7c\2\2\u0316\u0317\7n\2\2\u0317\u0318\7n\2\2\u0318\u0319\7{\2\2"+ - "\u0319\u00c4\3\2\2\2\u031a\u031b\7k\2\2\u031b\u031c\7u\2\2\u031c\u00c6"+ - "\3\2\2\2\u031d\u031e\7v\2\2\u031e\u031f\7t\2\2\u031f\u0320\7g\2\2\u0320"+ - "\u0321\7c\2\2\u0321\u0322\7v\2\2\u0322\u00c8\3\2\2\2\u0323\u0324\7e\2"+ - "\2\u0324\u0325\7c\2\2\u0325\u0326\7u\2\2\u0326\u0327\7v\2\2\u0327\u00ca"+ - "\3\2\2\2\u0328\u0329\7e\2\2\u0329\u032a\7c\2\2\u032a\u032b\7u\2\2\u032b"+ - "\u032c\7v\2\2\u032c\u032d\7c\2\2\u032d\u032e\7d\2\2\u032e\u032f\7n\2\2"+ - "\u032f\u0330\7g\2\2\u0330\u00cc\3\2\2\2\u0331\u0332\7x\2\2\u0332\u0333"+ - "\7g\2\2\u0333\u0334\7t\2\2\u0334\u0335\7u\2\2\u0335\u0336\7k\2\2\u0336"+ - "\u0337\7q\2\2\u0337\u0338\7p\2\2\u0338\u00ce\3\2\2\2\u0339\u033a\7l\2"+ - "\2\u033a\u033b\7u\2\2\u033b\u033c\7q\2\2\u033c\u033d\7p\2\2\u033d\u033e"+ - "\7k\2\2\u033e\u033f\7s\2\2\u033f\u00d0\3\2\2\2\u0340\u0341\7w\2\2\u0341"+ - "\u0342\7p\2\2\u0342\u0343\7q\2\2\u0343\u0344\7t\2\2\u0344\u0345\7f\2\2"+ - "\u0345\u0346\7g\2\2\u0346\u0347\7t\2\2\u0347\u0348\7g\2\2\u0348\u0349"+ - "\7f\2\2\u0349\u00d2\3\2\2\2\u034a\u034f\7$\2\2\u034b\u034e\5\u00d5k\2"+ - "\u034c\u034e\n\2\2\2\u034d\u034b\3\2\2\2\u034d\u034c\3\2\2\2\u034e\u0351"+ - "\3\2\2\2\u034f\u034d\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351"+ - "\u034f\3\2\2\2\u0352\u0353\7$\2\2\u0353\u00d4\3\2\2\2\u0354\u0357\7^\2"+ - "\2\u0355\u0358\t\3\2\2\u0356\u0358\5\u00d7l\2\u0357\u0355\3\2\2\2\u0357"+ - "\u0356\3\2\2\2\u0358\u00d6\3\2\2\2\u0359\u035a\7w\2\2\u035a\u035b\5\u00d9"+ - "m\2\u035b\u035c\5\u00d9m\2\u035c\u035d\5\u00d9m\2\u035d\u035e\5\u00d9"+ - "m\2\u035e\u00d8\3\2\2\2\u035f\u0360\t\4\2\2\u0360\u00da\3\2\2\2\u0361"+ - "\u0362\7A\2\2\u0362\u00dc\3\2\2\2\u0363\u0364\7p\2\2\u0364\u0365\7w\2"+ - "\2\u0365\u0366\7n\2\2\u0366\u0367\7n\2\2\u0367\u00de\3\2\2\2\u0368\u036b"+ - "\5\u00e1q\2\u0369\u036b\5\u00e3r\2\u036a\u0368\3\2\2\2\u036a\u0369\3\2"+ - "\2\2\u036b\u00e0\3\2\2\2\u036c\u0370\5\u00e5s\2\u036d\u0370\5\u00e7t\2"+ - "\u036e\u0370\5\u00e9u\2\u036f\u036c\3\2\2\2\u036f\u036d\3\2\2\2\u036f"+ - "\u036e\3\2\2\2\u0370\u00e2\3\2\2\2\u0371\u0372\7v\2\2\u0372\u0373\7t\2"+ - "\2\u0373\u0374\7w\2\2\u0374\u037b\7g\2\2\u0375\u0376\7h\2\2\u0376\u0377"+ - "\7c\2\2\u0377\u0378\7n\2\2\u0378\u0379\7u\2\2\u0379\u037b\7g\2\2\u037a"+ - "\u0371\3\2\2\2\u037a\u0375\3\2\2\2\u037b\u00e4\3\2\2\2\u037c\u037d\5\u00eb"+ - "v\2\u037d\u00e6\3\2\2\2\u037e\u037f\7\60\2\2\u037f\u0389\5\u00ebv\2\u0380"+ - "\u0381\5\u00ebv\2\u0381\u0385\7\60\2\2\u0382\u0384\t\5\2\2\u0383\u0382"+ - "\3\2\2\2\u0384\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386"+ - "\u0389\3\2\2\2\u0387\u0385\3\2\2\2\u0388\u037e\3\2\2\2\u0388\u0380\3\2"+ - "\2\2\u0389\u00e8\3\2\2\2\u038a\u038b\7\60\2\2\u038b\u0397\5\u00ebv\2\u038c"+ - "\u0394\5\u00ebv\2\u038d\u0391\7\60\2\2\u038e\u0390\t\5\2\2\u038f\u038e"+ - "\3\2\2\2\u0390\u0393\3\2\2\2\u0391\u038f\3\2\2\2\u0391\u0392\3\2\2\2\u0392"+ - "\u0395\3\2\2\2\u0393\u0391\3\2\2\2\u0394\u038d\3\2\2\2\u0394\u0395\3\2"+ - "\2\2\u0395\u0397\3\2\2\2\u0396\u038a\3\2\2\2\u0396\u038c\3\2\2\2\u0397"+ - "\u0398\3\2\2\2\u0398\u039a\t\6\2\2\u0399\u039b\t\7\2\2\u039a\u0399\3\2"+ - "\2\2\u039a\u039b\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039d\5\u00ebv\2\u039d"+ - "\u00ea\3\2\2\2\u039e\u03a0\t\5\2\2\u039f\u039e\3\2\2\2\u03a0\u03a1\3\2"+ - "\2\2\u03a1\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u00ec\3\2\2\2\u03a3"+ - "\u03a4\t\b\2\2\u03a4\u03a5\3\2\2\2\u03a5\u03a6\bw\2\2\u03a6\u00ee\3\2"+ - "\2\2\u03a7\u03ab\5\u00f1y\2\u03a8\u03aa\5\u00f3z\2\u03a9\u03a8\3\2\2\2"+ - "\u03aa\u03ad\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u00f0"+ - "\3\2\2\2\u03ad\u03ab\3\2\2\2\u03ae\u03b0\t\t\2\2\u03af\u03ae\3\2\2\2\u03b0"+ - "\u00f2\3\2\2\2\u03b1\u03b4\5\u00f1y\2\u03b2\u03b4\t\n\2\2\u03b3\u03b1"+ - "\3\2\2\2\u03b3\u03b2\3\2\2\2\u03b4\u00f4\3\2\2\2\u03b5\u03b6\7*\2\2\u03b6"+ - "\u03bf\7<\2\2\u03b7\u03be\5\u00f5{\2\u03b8\u03b9\7*\2\2\u03b9\u03be\n"+ - "\13\2\2\u03ba\u03bb\7<\2\2\u03bb\u03be\n\f\2\2\u03bc\u03be\n\r\2\2\u03bd"+ - "\u03b7\3\2\2\2\u03bd\u03b8\3\2\2\2\u03bd\u03ba\3\2\2\2\u03bd\u03bc\3\2"+ - "\2\2\u03be\u03c1\3\2\2\2\u03bf\u03bd\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0"+ - "\u03c3\3\2\2\2\u03c1\u03bf\3\2\2\2\u03c2\u03c4\7<\2\2\u03c3\u03c2\3\2"+ - "\2\2\u03c4\u03c5\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c5\u03c6\3\2\2\2\u03c6"+ - "\u03c7\3\2\2\2\u03c7\u03c8\7+\2\2\u03c8\u03c9\3\2\2\2\u03c9\u03ca\b{\2"+ - "\2\u03ca\u00f6\3\2\2\2\u03cb\u03cc\n\16\2\2\u03cc\u00f8\3\2\2\2\26\2\u034d"+ - "\u034f\u0357\u036a\u036f\u037a\u0385\u0388\u0391\u0394\u0396\u039a\u03a1"+ - "\u03ab\u03af\u03b3\u03bd\u03bf\u03c5\3\2\3\2"; + "\7w\2\2\u0128\u0129\7p\2\2\u0129\u012a\7q\2\2\u012a\u012b\7t\2\2\u012b"+ + "\u012c\7f\2\2\u012c\u012d\7g\2\2\u012d\u012e\7t\2\2\u012e\u012f\7g\2\2"+ + "\u012f\u0130\7f\2\2\u0130\22\3\2\2\2\u0131\u0132\7f\2\2\u0132\u0133\7"+ + "g\2\2\u0133\u0134\7e\2\2\u0134\u0135\7k\2\2\u0135\u0136\7o\2\2\u0136\u0137"+ + "\7c\2\2\u0137\u0138\7n\2\2\u0138\u0139\7/\2\2\u0139\u013a\7h\2\2\u013a"+ + "\u013b\7q\2\2\u013b\u013c\7t\2\2\u013c\u013d\7o\2\2\u013d\u013e\7c\2\2"+ + "\u013e\u013f\7v\2\2\u013f\24\3\2\2\2\u0140\u0141\7<\2\2\u0141\26\3\2\2"+ + "\2\u0142\u0143\7f\2\2\u0143\u0144\7g\2\2\u0144\u0145\7e\2\2\u0145\u0146"+ + "\7k\2\2\u0146\u0147\7o\2\2\u0147\u0148\7c\2\2\u0148\u0149\7n\2\2\u0149"+ + "\u014a\7/\2\2\u014a\u014b\7u\2\2\u014b\u014c\7g\2\2\u014c\u014d\7r\2\2"+ + "\u014d\u014e\7c\2\2\u014e\u014f\7t\2\2\u014f\u0150\7c\2\2\u0150\u0151"+ + "\7v\2\2\u0151\u0152\7q\2\2\u0152\u0153\7t\2\2\u0153\30\3\2\2\2\u0154\u0155"+ + "\7i\2\2\u0155\u0156\7t\2\2\u0156\u0157\7q\2\2\u0157\u0158\7w\2\2\u0158"+ + "\u0159\7r\2\2\u0159\u015a\7k\2\2\u015a\u015b\7p\2\2\u015b\u015c\7i\2\2"+ + "\u015c\u015d\7/\2\2\u015d\u015e\7u\2\2\u015e\u015f\7g\2\2\u015f\u0160"+ + "\7r\2\2\u0160\u0161\7c\2\2\u0161\u0162\7t\2\2\u0162\u0163\7c\2\2\u0163"+ + "\u0164\7v\2\2\u0164\u0165\7q\2\2\u0165\u0166\7t\2\2\u0166\32\3\2\2\2\u0167"+ + "\u0168\7k\2\2\u0168\u0169\7p\2\2\u0169\u016a\7h\2\2\u016a\u016b\7k\2\2"+ + "\u016b\u016c\7p\2\2\u016c\u016d\7k\2\2\u016d\u016e\7v\2\2\u016e\u016f"+ + "\7{\2\2\u016f\34\3\2\2\2\u0170\u0171\7o\2\2\u0171\u0172\7k\2\2\u0172\u0173"+ + "\7p\2\2\u0173\u0174\7w\2\2\u0174\u0175\7u\2\2\u0175\u0176\7/\2\2\u0176"+ + "\u0177\7u\2\2\u0177\u0178\7k\2\2\u0178\u0179\7i\2\2\u0179\u017a\7p\2\2"+ + "\u017a\36\3\2\2\2\u017b\u017c\7P\2\2\u017c\u017d\7c\2\2\u017d\u017e\7"+ + "P\2\2\u017e \3\2\2\2\u017f\u0180\7r\2\2\u0180\u0181\7g\2\2\u0181\u0182"+ + "\7t\2\2\u0182\u0183\7e\2\2\u0183\u0184\7g\2\2\u0184\u0185\7p\2\2\u0185"+ + "\u0186\7v\2\2\u0186\"\3\2\2\2\u0187\u0188\7r\2\2\u0188\u0189\7g\2\2\u0189"+ + "\u018a\7t\2\2\u018a\u018b\7/\2\2\u018b\u018c\7o\2\2\u018c\u018d\7k\2\2"+ + "\u018d\u018e\7n\2\2\u018e\u018f\7n\2\2\u018f\u0190\7g\2\2\u0190$\3\2\2"+ + "\2\u0191\u0192\7|\2\2\u0192\u0193\7g\2\2\u0193\u0194\7t\2\2\u0194\u0195"+ + "\7q\2\2\u0195\u0196\7/\2\2\u0196\u0197\7f\2\2\u0197\u0198\7k\2\2\u0198"+ + "\u0199\7i\2\2\u0199\u019a\7k\2\2\u019a\u019b\7v\2\2\u019b&\3\2\2\2\u019c"+ + "\u019d\7f\2\2\u019d\u019e\7k\2\2\u019e\u019f\7i\2\2\u019f\u01a0\7k\2\2"+ + "\u01a0\u01a1\7v\2\2\u01a1(\3\2\2\2\u01a2\u01a3\7r\2\2\u01a3\u01a4\7c\2"+ + "\2\u01a4\u01a5\7v\2\2\u01a5\u01a6\7v\2\2\u01a6\u01a7\7g\2\2\u01a7\u01a8"+ + "\7t\2\2\u01a8\u01a9\7p\2\2\u01a9\u01aa\7/\2\2\u01aa\u01ab\7u\2\2\u01ab"+ + "\u01ac\7g\2\2\u01ac\u01ad\7r\2\2\u01ad\u01ae\7c\2\2\u01ae\u01af\7t\2\2"+ + "\u01af\u01b0\7c\2\2\u01b0\u01b1\7v\2\2\u01b1\u01b2\7q\2\2\u01b2\u01b3"+ + "\7t\2\2\u01b3*\3\2\2\2\u01b4\u01b5\7k\2\2\u01b5\u01b6\7o\2\2\u01b6\u01b7"+ + "\7r\2\2\u01b7\u01b8\7q\2\2\u01b8\u01b9\7t\2\2\u01b9\u01ba\7v\2\2\u01ba"+ + ",\3\2\2\2\u01bb\u01bc\7.\2\2\u01bc.\3\2\2\2\u01bd\u01be\7x\2\2\u01be\u01bf"+ + "\7c\2\2\u01bf\u01c0\7t\2\2\u01c0\u01c1\7k\2\2\u01c1\u01c2\7c\2\2\u01c2"+ + "\u01c3\7d\2\2\u01c3\u01c4\7n\2\2\u01c4\u01c5\7g\2\2\u01c5\60\3\2\2\2\u01c6"+ + "\u01c7\7<\2\2\u01c7\u01c8\7?\2\2\u01c8\62\3\2\2\2\u01c9\u01ca\7g\2\2\u01ca"+ + "\u01cb\7z\2\2\u01cb\u01cc\7v\2\2\u01cc\u01cd\7g\2\2\u01cd\u01ce\7t\2\2"+ + "\u01ce\u01cf\7p\2\2\u01cf\u01d0\7c\2\2\u01d0\u01d1\7n\2\2\u01d1\64\3\2"+ + "\2\2\u01d2\u01d3\7h\2\2\u01d3\u01d4\7w\2\2\u01d4\u01d5\7p\2\2\u01d5\u01d6"+ + "\7e\2\2\u01d6\u01d7\7v\2\2\u01d7\u01d8\7k\2\2\u01d8\u01d9\7q\2\2\u01d9"+ + "\u01da\7p\2\2\u01da\66\3\2\2\2\u01db\u01dc\7*\2\2\u01dc8\3\2\2\2\u01dd"+ + "\u01de\7+\2\2\u01de:\3\2\2\2\u01df\u01e0\7}\2\2\u01e0<\3\2\2\2\u01e1\u01e2"+ + "\7\177\2\2\u01e2>\3\2\2\2\u01e3\u01e4\7v\2\2\u01e4\u01e5\7{\2\2\u01e5"+ + "\u01e6\7r\2\2\u01e6\u01e7\7g\2\2\u01e7@\3\2\2\2\u01e8\u01e9\7&\2\2\u01e9"+ + "B\3\2\2\2\u01ea\u01eb\7~\2\2\u01ebD\3\2\2\2\u01ec\u01ed\7,\2\2\u01edF"+ + "\3\2\2\2\u01ee\u01ef\7g\2\2\u01ef\u01f0\7s\2\2\u01f0H\3\2\2\2\u01f1\u01f2"+ + "\7p\2\2\u01f2\u01f3\7g\2\2\u01f3J\3\2\2\2\u01f4\u01f5\7n\2\2\u01f5\u01f6"+ + "\7v\2\2\u01f6L\3\2\2\2\u01f7\u01f8\7n\2\2\u01f8\u01f9\7g\2\2\u01f9N\3"+ + "\2\2\2\u01fa\u01fb\7i\2\2\u01fb\u01fc\7v\2\2\u01fcP\3\2\2\2\u01fd\u01fe"+ + "\7i\2\2\u01fe\u01ff\7g\2\2\u01ffR\3\2\2\2\u0200\u0201\7#\2\2\u0201\u0202"+ + "\7?\2\2\u0202T\3\2\2\2\u0203\u0204\7>\2\2\u0204V\3\2\2\2\u0205\u0206\7"+ + ">\2\2\u0206\u0207\7?\2\2\u0207X\3\2\2\2\u0208\u0209\7@\2\2\u0209Z\3\2"+ + "\2\2\u020a\u020b\7@\2\2\u020b\u020c\7?\2\2\u020c\\\3\2\2\2\u020d\u020e"+ + "\7~\2\2\u020e\u020f\7~\2\2\u020f^\3\2\2\2\u0210\u0211\7-\2\2\u0211`\3"+ + "\2\2\2\u0212\u0213\7/\2\2\u0213b\3\2\2\2\u0214\u0215\7f\2\2\u0215\u0216"+ + "\7k\2\2\u0216\u0217\7x\2\2\u0217d\3\2\2\2\u0218\u0219\7k\2\2\u0219\u021a"+ + "\7f\2\2\u021a\u021b\7k\2\2\u021b\u021c\7x\2\2\u021cf\3\2\2\2\u021d\u021e"+ + "\7o\2\2\u021e\u021f\7q\2\2\u021f\u0220\7f\2\2\u0220h\3\2\2\2\u0221\u0222"+ + "\7x\2\2\u0222\u0223\7c\2\2\u0223\u0224\7n\2\2\u0224\u0225\7k\2\2\u0225"+ + "\u0226\7f\2\2\u0226\u0227\7c\2\2\u0227\u0228\7v\2\2\u0228\u0229\7g\2\2"+ + "\u0229j\3\2\2\2\u022a\u022b\7#\2\2\u022bl\3\2\2\2\u022c\u022d\7]\2\2\u022d"+ + "n\3\2\2\2\u022e\u022f\7_\2\2\u022fp\3\2\2\2\u0230\u0231\7\60\2\2\u0231"+ + "r\3\2\2\2\u0232\u0233\7&\2\2\u0233\u0234\7&\2\2\u0234t\3\2\2\2\u0235\u0236"+ + "\7%\2\2\u0236v\3\2\2\2\u0237\u0238\7}\2\2\u0238\u0239\7~\2\2\u0239x\3"+ + "\2\2\2\u023a\u023b\7~\2\2\u023b\u023c\7\177\2\2\u023cz\3\2\2\2\u023d\u023e"+ + "\7h\2\2\u023e\u023f\7q\2\2\u023f\u0240\7t\2\2\u0240|\3\2\2\2\u0241\u0242"+ + "\7n\2\2\u0242\u0243\7g\2\2\u0243\u0244\7v\2\2\u0244~\3\2\2\2\u0245\u0246"+ + "\7y\2\2\u0246\u0247\7j\2\2\u0247\u0248\7g\2\2\u0248\u0249\7t\2\2\u0249"+ + "\u024a\7g\2\2\u024a\u0080\3\2\2\2\u024b\u024c\7i\2\2\u024c\u024d\7t\2"+ + "\2\u024d\u024e\7q\2\2\u024e\u024f\7w\2\2\u024f\u0250\7r\2\2\u0250\u0082"+ + "\3\2\2\2\u0251\u0252\7d\2\2\u0252\u0253\7{\2\2\u0253\u0084\3\2\2\2\u0254"+ + "\u0255\7q\2\2\u0255\u0256\7t\2\2\u0256\u0257\7f\2\2\u0257\u0258\7g\2\2"+ + "\u0258\u0259\7t\2\2\u0259\u0086\3\2\2\2\u025a\u025b\7t\2\2\u025b\u025c"+ + "\7g\2\2\u025c\u025d\7v\2\2\u025d\u025e\7w\2\2\u025e\u025f\7t\2\2\u025f"+ + "\u0260\7p\2\2\u0260\u0088\3\2\2\2\u0261\u0262\7k\2\2\u0262\u0263\7h\2"+ + "\2\u0263\u008a\3\2\2\2\u0264\u0265\7k\2\2\u0265\u0266\7p\2\2\u0266\u008c"+ + "\3\2\2\2\u0267\u0268\7c\2\2\u0268\u0269\7u\2\2\u0269\u008e\3\2\2\2\u026a"+ + "\u026b\7c\2\2\u026b\u026c\7v\2\2\u026c\u0090\3\2\2\2\u026d\u026e\7c\2"+ + "\2\u026e\u026f\7n\2\2\u026f\u0270\7n\2\2\u0270\u0271\7q\2\2\u0271\u0272"+ + "\7y\2\2\u0272\u0273\7k\2\2\u0273\u0274\7p\2\2\u0274\u0275\7i\2\2\u0275"+ + "\u0092\3\2\2\2\u0276\u0277\7g\2\2\u0277\u0278\7o\2\2\u0278\u0279\7r\2"+ + "\2\u0279\u027a\7v\2\2\u027a\u027b\7{\2\2\u027b\u0094\3\2\2\2\u027c\u027d"+ + "\7e\2\2\u027d\u027e\7q\2\2\u027e\u027f\7w\2\2\u027f\u0280\7p\2\2\u0280"+ + "\u0281\7v\2\2\u0281\u0096\3\2\2\2\u0282\u0283\7u\2\2\u0283\u0284\7v\2"+ + "\2\u0284\u0285\7c\2\2\u0285\u0286\7d\2\2\u0286\u0287\7n\2\2\u0287\u0288"+ + "\7g\2\2\u0288\u0098\3\2\2\2\u0289\u028a\7c\2\2\u028a\u028b\7u\2\2\u028b"+ + "\u028c\7e\2\2\u028c\u028d\7g\2\2\u028d\u028e\7p\2\2\u028e\u028f\7f\2\2"+ + "\u028f\u0290\7k\2\2\u0290\u0291\7p\2\2\u0291\u0292\7i\2\2\u0292\u009a"+ + "\3\2\2\2\u0293\u0294\7f\2\2\u0294\u0295\7g\2\2\u0295\u0296\7u\2\2\u0296"+ + "\u0297\7e\2\2\u0297\u0298\7g\2\2\u0298\u0299\7p\2\2\u0299\u029a\7f\2\2"+ + "\u029a\u029b\7k\2\2\u029b\u029c\7p\2\2\u029c\u029d\7i\2\2\u029d\u009c"+ + "\3\2\2\2\u029e\u029f\7u\2\2\u029f\u02a0\7q\2\2\u02a0\u02a1\7o\2\2\u02a1"+ + "\u02a2\7g\2\2\u02a2\u009e\3\2\2\2\u02a3\u02a4\7g\2\2\u02a4\u02a5\7x\2"+ + "\2\u02a5\u02a6\7g\2\2\u02a6\u02a7\7t\2\2\u02a7\u02a8\7{\2\2\u02a8\u00a0"+ + "\3\2\2\2\u02a9\u02aa\7u\2\2\u02aa\u02ab\7c\2\2\u02ab\u02ac\7v\2\2\u02ac"+ + "\u02ad\7k\2\2\u02ad\u02ae\7u\2\2\u02ae\u02af\7h\2\2\u02af\u02b0\7k\2\2"+ + "\u02b0\u02b1\7g\2\2\u02b1\u02b2\7u\2\2\u02b2\u00a2\3\2\2\2\u02b3\u02b4"+ + "\7e\2\2\u02b4\u02b5\7q\2\2\u02b5\u02b6\7n\2\2\u02b6\u02b7\7n\2\2\u02b7"+ + "\u02b8\7c\2\2\u02b8\u02b9\7v\2\2\u02b9\u02ba\7k\2\2\u02ba\u02bb\7q\2\2"+ + "\u02bb\u02bc\7p\2\2\u02bc\u00a4\3\2\2\2\u02bd\u02be\7i\2\2\u02be\u02bf"+ + "\7t\2\2\u02bf\u02c0\7g\2\2\u02c0\u02c1\7c\2\2\u02c1\u02c2\7v\2\2\u02c2"+ + "\u02c3\7g\2\2\u02c3\u02c4\7u\2\2\u02c4\u02c5\7v\2\2\u02c5\u00a6\3\2\2"+ + "\2\u02c6\u02c7\7n\2\2\u02c7\u02c8\7g\2\2\u02c8\u02c9\7c\2\2\u02c9\u02ca"+ + "\7u\2\2\u02ca\u02cb\7v\2\2\u02cb\u00a8\3\2\2\2\u02cc\u02cd\7u\2\2\u02cd"+ + "\u02ce\7y\2\2\u02ce\u02cf\7k\2\2\u02cf\u02d0\7v\2\2\u02d0\u02d1\7e\2\2"+ + "\u02d1\u02d2\7j\2\2\u02d2\u00aa\3\2\2\2\u02d3\u02d4\7e\2\2\u02d4\u02d5"+ + "\7c\2\2\u02d5\u02d6\7u\2\2\u02d6\u02d7\7g\2\2\u02d7\u00ac\3\2\2\2\u02d8"+ + "\u02d9\7v\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7{\2\2\u02db\u00ae\3\2\2"+ + "\2\u02dc\u02dd\7e\2\2\u02dd\u02de\7c\2\2\u02de\u02df\7v\2\2\u02df\u02e0"+ + "\7e\2\2\u02e0\u02e1\7j\2\2\u02e1\u00b0\3\2\2\2\u02e2\u02e3\7f\2\2\u02e3"+ + "\u02e4\7g\2\2\u02e4\u02e5\7h\2\2\u02e5\u02e6\7c\2\2\u02e6\u02e7\7w\2\2"+ + "\u02e7\u02e8\7n\2\2\u02e8\u02e9\7v\2\2\u02e9\u00b2\3\2\2\2\u02ea\u02eb"+ + "\7v\2\2\u02eb\u02ec\7j\2\2\u02ec\u02ed\7g\2\2\u02ed\u02ee\7p\2\2\u02ee"+ + "\u00b4\3\2\2\2\u02ef\u02f0\7g\2\2\u02f0\u02f1\7n\2\2\u02f1\u02f2\7u\2"+ + "\2\u02f2\u02f3\7g\2\2\u02f3\u00b6\3\2\2\2\u02f4\u02f5\7v\2\2\u02f5\u02f6"+ + "\7{\2\2\u02f6\u02f7\7r\2\2\u02f7\u02f8\7g\2\2\u02f8\u02f9\7u\2\2\u02f9"+ + "\u02fa\7y\2\2\u02fa\u02fb\7k\2\2\u02fb\u02fc\7v\2\2\u02fc\u02fd\7e\2\2"+ + "\u02fd\u02fe\7j\2\2\u02fe\u00b8\3\2\2\2\u02ff\u0300\7q\2\2\u0300\u0301"+ + "\7t\2\2\u0301\u00ba\3\2\2\2\u0302\u0303\7c\2\2\u0303\u0304\7p\2\2\u0304"+ + "\u0305\7f\2\2\u0305\u00bc\3\2\2\2\u0306\u0307\7p\2\2\u0307\u0308\7q\2"+ + "\2\u0308\u0309\7v\2\2\u0309\u00be\3\2\2\2\u030a\u030b\7v\2\2\u030b\u030c"+ + "\7q\2\2\u030c\u00c0\3\2\2\2\u030d\u030e\7k\2\2\u030e\u030f\7p\2\2\u030f"+ + "\u0310\7u\2\2\u0310\u0311\7v\2\2\u0311\u0312\7c\2\2\u0312\u0313\7p\2\2"+ + "\u0313\u0314\7e\2\2\u0314\u0315\7g\2\2\u0315\u00c2\3\2\2\2\u0316\u0317"+ + "\7q\2\2\u0317\u0318\7h\2\2\u0318\u00c4\3\2\2\2\u0319\u031a\7u\2\2\u031a"+ + "\u031b\7v\2\2\u031b\u031c\7c\2\2\u031c\u031d\7v\2\2\u031d\u031e\7k\2\2"+ + "\u031e\u031f\7e\2\2\u031f\u0320\7c\2\2\u0320\u0321\7n\2\2\u0321\u0322"+ + "\7n\2\2\u0322\u0323\7{\2\2\u0323\u00c6\3\2\2\2\u0324\u0325\7k\2\2\u0325"+ + "\u0326\7u\2\2\u0326\u00c8\3\2\2\2\u0327\u0328\7v\2\2\u0328\u0329\7t\2"+ + "\2\u0329\u032a\7g\2\2\u032a\u032b\7c\2\2\u032b\u032c\7v\2\2\u032c\u00ca"+ + "\3\2\2\2\u032d\u032e\7e\2\2\u032e\u032f\7c\2\2\u032f\u0330\7u\2\2\u0330"+ + "\u0331\7v\2\2\u0331\u00cc\3\2\2\2\u0332\u0333\7e\2\2\u0333\u0334\7c\2"+ + "\2\u0334\u0335\7u\2\2\u0335\u0336\7v\2\2\u0336\u0337\7c\2\2\u0337\u0338"+ + "\7d\2\2\u0338\u0339\7n\2\2\u0339\u033a\7g\2\2\u033a\u00ce\3\2\2\2\u033b"+ + "\u033c\7x\2\2\u033c\u033d\7g\2\2\u033d\u033e\7t\2\2\u033e\u033f\7u\2\2"+ + "\u033f\u0340\7k\2\2\u0340\u0341\7q\2\2\u0341\u0342\7p\2\2\u0342\u00d0"+ + "\3\2\2\2\u0343\u0344\7l\2\2\u0344\u0345\7u\2\2\u0345\u0346\7q\2\2\u0346"+ + "\u0347\7p\2\2\u0347\u0348\7k\2\2\u0348\u0349\7s\2\2\u0349\u00d2\3\2\2"+ + "\2\u034a\u034f\7$\2\2\u034b\u034e\5\u00d5k\2\u034c\u034e\n\2\2\2\u034d"+ + "\u034b\3\2\2\2\u034d\u034c\3\2\2\2\u034e\u0351\3\2\2\2\u034f\u034d\3\2"+ + "\2\2\u034f\u0350\3\2\2\2\u0350\u0352\3\2\2\2\u0351\u034f\3\2\2\2\u0352"+ + "\u0353\7$\2\2\u0353\u00d4\3\2\2\2\u0354\u0357\7^\2\2\u0355\u0358\t\3\2"+ + "\2\u0356\u0358\5\u00d7l\2\u0357\u0355\3\2\2\2\u0357\u0356\3\2\2\2\u0358"+ + "\u00d6\3\2\2\2\u0359\u035a\7w\2\2\u035a\u035b\5\u00d9m\2\u035b\u035c\5"+ + "\u00d9m\2\u035c\u035d\5\u00d9m\2\u035d\u035e\5\u00d9m\2\u035e\u00d8\3"+ + "\2\2\2\u035f\u0360\t\4\2\2\u0360\u00da\3\2\2\2\u0361\u0362\7A\2\2\u0362"+ + "\u00dc\3\2\2\2\u0363\u0364\7p\2\2\u0364\u0365\7w\2\2\u0365\u0366\7n\2"+ + "\2\u0366\u0367\7n\2\2\u0367\u00de\3\2\2\2\u0368\u036b\5\u00e1q\2\u0369"+ + "\u036b\5\u00e3r\2\u036a\u0368\3\2\2\2\u036a\u0369\3\2\2\2\u036b\u00e0"+ + "\3\2\2\2\u036c\u0370\5\u00e5s\2\u036d\u0370\5\u00e7t\2\u036e\u0370\5\u00e9"+ + "u\2\u036f\u036c\3\2\2\2\u036f\u036d\3\2\2\2\u036f\u036e\3\2\2\2\u0370"+ + "\u00e2\3\2\2\2\u0371\u0372\7v\2\2\u0372\u0373\7t\2\2\u0373\u0374\7w\2"+ + "\2\u0374\u037b\7g\2\2\u0375\u0376\7h\2\2\u0376\u0377\7c\2\2\u0377\u0378"+ + "\7n\2\2\u0378\u0379\7u\2\2\u0379\u037b\7g\2\2\u037a\u0371\3\2\2\2\u037a"+ + "\u0375\3\2\2\2\u037b\u00e4\3\2\2\2\u037c\u037d\5\u00ebv\2\u037d\u00e6"+ + "\3\2\2\2\u037e\u037f\7\60\2\2\u037f\u0389\5\u00ebv\2\u0380\u0381\5\u00eb"+ + "v\2\u0381\u0385\7\60\2\2\u0382\u0384\t\5\2\2\u0383\u0382\3\2\2\2\u0384"+ + "\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386\u0389\3\2"+ + "\2\2\u0387\u0385\3\2\2\2\u0388\u037e\3\2\2\2\u0388\u0380\3\2\2\2\u0389"+ + "\u00e8\3\2\2\2\u038a\u038b\7\60\2\2\u038b\u0397\5\u00ebv\2\u038c\u0394"+ + "\5\u00ebv\2\u038d\u0391\7\60\2\2\u038e\u0390\t\5\2\2\u038f\u038e\3\2\2"+ + "\2\u0390\u0393\3\2\2\2\u0391\u038f\3\2\2\2\u0391\u0392\3\2\2\2\u0392\u0395"+ + "\3\2\2\2\u0393\u0391\3\2\2\2\u0394\u038d\3\2\2\2\u0394\u0395\3\2\2\2\u0395"+ + "\u0397\3\2\2\2\u0396\u038a\3\2\2\2\u0396\u038c\3\2\2\2\u0397\u0398\3\2"+ + "\2\2\u0398\u039a\t\6\2\2\u0399\u039b\t\7\2\2\u039a\u0399\3\2\2\2\u039a"+ + "\u039b\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039d\5\u00ebv\2\u039d\u00ea"+ + "\3\2\2\2\u039e\u03a0\t\5\2\2\u039f\u039e\3\2\2\2\u03a0\u03a1\3\2\2\2\u03a1"+ + "\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u00ec\3\2\2\2\u03a3\u03a4\t\b"+ + "\2\2\u03a4\u03a5\3\2\2\2\u03a5\u03a6\bw\2\2\u03a6\u00ee\3\2\2\2\u03a7"+ + "\u03ab\5\u00f1y\2\u03a8\u03aa\5\u00f3z\2\u03a9\u03a8\3\2\2\2\u03aa\u03ad"+ + "\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u00f0\3\2\2\2\u03ad"+ + "\u03ab\3\2\2\2\u03ae\u03b0\t\t\2\2\u03af\u03ae\3\2\2\2\u03b0\u00f2\3\2"+ + "\2\2\u03b1\u03b4\5\u00f1y\2\u03b2\u03b4\t\n\2\2\u03b3\u03b1\3\2\2\2\u03b3"+ + "\u03b2\3\2\2\2\u03b4\u00f4\3\2\2\2\u03b5\u03b6\7*\2\2\u03b6\u03bf\7<\2"+ + "\2\u03b7\u03be\5\u00f5{\2\u03b8\u03b9\7*\2\2\u03b9\u03be\n\13\2\2\u03ba"+ + "\u03bb\7<\2\2\u03bb\u03be\n\f\2\2\u03bc\u03be\n\r\2\2\u03bd\u03b7\3\2"+ + "\2\2\u03bd\u03b8\3\2\2\2\u03bd\u03ba\3\2\2\2\u03bd\u03bc\3\2\2\2\u03be"+ + "\u03c1\3\2\2\2\u03bf\u03bd\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0\u03c3\3\2"+ + "\2\2\u03c1\u03bf\3\2\2\2\u03c2\u03c4\7<\2\2\u03c3\u03c2\3\2\2\2\u03c4"+ + "\u03c5\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c5\u03c6\3\2\2\2\u03c6\u03c7\3\2"+ + "\2\2\u03c7\u03c8\7+\2\2\u03c8\u03c9\3\2\2\2\u03c9\u03ca\b{\2\2\u03ca\u00f6"+ + "\3\2\2\2\u03cb\u03cc\n\16\2\2\u03cc\u00f8\3\2\2\2\26\2\u034d\u034f\u0357"+ + "\u036a\u036f\u037a\u0385\u0388\u0391\u0394\u0396\u039a\u03a1\u03ab\u03af"+ + "\u03b3\u03bd\u03bf\u03c5\3\2\3\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens b/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens index ced2126dd5..d1974c069c 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens @@ -57,51 +57,51 @@ T__55=56 T__56=57 T__57=58 T__58=59 -Kfor=60 -Klet=61 -Kwhere=62 -Kgroup=63 -Kby=64 -Korder=65 -Kreturn=66 -Kif=67 -Kin=68 -Kas=69 -Kat=70 -Kallowing=71 -Kempty=72 -Kcount=73 -Kstable=74 -Kascending=75 -Kdescending=76 -Ksome=77 -Kevery=78 -Ksatisfies=79 -Kcollation=80 -Kgreatest=81 -Kleast=82 -Kswitch=83 -Kcase=84 -Ktry=85 -Kcatch=86 -Kdefault=87 -Kthen=88 -Kelse=89 -Ktypeswitch=90 -Kor=91 -Kand=92 -Knot=93 -Kto=94 -Kinstance=95 -Kof=96 -Kstatically=97 -Kis=98 -Ktreat=99 -Kcast=100 -Kcastable=101 -Kversion=102 -Kjsoniq=103 -Kunordered=104 +T__59=60 +Kfor=61 +Klet=62 +Kwhere=63 +Kgroup=64 +Kby=65 +Korder=66 +Kreturn=67 +Kif=68 +Kin=69 +Kas=70 +Kat=71 +Kallowing=72 +Kempty=73 +Kcount=74 +Kstable=75 +Kascending=76 +Kdescending=77 +Ksome=78 +Kevery=79 +Ksatisfies=80 +Kcollation=81 +Kgreatest=82 +Kleast=83 +Kswitch=84 +Kcase=85 +Ktry=86 +Kcatch=87 +Kdefault=88 +Kthen=89 +Kelse=90 +Ktypeswitch=91 +Kor=92 +Kand=93 +Knot=94 +Kto=95 +Kinstance=96 +Kof=97 +Kstatically=98 +Kis=99 +Ktreat=100 +Kcast=101 +Kcastable=102 +Kversion=103 +Kjsoniq=104 STRING=105 ArgumentPlaceholder=106 NullLiteral=107 @@ -122,102 +122,102 @@ ContentChar=117 'declare'=5 'ordering'=6 'ordered'=7 -'decimal-format'=8 -':'=9 -'decimal-separator'=10 -'grouping-separator'=11 -'infinity'=12 -'minus-sign'=13 -'NaN'=14 -'percent'=15 -'per-mille'=16 -'zero-digit'=17 -'digit'=18 -'pattern-separator'=19 -'import'=20 -','=21 -'variable'=22 -':='=23 -'external'=24 -'function'=25 -'('=26 -')'=27 -'{'=28 -'}'=29 -'type'=30 -'$'=31 -'|'=32 -'*'=33 -'eq'=34 -'ne'=35 -'lt'=36 -'le'=37 -'gt'=38 -'ge'=39 -'!='=40 -'<'=41 -'<='=42 -'>'=43 -'>='=44 -'||'=45 -'+'=46 -'-'=47 -'div'=48 -'idiv'=49 -'mod'=50 -'validate'=51 -'!'=52 -'['=53 -']'=54 -'.'=55 -'$$'=56 -'#'=57 -'{|'=58 -'|}'=59 -'for'=60 -'let'=61 -'where'=62 -'group'=63 -'by'=64 -'order'=65 -'return'=66 -'if'=67 -'in'=68 -'as'=69 -'at'=70 -'allowing'=71 -'empty'=72 -'count'=73 -'stable'=74 -'ascending'=75 -'descending'=76 -'some'=77 -'every'=78 -'satisfies'=79 -'collation'=80 -'greatest'=81 -'least'=82 -'switch'=83 -'case'=84 -'try'=85 -'catch'=86 -'default'=87 -'then'=88 -'else'=89 -'typeswitch'=90 -'or'=91 -'and'=92 -'not'=93 -'to'=94 -'instance'=95 -'of'=96 -'statically'=97 -'is'=98 -'treat'=99 -'cast'=100 -'castable'=101 -'version'=102 -'jsoniq'=103 -'unordered'=104 +'unordered'=8 +'decimal-format'=9 +':'=10 +'decimal-separator'=11 +'grouping-separator'=12 +'infinity'=13 +'minus-sign'=14 +'NaN'=15 +'percent'=16 +'per-mille'=17 +'zero-digit'=18 +'digit'=19 +'pattern-separator'=20 +'import'=21 +','=22 +'variable'=23 +':='=24 +'external'=25 +'function'=26 +'('=27 +')'=28 +'{'=29 +'}'=30 +'type'=31 +'$'=32 +'|'=33 +'*'=34 +'eq'=35 +'ne'=36 +'lt'=37 +'le'=38 +'gt'=39 +'ge'=40 +'!='=41 +'<'=42 +'<='=43 +'>'=44 +'>='=45 +'||'=46 +'+'=47 +'-'=48 +'div'=49 +'idiv'=50 +'mod'=51 +'validate'=52 +'!'=53 +'['=54 +']'=55 +'.'=56 +'$$'=57 +'#'=58 +'{|'=59 +'|}'=60 +'for'=61 +'let'=62 +'where'=63 +'group'=64 +'by'=65 +'order'=66 +'return'=67 +'if'=68 +'in'=69 +'as'=70 +'at'=71 +'allowing'=72 +'empty'=73 +'count'=74 +'stable'=75 +'ascending'=76 +'descending'=77 +'some'=78 +'every'=79 +'satisfies'=80 +'collation'=81 +'greatest'=82 +'least'=83 +'switch'=84 +'case'=85 +'try'=86 +'catch'=87 +'default'=88 +'then'=89 +'else'=90 +'typeswitch'=91 +'or'=92 +'and'=93 +'not'=94 +'to'=95 +'instance'=96 +'of'=97 +'statically'=98 +'is'=99 +'treat'=100 +'cast'=101 +'castable'=102 +'version'=103 +'jsoniq'=104 '?'=106 'null'=107 diff --git a/src/main/java/org/rumbledb/parser/JsoniqParser.java b/src/main/java/org/rumbledb/parser/JsoniqParser.java index 0ddaa7a548..4f8a6a4122 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqParser.java +++ b/src/main/java/org/rumbledb/parser/JsoniqParser.java @@ -3,14 +3,25 @@ // Java header package org.rumbledb.parser; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; -import java.util.List; -import java.util.Iterator; import java.util.ArrayList; +import java.util.List; + +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) public class JsoniqParser extends Parser { @@ -28,54 +39,54 @@ public class JsoniqParser extends Parser { T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45, T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52, T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, - Kfor=60, Klet=61, Kwhere=62, Kgroup=63, Kby=64, Korder=65, Kreturn=66, - Kif=67, Kin=68, Kas=69, Kat=70, Kallowing=71, Kempty=72, Kcount=73, Kstable=74, - Kascending=75, Kdescending=76, Ksome=77, Kevery=78, Ksatisfies=79, Kcollation=80, - Kgreatest=81, Kleast=82, Kswitch=83, Kcase=84, Ktry=85, Kcatch=86, Kdefault=87, - Kthen=88, Kelse=89, Ktypeswitch=90, Kor=91, Kand=92, Knot=93, Kto=94, - Kinstance=95, Kof=96, Kstatically=97, Kis=98, Ktreat=99, Kcast=100, Kcastable=101, - Kversion=102, Kjsoniq=103, Kunordered=104, STRING=105, ArgumentPlaceholder=106, - NullLiteral=107, Literal=108, NumericLiteral=109, BooleanLiteral=110, - IntegerLiteral=111, DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, - XQComment=116, ContentChar=117; + T__59=60, Kfor=61, Klet=62, Kwhere=63, Kgroup=64, Kby=65, Korder=66, Kreturn=67, + Kif=68, Kin=69, Kas=70, Kat=71, Kallowing=72, Kempty=73, Kcount=74, Kstable=75, + Kascending=76, Kdescending=77, Ksome=78, Kevery=79, Ksatisfies=80, Kcollation=81, + Kgreatest=82, Kleast=83, Kswitch=84, Kcase=85, Ktry=86, Kcatch=87, Kdefault=88, + Kthen=89, Kelse=90, Ktypeswitch=91, Kor=92, Kand=93, Knot=94, Kto=95, + Kinstance=96, Kof=97, Kstatically=98, Kis=99, Ktreat=100, Kcast=101, Kcastable=102, + Kversion=103, Kjsoniq=104, STRING=105, ArgumentPlaceholder=106, NullLiteral=107, + Literal=108, NumericLiteral=109, BooleanLiteral=110, IntegerLiteral=111, + DecimalLiteral=112, DoubleLiteral=113, WS=114, NCName=115, XQComment=116, + ContentChar=117; public static final int RULE_moduleAndThisIsIt = 0, RULE_module = 1, RULE_mainModule = 2, RULE_libraryModule = 3, RULE_prolog = 4, RULE_setter = 5, RULE_namespaceDecl = 6, RULE_annotatedDecl = 7, RULE_defaultCollationDecl = 8, RULE_orderingModeDecl = 9, RULE_emptyOrderDecl = 10, - RULE_decimalFormatDecl = 11, RULE_qname = 12, RULE_dfPropertyName = 13, - RULE_moduleImport = 14, RULE_varDecl = 15, RULE_functionDecl = 16, RULE_typeDecl = 17, - RULE_paramList = 18, RULE_param = 19, RULE_expr = 20, RULE_exprSingle = 21, - RULE_flowrExpr = 22, RULE_forClause = 23, RULE_forVar = 24, RULE_letClause = 25, - RULE_letVar = 26, RULE_whereClause = 27, RULE_groupByClause = 28, RULE_groupByVar = 29, - RULE_orderByClause = 30, RULE_orderByExpr = 31, RULE_countClause = 32, - RULE_quantifiedExpr = 33, RULE_quantifiedExprVar = 34, RULE_switchExpr = 35, - RULE_switchCaseClause = 36, RULE_typeSwitchExpr = 37, RULE_caseClause = 38, - RULE_ifExpr = 39, RULE_tryCatchExpr = 40, RULE_catchClause = 41, RULE_orExpr = 42, - RULE_andExpr = 43, RULE_notExpr = 44, RULE_comparisonExpr = 45, RULE_stringConcatExpr = 46, - RULE_rangeExpr = 47, RULE_additiveExpr = 48, RULE_multiplicativeExpr = 49, - RULE_instanceOfExpr = 50, RULE_isStaticallyExpr = 51, RULE_treatExpr = 52, - RULE_castableExpr = 53, RULE_castExpr = 54, RULE_arrowExpr = 55, RULE_unaryExpr = 56, - RULE_valueExpr = 57, RULE_validateExpr = 58, RULE_simpleMapExpr = 59, - RULE_postFixExpr = 60, RULE_arrayLookup = 61, RULE_arrayUnboxing = 62, - RULE_predicate = 63, RULE_objectLookup = 64, RULE_primaryExpr = 65, RULE_varRef = 66, - RULE_parenthesizedExpr = 67, RULE_contextItemExpr = 68, RULE_orderedExpr = 69, - RULE_unorderedExpr = 70, RULE_functionCall = 71, RULE_argumentList = 72, - RULE_argument = 73, RULE_functionItemExpr = 74, RULE_namedFunctionRef = 75, - RULE_inlineFunctionExpr = 76, RULE_sequenceType = 77, RULE_objectConstructor = 78, - RULE_itemType = 79, RULE_functionTest = 80, RULE_anyFunctionTest = 81, - RULE_typedFunctionTest = 82, RULE_singleType = 83, RULE_pairConstructor = 84, - RULE_arrayConstructor = 85, RULE_uriLiteral = 86, RULE_stringLiteral = 87, - RULE_keyWords = 88; + RULE_decimalFormatDecl = 11, RULE_qname = 12, RULE_nCNameOrKeyWord = 13, + RULE_dfPropertyName = 14, RULE_moduleImport = 15, RULE_varDecl = 16, RULE_functionDecl = 17, + RULE_typeDecl = 18, RULE_paramList = 19, RULE_param = 20, RULE_expr = 21, + RULE_exprSingle = 22, RULE_flowrExpr = 23, RULE_forClause = 24, RULE_forVar = 25, + RULE_letClause = 26, RULE_letVar = 27, RULE_whereClause = 28, RULE_groupByClause = 29, + RULE_groupByVar = 30, RULE_orderByClause = 31, RULE_orderByExpr = 32, + RULE_countClause = 33, RULE_quantifiedExpr = 34, RULE_quantifiedExprVar = 35, + RULE_switchExpr = 36, RULE_switchCaseClause = 37, RULE_typeSwitchExpr = 38, + RULE_caseClause = 39, RULE_ifExpr = 40, RULE_tryCatchExpr = 41, RULE_catchClause = 42, + RULE_orExpr = 43, RULE_andExpr = 44, RULE_notExpr = 45, RULE_comparisonExpr = 46, + RULE_stringConcatExpr = 47, RULE_rangeExpr = 48, RULE_additiveExpr = 49, + RULE_multiplicativeExpr = 50, RULE_instanceOfExpr = 51, RULE_isStaticallyExpr = 52, + RULE_treatExpr = 53, RULE_castableExpr = 54, RULE_castExpr = 55, RULE_arrowExpr = 56, + RULE_unaryExpr = 57, RULE_valueExpr = 58, RULE_validateExpr = 59, RULE_simpleMapExpr = 60, + RULE_postFixExpr = 61, RULE_arrayLookup = 62, RULE_arrayUnboxing = 63, + RULE_predicate = 64, RULE_objectLookup = 65, RULE_primaryExpr = 66, RULE_varRef = 67, + RULE_parenthesizedExpr = 68, RULE_contextItemExpr = 69, RULE_orderedExpr = 70, + RULE_unorderedExpr = 71, RULE_functionCall = 72, RULE_argumentList = 73, + RULE_argument = 74, RULE_functionItemExpr = 75, RULE_namedFunctionRef = 76, + RULE_inlineFunctionExpr = 77, RULE_sequenceType = 78, RULE_objectConstructor = 79, + RULE_itemType = 80, RULE_functionTest = 81, RULE_anyFunctionTest = 82, + RULE_typedFunctionTest = 83, RULE_singleType = 84, RULE_pairConstructor = 85, + RULE_arrayConstructor = 86, RULE_uriLiteral = 87, RULE_stringLiteral = 88, + RULE_keyWords = 89; public static final String[] ruleNames = { "moduleAndThisIsIt", "module", "mainModule", "libraryModule", "prolog", "setter", "namespaceDecl", "annotatedDecl", "defaultCollationDecl", "orderingModeDecl", - "emptyOrderDecl", "decimalFormatDecl", "qname", "dfPropertyName", "moduleImport", - "varDecl", "functionDecl", "typeDecl", "paramList", "param", "expr", "exprSingle", - "flowrExpr", "forClause", "forVar", "letClause", "letVar", "whereClause", - "groupByClause", "groupByVar", "orderByClause", "orderByExpr", "countClause", - "quantifiedExpr", "quantifiedExprVar", "switchExpr", "switchCaseClause", - "typeSwitchExpr", "caseClause", "ifExpr", "tryCatchExpr", "catchClause", - "orExpr", "andExpr", "notExpr", "comparisonExpr", "stringConcatExpr", + "emptyOrderDecl", "decimalFormatDecl", "qname", "nCNameOrKeyWord", "dfPropertyName", + "moduleImport", "varDecl", "functionDecl", "typeDecl", "paramList", "param", + "expr", "exprSingle", "flowrExpr", "forClause", "forVar", "letClause", + "letVar", "whereClause", "groupByClause", "groupByVar", "orderByClause", + "orderByExpr", "countClause", "quantifiedExpr", "quantifiedExprVar", "switchExpr", + "switchCaseClause", "typeSwitchExpr", "caseClause", "ifExpr", "tryCatchExpr", + "catchClause", "orExpr", "andExpr", "notExpr", "comparisonExpr", "stringConcatExpr", "rangeExpr", "additiveExpr", "multiplicativeExpr", "instanceOfExpr", "isStaticallyExpr", "treatExpr", "castableExpr", "castExpr", "arrowExpr", "unaryExpr", "valueExpr", "validateExpr", "simpleMapExpr", "postFixExpr", "arrayLookup", "arrayUnboxing", @@ -89,20 +100,21 @@ public class JsoniqParser extends Parser { private static final String[] _LITERAL_NAMES = { null, "';'", "'module'", "'namespace'", "'='", "'declare'", "'ordering'", - "'ordered'", "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", - "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", - "'digit'", "'pattern-separator'", "'import'", "','", "'variable'", "':='", - "'external'", "'function'", "'('", "')'", "'{'", "'}'", "'type'", "'$'", - "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", "'gt'", "'ge'", "'!='", - "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", "'div'", "'idiv'", - "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", "'$$'", "'#'", "'{|'", - "'|}'", "'for'", "'let'", "'where'", "'group'", "'by'", "'order'", "'return'", - "'if'", "'in'", "'as'", "'at'", "'allowing'", "'empty'", "'count'", "'stable'", - "'ascending'", "'descending'", "'some'", "'every'", "'satisfies'", "'collation'", - "'greatest'", "'least'", "'switch'", "'case'", "'try'", "'catch'", "'default'", - "'then'", "'else'", "'typeswitch'", "'or'", "'and'", "'not'", "'to'", - "'instance'", "'of'", "'statically'", "'is'", "'treat'", "'cast'", "'castable'", - "'version'", "'jsoniq'", "'unordered'", null, "'?'", "'null'" + "'ordered'", "'unordered'", "'decimal-format'", "':'", "'decimal-separator'", + "'grouping-separator'", "'infinity'", "'minus-sign'", "'NaN'", "'percent'", + "'per-mille'", "'zero-digit'", "'digit'", "'pattern-separator'", "'import'", + "','", "'variable'", "':='", "'external'", "'function'", "'('", "')'", + "'{'", "'}'", "'type'", "'$'", "'|'", "'*'", "'eq'", "'ne'", "'lt'", "'le'", + "'gt'", "'ge'", "'!='", "'<'", "'<='", "'>'", "'>='", "'||'", "'+'", "'-'", + "'div'", "'idiv'", "'mod'", "'validate'", "'!'", "'['", "']'", "'.'", + "'$$'", "'#'", "'{|'", "'|}'", "'for'", "'let'", "'where'", "'group'", + "'by'", "'order'", "'return'", "'if'", "'in'", "'as'", "'at'", "'allowing'", + "'empty'", "'count'", "'stable'", "'ascending'", "'descending'", "'some'", + "'every'", "'satisfies'", "'collation'", "'greatest'", "'least'", "'switch'", + "'case'", "'try'", "'catch'", "'default'", "'then'", "'else'", "'typeswitch'", + "'or'", "'and'", "'not'", "'to'", "'instance'", "'of'", "'statically'", + "'is'", "'treat'", "'cast'", "'castable'", "'version'", "'jsoniq'", null, + "'?'", "'null'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -110,15 +122,15 @@ public class JsoniqParser extends Parser { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", "Kif", - "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", "Kascending", - "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", "Kgreatest", - "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", "Kthen", "Kelse", - "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", "Kof", "Kstatically", - "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", "Kjsoniq", "Kunordered", - "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", - "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", - "WS", "NCName", "XQComment", "ContentChar" + null, "Kfor", "Klet", "Kwhere", "Kgroup", "Kby", "Korder", "Kreturn", + "Kif", "Kin", "Kas", "Kat", "Kallowing", "Kempty", "Kcount", "Kstable", + "Kascending", "Kdescending", "Ksome", "Kevery", "Ksatisfies", "Kcollation", + "Kgreatest", "Kleast", "Kswitch", "Kcase", "Ktry", "Kcatch", "Kdefault", + "Kthen", "Kelse", "Ktypeswitch", "Kor", "Kand", "Knot", "Kto", "Kinstance", + "Kof", "Kstatically", "Kis", "Ktreat", "Kcast", "Kcastable", "Kversion", + "Kjsoniq", "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", + "NumericLiteral", "BooleanLiteral", "IntegerLiteral", "DecimalLiteral", + "DoubleLiteral", "WS", "NCName", "XQComment", "ContentChar" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -191,9 +203,9 @@ public final ModuleAndThisIsItContext moduleAndThisIsIt() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(178); + setState(180); module(); - setState(179); + setState(181); match(EOF); } } @@ -239,44 +251,45 @@ public final ModuleContext module() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(186); + setState(188); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { case 1: { - setState(181); + setState(183); match(Kjsoniq); - setState(182); + setState(184); match(Kversion); - setState(183); + setState(185); ((ModuleContext)_localctx).vers = stringLiteral(); - setState(184); + setState(186); match(T__0); } break; } - setState(190); + setState(192); _errHandler.sync(this); switch (_input.LA(1)) { case T__1: { - setState(188); + setState(190); libraryModule(); } break; case T__4: case T__6: - case T__19: - case T__24: + case T__7: + case T__20: case T__25: - case T__27: - case T__30: - case T__45: + case T__26: + case T__28: + case T__31: case T__46: - case T__50: - case T__52: - case T__55: - case T__57: + case T__47: + case T__51: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -321,13 +334,12 @@ public final ModuleContext module() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: { - setState(189); + setState(191); ((ModuleContext)_localctx).main = mainModule(); } break; @@ -371,9 +383,9 @@ public final MainModuleContext mainModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(192); + setState(194); prolog(); - setState(193); + setState(195); expr(); } } @@ -413,19 +425,19 @@ public final LibraryModuleContext libraryModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(195); + setState(197); match(T__1); - setState(196); + setState(198); match(T__2); - setState(197); + setState(199); match(NCName); - setState(198); + setState(200); match(T__3); - setState(199); + setState(201); uriLiteral(); - setState(200); + setState(202); match(T__0); - setState(201); + setState(203); prolog(); } } @@ -484,57 +496,57 @@ public final PrologContext prolog() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(212); + setState(214); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(206); + setState(208); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: { - setState(203); + setState(205); setter(); } break; case 2: { - setState(204); + setState(206); namespaceDecl(); } break; case 3: { - setState(205); + setState(207); moduleImport(); } break; } - setState(208); + setState(210); match(T__0); } } } - setState(214); + setState(216); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); } - setState(220); + setState(222); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__4) { { { - setState(215); + setState(217); annotatedDecl(); - setState(216); + setState(218); match(T__0); } } - setState(222); + setState(224); _errHandler.sync(this); _la = _input.LA(1); } @@ -579,34 +591,34 @@ public final SetterContext setter() throws RecognitionException { SetterContext _localctx = new SetterContext(_ctx, getState()); enterRule(_localctx, 10, RULE_setter); try { - setState(227); + setState(229); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(223); + setState(225); defaultCollationDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(224); + setState(226); orderingModeDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(225); + setState(227); emptyOrderDecl(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(226); + setState(228); decimalFormatDecl(); } break; @@ -645,15 +657,15 @@ public final NamespaceDeclContext namespaceDecl() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(229); + setState(231); match(T__4); - setState(230); + setState(232); match(T__2); - setState(231); + setState(233); match(NCName); - setState(232); + setState(234); match(T__3); - setState(233); + setState(235); uriLiteral(); } } @@ -693,27 +705,27 @@ public final AnnotatedDeclContext annotatedDecl() throws RecognitionException { AnnotatedDeclContext _localctx = new AnnotatedDeclContext(_ctx, getState()); enterRule(_localctx, 14, RULE_annotatedDecl); try { - setState(238); + setState(240); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(235); + setState(237); functionDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(236); + setState(238); varDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(237); + setState(239); typeDecl(); } break; @@ -753,13 +765,13 @@ public final DefaultCollationDeclContext defaultCollationDecl() throws Recogniti try { enterOuterAlt(_localctx, 1); { - setState(240); + setState(242); match(T__4); - setState(241); + setState(243); match(Kdefault); - setState(242); + setState(244); match(Kcollation); - setState(243); + setState(245); uriLiteral(); } } @@ -793,13 +805,13 @@ public final OrderingModeDeclContext orderingModeDecl() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(245); + setState(247); match(T__4); - setState(246); + setState(248); match(T__5); - setState(247); + setState(249); _la = _input.LA(1); - if ( !(_la==T__6 || _la==Kunordered) ) { + if ( !(_la==T__6 || _la==T__7) ) { _errHandler.recoverInline(this); } else { @@ -844,16 +856,16 @@ public final EmptyOrderDeclContext emptyOrderDecl() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(249); + setState(251); match(T__4); - setState(250); + setState(252); match(Kdefault); - setState(251); + setState(253); match(Korder); - setState(252); + setState(254); match(Kempty); { - setState(253); + setState(255); ((EmptyOrderDeclContext)_localctx).emptySequenceOrder = _input.LT(1); _la = _input.LA(1); if ( !(_la==Kgreatest || _la==Kleast) ) { @@ -913,17 +925,17 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(255); + setState(257); match(T__4); - setState(260); + setState(262); _errHandler.sync(this); switch (_input.LA(1)) { - case T__7: + case T__8: { { - setState(256); - match(T__7); - setState(257); + setState(258); + match(T__8); + setState(259); qname(); } } @@ -931,31 +943,31 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce case Kdefault: { { - setState(258); + setState(260); match(Kdefault); - setState(259); - match(T__7); + setState(261); + match(T__8); } } break; default: throw new NoViableAltException(this); } - setState(268); + setState(270); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) { { { - setState(262); + setState(264); dfPropertyName(); - setState(263); + setState(265); match(T__3); - setState(264); + setState(266); stringLiteral(); } } - setState(270); + setState(272); _errHandler.sync(this); _la = _input.LA(1); } @@ -975,11 +987,10 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce public static class QnameContext extends ParserRuleContext { public Token ns; public KeyWordsContext nskw; - public Token local_name; + public NCNameOrKeyWordContext local_name; public KeyWordsContext local_namekw; - public List NCName() { return getTokens(JsoniqParser.NCName); } - public TerminalNode NCName(int i) { - return getToken(JsoniqParser.NCName, i); + public NCNameOrKeyWordContext nCNameOrKeyWord() { + return getRuleContext(NCNameOrKeyWordContext.class,0); } public List keyWords() { return getRuleContexts(KeyWordsContext.class); @@ -987,6 +998,7 @@ public List keyWords() { public KeyWordsContext keyWords(int i) { return getRuleContext(KeyWordsContext.class,i); } + public TerminalNode NCName() { return getToken(JsoniqParser.NCName, 0); } public QnameContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -1004,17 +1016,17 @@ public final QnameContext qname() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(276); + setState(278); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: { - setState(273); + setState(275); _errHandler.sync(this); switch (_input.LA(1)) { case NCName: { - setState(271); + setState(273); ((QnameContext)_localctx).ns = match(NCName); } break; @@ -1062,83 +1074,79 @@ public final QnameContext qname() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: { - setState(272); + setState(274); ((QnameContext)_localctx).nskw = keyWords(); } break; default: throw new NoViableAltException(this); } - setState(275); - match(T__8); + setState(277); + match(T__9); } break; } - setState(280); + setState(282); _errHandler.sync(this); - switch (_input.LA(1)) { - case NCName: + switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { + case 1: { - setState(278); - ((QnameContext)_localctx).local_name = match(NCName); + setState(280); + ((QnameContext)_localctx).local_name = nCNameOrKeyWord(); } break; - case Kfor: - case Klet: - case Kwhere: - case Kgroup: - case Kby: - case Korder: - case Kreturn: - case Kif: - case Kin: - case Kas: - case Kat: - case Kallowing: - case Kempty: - case Kcount: - case Kstable: - case Kascending: - case Kdescending: - case Ksome: - case Kevery: - case Ksatisfies: - case Kcollation: - case Kgreatest: - case Kleast: - case Kswitch: - case Kcase: - case Ktry: - case Kcatch: - case Kdefault: - case Kthen: - case Kelse: - case Ktypeswitch: - case Kor: - case Kand: - case Knot: - case Kto: - case Kinstance: - case Kof: - case Kstatically: - case Kis: - case Ktreat: - case Kcast: - case Kcastable: - case Kversion: - case Kjsoniq: - case Kunordered: - case NullLiteral: + case 2: { - setState(279); + setState(281); ((QnameContext)_localctx).local_namekw = keyWords(); } break; - default: - throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class NCNameOrKeyWordContext extends ParserRuleContext { + public TerminalNode NCName() { return getToken(JsoniqParser.NCName, 0); } + public TerminalNode NullLiteral() { return getToken(JsoniqParser.NullLiteral, 0); } + public NCNameOrKeyWordContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nCNameOrKeyWord; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitNCNameOrKeyWord(this); + else return visitor.visitChildren(this); + } + } + + public final NCNameOrKeyWordContext nCNameOrKeyWord() throws RecognitionException { + NCNameOrKeyWordContext _localctx = new NCNameOrKeyWordContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_nCNameOrKeyWord); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(284); + _la = _input.LA(1); + if ( !(_la==NullLiteral || _la==NCName) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); } } } @@ -1167,14 +1175,14 @@ public T accept(ParseTreeVisitor visitor) { public final DfPropertyNameContext dfPropertyName() throws RecognitionException { DfPropertyNameContext _localctx = new DfPropertyNameContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_dfPropertyName); + enterRule(_localctx, 28, RULE_dfPropertyName); int _la; try { enterOuterAlt(_localctx, 1); { - setState(282); + setState(286); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -1219,53 +1227,53 @@ public T accept(ParseTreeVisitor visitor) { public final ModuleImportContext moduleImport() throws RecognitionException { ModuleImportContext _localctx = new ModuleImportContext(_ctx, getState()); - enterRule(_localctx, 28, RULE_moduleImport); + enterRule(_localctx, 30, RULE_moduleImport); int _la; try { enterOuterAlt(_localctx, 1); { - setState(284); - match(T__19); - setState(285); - match(T__1); + setState(288); + match(T__20); setState(289); + match(T__1); + setState(293); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__2) { { - setState(286); + setState(290); match(T__2); - setState(287); + setState(291); ((ModuleImportContext)_localctx).prefix = match(NCName); - setState(288); + setState(292); match(T__3); } } - setState(291); + setState(295); ((ModuleImportContext)_localctx).targetNamespace = uriLiteral(); - setState(301); + setState(305); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(292); + setState(296); match(Kat); - setState(293); + setState(297); uriLiteral(); - setState(298); + setState(302); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(294); - match(T__20); - setState(295); + setState(298); + match(T__21); + setState(299); uriLiteral(); } } - setState(300); + setState(304); _errHandler.sync(this); _la = _input.LA(1); } @@ -1310,55 +1318,55 @@ public T accept(ParseTreeVisitor visitor) { public final VarDeclContext varDecl() throws RecognitionException { VarDeclContext _localctx = new VarDeclContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_varDecl); + enterRule(_localctx, 32, RULE_varDecl); int _la; try { enterOuterAlt(_localctx, 1); { - setState(303); + setState(307); match(T__4); - setState(304); - match(T__21); - setState(305); - varRef(); setState(308); + match(T__22); + setState(309); + varRef(); + setState(312); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(306); + setState(310); match(Kas); - setState(307); + setState(311); sequenceType(); } } - setState(317); + setState(321); _errHandler.sync(this); switch (_input.LA(1)) { - case T__22: + case T__23: { { - setState(310); - match(T__22); - setState(311); + setState(314); + match(T__23); + setState(315); exprSingle(); } } break; - case T__23: + case T__24: { { - setState(312); - ((VarDeclContext)_localctx).external = match(T__23); - setState(315); + setState(316); + ((VarDeclContext)_localctx).external = match(T__24); + setState(319); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__22) { + if (_la==T__23) { { - setState(313); - match(T__22); - setState(314); + setState(317); + match(T__23); + setState(318); exprSingle(); } } @@ -1412,68 +1420,68 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionDeclContext functionDecl() throws RecognitionException { FunctionDeclContext _localctx = new FunctionDeclContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_functionDecl); + enterRule(_localctx, 34, RULE_functionDecl); int _la; try { enterOuterAlt(_localctx, 1); { - setState(319); + setState(323); match(T__4); - setState(320); - match(T__24); - setState(321); - ((FunctionDeclContext)_localctx).fn_name = qname(); - setState(322); - match(T__25); setState(324); + match(T__25); + setState(325); + ((FunctionDeclContext)_localctx).fn_name = qname(); + setState(326); + match(T__26); + setState(328); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__30) { + if (_la==T__31) { { - setState(323); + setState(327); paramList(); } } - setState(326); - match(T__26); - setState(329); + setState(330); + match(T__27); + setState(333); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(327); + setState(331); match(Kas); - setState(328); + setState(332); ((FunctionDeclContext)_localctx).return_type = sequenceType(); } } - setState(337); + setState(341); _errHandler.sync(this); switch (_input.LA(1)) { - case T__27: + case T__28: { - setState(331); - match(T__27); - setState(333); + setState(335); + match(T__28); + setState(337); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(332); + setState(336); ((FunctionDeclContext)_localctx).fn_body = expr(); } } - setState(335); - match(T__28); + setState(339); + match(T__29); } break; - case T__23: + case T__24: { - setState(336); - match(T__23); + setState(340); + match(T__24); } break; default: @@ -1514,19 +1522,19 @@ public T accept(ParseTreeVisitor visitor) { public final TypeDeclContext typeDecl() throws RecognitionException { TypeDeclContext _localctx = new TypeDeclContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_typeDecl); + enterRule(_localctx, 36, RULE_typeDecl); try { enterOuterAlt(_localctx, 1); { - setState(339); + setState(343); match(T__4); - setState(340); - match(T__29); - setState(341); + setState(344); + match(T__30); + setState(345); ((TypeDeclContext)_localctx).type_name = qname(); - setState(342); + setState(346); match(Kas); - setState(343); + setState(347); ((TypeDeclContext)_localctx).type_definition = exprSingle(); } } @@ -1561,26 +1569,26 @@ public T accept(ParseTreeVisitor visitor) { public final ParamListContext paramList() throws RecognitionException { ParamListContext _localctx = new ParamListContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_paramList); + enterRule(_localctx, 38, RULE_paramList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(345); + setState(349); param(); - setState(350); + setState(354); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(346); - match(T__20); - setState(347); + setState(350); + match(T__21); + setState(351); param(); } } - setState(352); + setState(356); _errHandler.sync(this); _la = _input.LA(1); } @@ -1618,23 +1626,23 @@ public T accept(ParseTreeVisitor visitor) { public final ParamContext param() throws RecognitionException { ParamContext _localctx = new ParamContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_param); + enterRule(_localctx, 40, RULE_param); int _la; try { enterOuterAlt(_localctx, 1); { - setState(353); - match(T__30); - setState(354); - qname(); setState(357); + match(T__31); + setState(358); + qname(); + setState(361); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(355); + setState(359); match(Kas); - setState(356); + setState(360); sequenceType(); } } @@ -1672,26 +1680,26 @@ public T accept(ParseTreeVisitor visitor) { public final ExprContext expr() throws RecognitionException { ExprContext _localctx = new ExprContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_expr); + enterRule(_localctx, 42, RULE_expr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(359); + setState(363); exprSingle(); - setState(364); + setState(368); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(360); - match(T__20); - setState(361); + setState(364); + match(T__21); + setState(365); exprSingle(); } } - setState(366); + setState(370); _errHandler.sync(this); _la = _input.LA(1); } @@ -1743,57 +1751,57 @@ public T accept(ParseTreeVisitor visitor) { public final ExprSingleContext exprSingle() throws RecognitionException { ExprSingleContext _localctx = new ExprSingleContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_exprSingle); + enterRule(_localctx, 44, RULE_exprSingle); try { - setState(374); + setState(378); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(367); + setState(371); flowrExpr(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(368); + setState(372); quantifiedExpr(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(369); + setState(373); switchExpr(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(370); + setState(374); typeSwitchExpr(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(371); + setState(375); ifExpr(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(372); + setState(376); tryCatchExpr(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(373); + setState(377); orExpr(); } break; @@ -1867,71 +1875,71 @@ public T accept(ParseTreeVisitor visitor) { public final FlowrExprContext flowrExpr() throws RecognitionException { FlowrExprContext _localctx = new FlowrExprContext(_ctx, getState()); - enterRule(_localctx, 44, RULE_flowrExpr); + enterRule(_localctx, 46, RULE_flowrExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(378); + setState(382); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(376); + setState(380); ((FlowrExprContext)_localctx).start_for = forClause(); } break; case Klet: { - setState(377); + setState(381); ((FlowrExprContext)_localctx).start_let = letClause(); } break; default: throw new NoViableAltException(this); } - setState(388); + setState(392); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (Kfor - 60)) | (1L << (Klet - 60)) | (1L << (Kwhere - 60)) | (1L << (Kgroup - 60)) | (1L << (Korder - 60)) | (1L << (Kcount - 60)) | (1L << (Kstable - 60)))) != 0)) { + while (((((_la - 61)) & ~0x3f) == 0 && ((1L << (_la - 61)) & ((1L << (Kfor - 61)) | (1L << (Klet - 61)) | (1L << (Kwhere - 61)) | (1L << (Kgroup - 61)) | (1L << (Korder - 61)) | (1L << (Kcount - 61)) | (1L << (Kstable - 61)))) != 0)) { { - setState(386); + setState(390); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(380); + setState(384); forClause(); } break; case Kwhere: { - setState(381); + setState(385); whereClause(); } break; case Klet: { - setState(382); + setState(386); letClause(); } break; case Kgroup: { - setState(383); + setState(387); groupByClause(); } break; case Korder: case Kstable: { - setState(384); + setState(388); orderByClause(); } break; case Kcount: { - setState(385); + setState(389); countClause(); } break; @@ -1939,13 +1947,13 @@ public final FlowrExprContext flowrExpr() throws RecognitionException { throw new NoViableAltException(this); } } - setState(390); + setState(394); _errHandler.sync(this); _la = _input.LA(1); } - setState(391); + setState(395); match(Kreturn); - setState(392); + setState(396); ((FlowrExprContext)_localctx).return_expr = exprSingle(); } } @@ -1983,30 +1991,30 @@ public T accept(ParseTreeVisitor visitor) { public final ForClauseContext forClause() throws RecognitionException { ForClauseContext _localctx = new ForClauseContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_forClause); + enterRule(_localctx, 48, RULE_forClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(394); + setState(398); match(Kfor); - setState(395); + setState(399); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); - setState(400); + setState(404); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(396); - match(T__20); - setState(397); + setState(400); + match(T__21); + setState(401); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); } } - setState(402); + setState(406); _errHandler.sync(this); _la = _input.LA(1); } @@ -2059,52 +2067,52 @@ public T accept(ParseTreeVisitor visitor) { public final ForVarContext forVar() throws RecognitionException { ForVarContext _localctx = new ForVarContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_forVar); + enterRule(_localctx, 50, RULE_forVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(403); + setState(407); ((ForVarContext)_localctx).var_ref = varRef(); - setState(406); + setState(410); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(404); + setState(408); match(Kas); - setState(405); + setState(409); ((ForVarContext)_localctx).seq = sequenceType(); } } - setState(410); + setState(414); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kallowing) { { - setState(408); + setState(412); ((ForVarContext)_localctx).flag = match(Kallowing); - setState(409); + setState(413); match(Kempty); } } - setState(414); + setState(418); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(412); + setState(416); match(Kat); - setState(413); + setState(417); ((ForVarContext)_localctx).at = varRef(); } } - setState(416); + setState(420); match(Kin); - setState(417); + setState(421); ((ForVarContext)_localctx).ex = exprSingle(); } } @@ -2142,30 +2150,30 @@ public T accept(ParseTreeVisitor visitor) { public final LetClauseContext letClause() throws RecognitionException { LetClauseContext _localctx = new LetClauseContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_letClause); + enterRule(_localctx, 52, RULE_letClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(419); + setState(423); match(Klet); - setState(420); + setState(424); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); - setState(425); + setState(429); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(421); - match(T__20); - setState(422); + setState(425); + match(T__21); + setState(426); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); } } - setState(427); + setState(431); _errHandler.sync(this); _la = _input.LA(1); } @@ -2209,28 +2217,28 @@ public T accept(ParseTreeVisitor visitor) { public final LetVarContext letVar() throws RecognitionException { LetVarContext _localctx = new LetVarContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_letVar); + enterRule(_localctx, 54, RULE_letVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(428); + setState(432); ((LetVarContext)_localctx).var_ref = varRef(); - setState(431); + setState(435); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(429); + setState(433); match(Kas); - setState(430); + setState(434); ((LetVarContext)_localctx).seq = sequenceType(); } } - setState(433); - match(T__22); - setState(434); + setState(437); + match(T__23); + setState(438); ((LetVarContext)_localctx).ex = exprSingle(); } } @@ -2263,13 +2271,13 @@ public T accept(ParseTreeVisitor visitor) { public final WhereClauseContext whereClause() throws RecognitionException { WhereClauseContext _localctx = new WhereClauseContext(_ctx, getState()); - enterRule(_localctx, 54, RULE_whereClause); + enterRule(_localctx, 56, RULE_whereClause); try { enterOuterAlt(_localctx, 1); { - setState(436); + setState(440); match(Kwhere); - setState(437); + setState(441); exprSingle(); } } @@ -2308,32 +2316,32 @@ public T accept(ParseTreeVisitor visitor) { public final GroupByClauseContext groupByClause() throws RecognitionException { GroupByClauseContext _localctx = new GroupByClauseContext(_ctx, getState()); - enterRule(_localctx, 56, RULE_groupByClause); + enterRule(_localctx, 58, RULE_groupByClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(439); + setState(443); match(Kgroup); - setState(440); + setState(444); match(Kby); - setState(441); + setState(445); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); - setState(446); + setState(450); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(442); - match(T__20); - setState(443); + setState(446); + match(T__21); + setState(447); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); } } - setState(448); + setState(452); _errHandler.sync(this); _la = _input.LA(1); } @@ -2383,45 +2391,45 @@ public T accept(ParseTreeVisitor visitor) { public final GroupByVarContext groupByVar() throws RecognitionException { GroupByVarContext _localctx = new GroupByVarContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_groupByVar); + enterRule(_localctx, 60, RULE_groupByVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(449); + setState(453); ((GroupByVarContext)_localctx).var_ref = varRef(); - setState(456); + setState(460); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__22 || _la==Kas) { + if (_la==T__23 || _la==Kas) { { - setState(452); + setState(456); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(450); + setState(454); match(Kas); - setState(451); + setState(455); ((GroupByVarContext)_localctx).seq = sequenceType(); } } - setState(454); - ((GroupByVarContext)_localctx).decl = match(T__22); - setState(455); + setState(458); + ((GroupByVarContext)_localctx).decl = match(T__23); + setState(459); ((GroupByVarContext)_localctx).ex = exprSingle(); } } - setState(460); + setState(464); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(458); + setState(462); match(Kcollation); - setState(459); + setState(463); ((GroupByVarContext)_localctx).uri = uriLiteral(); } } @@ -2463,20 +2471,20 @@ public T accept(ParseTreeVisitor visitor) { public final OrderByClauseContext orderByClause() throws RecognitionException { OrderByClauseContext _localctx = new OrderByClauseContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_orderByClause); + enterRule(_localctx, 62, RULE_orderByClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(467); + setState(471); _errHandler.sync(this); switch (_input.LA(1)) { case Korder: { { - setState(462); + setState(466); match(Korder); - setState(463); + setState(467); match(Kby); } } @@ -2484,11 +2492,11 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { case Kstable: { { - setState(464); + setState(468); ((OrderByClauseContext)_localctx).stb = match(Kstable); - setState(465); + setState(469); match(Korder); - setState(466); + setState(470); match(Kby); } } @@ -2496,21 +2504,21 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(469); + setState(473); orderByExpr(); - setState(474); + setState(478); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(470); - match(T__20); - setState(471); + setState(474); + match(T__21); + setState(475); orderByExpr(); } } - setState(476); + setState(480); _errHandler.sync(this); _la = _input.LA(1); } @@ -2558,29 +2566,29 @@ public T accept(ParseTreeVisitor visitor) { public final OrderByExprContext orderByExpr() throws RecognitionException { OrderByExprContext _localctx = new OrderByExprContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_orderByExpr); + enterRule(_localctx, 64, RULE_orderByExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(477); + setState(481); ((OrderByExprContext)_localctx).ex = exprSingle(); - setState(480); + setState(484); _errHandler.sync(this); switch (_input.LA(1)) { case Kascending: { - setState(478); + setState(482); match(Kascending); } break; case Kdescending: { - setState(479); + setState(483); ((OrderByExprContext)_localctx).desc = match(Kdescending); } break; - case T__20: + case T__21: case Kfor: case Klet: case Kwhere: @@ -2595,25 +2603,25 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { default: break; } - setState(487); + setState(491); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kempty) { { - setState(482); + setState(486); match(Kempty); - setState(485); + setState(489); _errHandler.sync(this); switch (_input.LA(1)) { case Kgreatest: { - setState(483); + setState(487); ((OrderByExprContext)_localctx).gr = match(Kgreatest); } break; case Kleast: { - setState(484); + setState(488); ((OrderByExprContext)_localctx).ls = match(Kleast); } break; @@ -2623,14 +2631,14 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { } } - setState(491); + setState(495); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(489); + setState(493); match(Kcollation); - setState(490); + setState(494); ((OrderByExprContext)_localctx).uril = uriLiteral(); } } @@ -2666,13 +2674,13 @@ public T accept(ParseTreeVisitor visitor) { public final CountClauseContext countClause() throws RecognitionException { CountClauseContext _localctx = new CountClauseContext(_ctx, getState()); - enterRule(_localctx, 64, RULE_countClause); + enterRule(_localctx, 66, RULE_countClause); try { enterOuterAlt(_localctx, 1); { - setState(493); + setState(497); match(Kcount); - setState(494); + setState(498); varRef(); } } @@ -2717,52 +2725,52 @@ public T accept(ParseTreeVisitor visitor) { public final QuantifiedExprContext quantifiedExpr() throws RecognitionException { QuantifiedExprContext _localctx = new QuantifiedExprContext(_ctx, getState()); - enterRule(_localctx, 66, RULE_quantifiedExpr); + enterRule(_localctx, 68, RULE_quantifiedExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(498); + setState(502); _errHandler.sync(this); switch (_input.LA(1)) { case Ksome: { - setState(496); + setState(500); ((QuantifiedExprContext)_localctx).so = match(Ksome); } break; case Kevery: { - setState(497); + setState(501); ((QuantifiedExprContext)_localctx).ev = match(Kevery); } break; default: throw new NoViableAltException(this); } - setState(500); + setState(504); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); - setState(505); + setState(509); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(501); - match(T__20); - setState(502); + setState(505); + match(T__21); + setState(506); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); } } - setState(507); + setState(511); _errHandler.sync(this); _la = _input.LA(1); } - setState(508); + setState(512); match(Ksatisfies); - setState(509); + setState(513); exprSingle(); } } @@ -2802,28 +2810,28 @@ public T accept(ParseTreeVisitor visitor) { public final QuantifiedExprVarContext quantifiedExprVar() throws RecognitionException { QuantifiedExprVarContext _localctx = new QuantifiedExprVarContext(_ctx, getState()); - enterRule(_localctx, 68, RULE_quantifiedExprVar); + enterRule(_localctx, 70, RULE_quantifiedExprVar); int _la; try { enterOuterAlt(_localctx, 1); { - setState(511); + setState(515); varRef(); - setState(514); + setState(518); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(512); + setState(516); match(Kas); - setState(513); + setState(517); sequenceType(); } } - setState(516); + setState(520); match(Kin); - setState(517); + setState(521); exprSingle(); } } @@ -2871,39 +2879,39 @@ public T accept(ParseTreeVisitor visitor) { public final SwitchExprContext switchExpr() throws RecognitionException { SwitchExprContext _localctx = new SwitchExprContext(_ctx, getState()); - enterRule(_localctx, 70, RULE_switchExpr); + enterRule(_localctx, 72, RULE_switchExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(519); + setState(523); match(Kswitch); - setState(520); - match(T__25); - setState(521); - ((SwitchExprContext)_localctx).cond = expr(); - setState(522); + setState(524); match(T__26); - setState(524); + setState(525); + ((SwitchExprContext)_localctx).cond = expr(); + setState(526); + match(T__27); + setState(528); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(523); + setState(527); ((SwitchExprContext)_localctx).switchCaseClause = switchCaseClause(); ((SwitchExprContext)_localctx).cases.add(((SwitchExprContext)_localctx).switchCaseClause); } } - setState(526); + setState(530); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(528); + setState(532); match(Kdefault); - setState(529); + setState(533); match(Kreturn); - setState(530); + setState(534); ((SwitchExprContext)_localctx).def = exprSingle(); } } @@ -2946,31 +2954,31 @@ public T accept(ParseTreeVisitor visitor) { public final SwitchCaseClauseContext switchCaseClause() throws RecognitionException { SwitchCaseClauseContext _localctx = new SwitchCaseClauseContext(_ctx, getState()); - enterRule(_localctx, 72, RULE_switchCaseClause); + enterRule(_localctx, 74, RULE_switchCaseClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(534); + setState(538); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(532); + setState(536); match(Kcase); - setState(533); + setState(537); ((SwitchCaseClauseContext)_localctx).exprSingle = exprSingle(); ((SwitchCaseClauseContext)_localctx).cond.add(((SwitchCaseClauseContext)_localctx).exprSingle); } } - setState(536); + setState(540); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(538); + setState(542); match(Kreturn); - setState(539); + setState(543); ((SwitchCaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3022,49 +3030,49 @@ public T accept(ParseTreeVisitor visitor) { public final TypeSwitchExprContext typeSwitchExpr() throws RecognitionException { TypeSwitchExprContext _localctx = new TypeSwitchExprContext(_ctx, getState()); - enterRule(_localctx, 74, RULE_typeSwitchExpr); + enterRule(_localctx, 76, RULE_typeSwitchExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(541); + setState(545); match(Ktypeswitch); - setState(542); - match(T__25); - setState(543); - ((TypeSwitchExprContext)_localctx).cond = expr(); - setState(544); + setState(546); match(T__26); - setState(546); + setState(547); + ((TypeSwitchExprContext)_localctx).cond = expr(); + setState(548); + match(T__27); + setState(550); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(545); + setState(549); ((TypeSwitchExprContext)_localctx).caseClause = caseClause(); ((TypeSwitchExprContext)_localctx).cses.add(((TypeSwitchExprContext)_localctx).caseClause); } } - setState(548); + setState(552); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(550); + setState(554); match(Kdefault); - setState(552); + setState(556); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__30) { + if (_la==T__31) { { - setState(551); + setState(555); ((TypeSwitchExprContext)_localctx).var_ref = varRef(); } } - setState(554); + setState(558); match(Kreturn); - setState(555); + setState(559); ((TypeSwitchExprContext)_localctx).def = exprSingle(); } } @@ -3112,48 +3120,48 @@ public T accept(ParseTreeVisitor visitor) { public final CaseClauseContext caseClause() throws RecognitionException { CaseClauseContext _localctx = new CaseClauseContext(_ctx, getState()); - enterRule(_localctx, 76, RULE_caseClause); + enterRule(_localctx, 78, RULE_caseClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(557); - match(Kcase); setState(561); + match(Kcase); + setState(565); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__30) { + if (_la==T__31) { { - setState(558); + setState(562); ((CaseClauseContext)_localctx).var_ref = varRef(); - setState(559); + setState(563); match(Kas); } } - setState(563); + setState(567); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); - setState(568); + setState(572); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__31) { + while (_la==T__32) { { { - setState(564); - match(T__31); - setState(565); + setState(568); + match(T__32); + setState(569); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); } } - setState(570); + setState(574); _errHandler.sync(this); _la = _input.LA(1); } - setState(571); + setState(575); match(Kreturn); - setState(572); + setState(576); ((CaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3197,25 +3205,25 @@ public T accept(ParseTreeVisitor visitor) { public final IfExprContext ifExpr() throws RecognitionException { IfExprContext _localctx = new IfExprContext(_ctx, getState()); - enterRule(_localctx, 78, RULE_ifExpr); + enterRule(_localctx, 80, RULE_ifExpr); try { enterOuterAlt(_localctx, 1); { - setState(574); + setState(578); match(Kif); - setState(575); - match(T__25); - setState(576); - ((IfExprContext)_localctx).test_condition = expr(); - setState(577); + setState(579); match(T__26); - setState(578); + setState(580); + ((IfExprContext)_localctx).test_condition = expr(); + setState(581); + match(T__27); + setState(582); match(Kthen); - setState(579); + setState(583); ((IfExprContext)_localctx).branch = exprSingle(); - setState(580); + setState(584); match(Kelse); - setState(581); + setState(585); ((IfExprContext)_localctx).else_branch = exprSingle(); } } @@ -3257,20 +3265,20 @@ public T accept(ParseTreeVisitor visitor) { public final TryCatchExprContext tryCatchExpr() throws RecognitionException { TryCatchExprContext _localctx = new TryCatchExprContext(_ctx, getState()); - enterRule(_localctx, 80, RULE_tryCatchExpr); + enterRule(_localctx, 82, RULE_tryCatchExpr); try { int _alt; enterOuterAlt(_localctx, 1); - { - setState(583); - match(Ktry); - setState(584); - match(T__27); - setState(585); - ((TryCatchExprContext)_localctx).try_expression = expr(); - setState(586); + { + setState(587); + match(Ktry); + setState(588); match(T__28); - setState(588); + setState(589); + ((TryCatchExprContext)_localctx).try_expression = expr(); + setState(590); + match(T__29); + setState(592); _errHandler.sync(this); _alt = 1; do { @@ -3278,7 +3286,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { case 1: { { - setState(587); + setState(591); ((TryCatchExprContext)_localctx).catchClause = catchClause(); ((TryCatchExprContext)_localctx).catches.add(((TryCatchExprContext)_localctx).catchClause); } @@ -3287,7 +3295,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(590); + setState(594); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,54,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); @@ -3305,7 +3313,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { } public static class CatchClauseContext extends ParserRuleContext { - public Token s33; + public Token s34; public List jokers = new ArrayList(); public QnameContext qname; public List errors = new ArrayList(); @@ -3333,21 +3341,21 @@ public T accept(ParseTreeVisitor visitor) { public final CatchClauseContext catchClause() throws RecognitionException { CatchClauseContext _localctx = new CatchClauseContext(_ctx, getState()); - enterRule(_localctx, 82, RULE_catchClause); + enterRule(_localctx, 84, RULE_catchClause); int _la; try { enterOuterAlt(_localctx, 1); { - setState(592); + setState(596); match(Kcatch); - setState(595); + setState(599); _errHandler.sync(this); switch (_input.LA(1)) { - case T__32: + case T__33: { - setState(593); - ((CatchClauseContext)_localctx).s33 = match(T__32); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s33); + setState(597); + ((CatchClauseContext)_localctx).s34 = match(T__33); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); } break; case Kfor: @@ -3394,11 +3402,10 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: case NCName: { - setState(594); + setState(598); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3406,22 +3413,22 @@ public final CatchClauseContext catchClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(604); + setState(608); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__31) { + while (_la==T__32) { { { - setState(597); - match(T__31); - setState(600); + setState(601); + match(T__32); + setState(604); _errHandler.sync(this); switch (_input.LA(1)) { - case T__32: + case T__33: { - setState(598); - ((CatchClauseContext)_localctx).s33 = match(T__32); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s33); + setState(602); + ((CatchClauseContext)_localctx).s34 = match(T__33); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); } break; case Kfor: @@ -3468,11 +3475,10 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: case NCName: { - setState(599); + setState(603); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3482,16 +3488,16 @@ public final CatchClauseContext catchClause() throws RecognitionException { } } } - setState(606); + setState(610); _errHandler.sync(this); _la = _input.LA(1); } - setState(607); - match(T__27); - setState(608); - ((CatchClauseContext)_localctx).catch_expression = expr(); - setState(609); + setState(611); match(T__28); + setState(612); + ((CatchClauseContext)_localctx).catch_expression = expr(); + setState(613); + match(T__29); } } catch (RecognitionException re) { @@ -3532,29 +3538,29 @@ public T accept(ParseTreeVisitor visitor) { public final OrExprContext orExpr() throws RecognitionException { OrExprContext _localctx = new OrExprContext(_ctx, getState()); - enterRule(_localctx, 84, RULE_orExpr); + enterRule(_localctx, 86, RULE_orExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(611); + setState(615); ((OrExprContext)_localctx).main_expr = andExpr(); - setState(616); + setState(620); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,58,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(612); + setState(616); match(Kor); - setState(613); + setState(617); ((OrExprContext)_localctx).andExpr = andExpr(); ((OrExprContext)_localctx).rhs.add(((OrExprContext)_localctx).andExpr); } } } - setState(618); + setState(622); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,58,_ctx); } @@ -3598,29 +3604,29 @@ public T accept(ParseTreeVisitor visitor) { public final AndExprContext andExpr() throws RecognitionException { AndExprContext _localctx = new AndExprContext(_ctx, getState()); - enterRule(_localctx, 86, RULE_andExpr); + enterRule(_localctx, 88, RULE_andExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(619); + setState(623); ((AndExprContext)_localctx).main_expr = notExpr(); - setState(624); + setState(628); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(620); + setState(624); match(Kand); - setState(621); + setState(625); ((AndExprContext)_localctx).notExpr = notExpr(); ((AndExprContext)_localctx).rhs.add(((AndExprContext)_localctx).notExpr); } } } - setState(626); + setState(630); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); } @@ -3658,22 +3664,22 @@ public T accept(ParseTreeVisitor visitor) { public final NotExprContext notExpr() throws RecognitionException { NotExprContext _localctx = new NotExprContext(_ctx, getState()); - enterRule(_localctx, 88, RULE_notExpr); + enterRule(_localctx, 90, RULE_notExpr); try { enterOuterAlt(_localctx, 1); { - setState(628); + setState(632); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,60,_ctx) ) { case 1: { - setState(627); + setState(631); ((NotExprContext)_localctx).Knot = match(Knot); ((NotExprContext)_localctx).op.add(((NotExprContext)_localctx).Knot); } break; } - setState(630); + setState(634); ((NotExprContext)_localctx).main_expr = comparisonExpr(); } } @@ -3690,20 +3696,20 @@ public final NotExprContext notExpr() throws RecognitionException { public static class ComparisonExprContext extends ParserRuleContext { public StringConcatExprContext main_expr; - public Token s34; - public List op = new ArrayList(); public Token s35; + public List op = new ArrayList(); public Token s36; public Token s37; public Token s38; public Token s39; - public Token s4; public Token s40; + public Token s4; public Token s41; public Token s42; public Token s43; public Token s44; - public Token _tset1183; + public Token s45; + public Token _tset1194; public StringConcatExprContext stringConcatExpr; public List rhs = new ArrayList(); public List stringConcatExpr() { @@ -3725,31 +3731,31 @@ public T accept(ParseTreeVisitor visitor) { public final ComparisonExprContext comparisonExpr() throws RecognitionException { ComparisonExprContext _localctx = new ComparisonExprContext(_ctx, getState()); - enterRule(_localctx, 90, RULE_comparisonExpr); + enterRule(_localctx, 92, RULE_comparisonExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(632); + setState(636); ((ComparisonExprContext)_localctx).main_expr = stringConcatExpr(); - setState(635); + setState(639); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44))) != 0)) { { - setState(633); - ((ComparisonExprContext)_localctx)._tset1183 = _input.LT(1); + setState(637); + ((ComparisonExprContext)_localctx)._tset1194 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) ) { - ((ComparisonExprContext)_localctx)._tset1183 = (Token)_errHandler.recoverInline(this); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__44))) != 0)) ) { + ((ComparisonExprContext)_localctx)._tset1194 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1183); - setState(634); + ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1194); + setState(638); ((ComparisonExprContext)_localctx).stringConcatExpr = stringConcatExpr(); ((ComparisonExprContext)_localctx).rhs.add(((ComparisonExprContext)_localctx).stringConcatExpr); } @@ -3791,27 +3797,27 @@ public T accept(ParseTreeVisitor visitor) { public final StringConcatExprContext stringConcatExpr() throws RecognitionException { StringConcatExprContext _localctx = new StringConcatExprContext(_ctx, getState()); - enterRule(_localctx, 92, RULE_stringConcatExpr); + enterRule(_localctx, 94, RULE_stringConcatExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(637); + setState(641); ((StringConcatExprContext)_localctx).main_expr = rangeExpr(); - setState(642); + setState(646); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__44) { + while (_la==T__45) { { { - setState(638); - match(T__44); - setState(639); + setState(642); + match(T__45); + setState(643); ((StringConcatExprContext)_localctx).rangeExpr = rangeExpr(); ((StringConcatExprContext)_localctx).rhs.add(((StringConcatExprContext)_localctx).rangeExpr); } } - setState(644); + setState(648); _errHandler.sync(this); _la = _input.LA(1); } @@ -3852,20 +3858,20 @@ public T accept(ParseTreeVisitor visitor) { public final RangeExprContext rangeExpr() throws RecognitionException { RangeExprContext _localctx = new RangeExprContext(_ctx, getState()); - enterRule(_localctx, 94, RULE_rangeExpr); + enterRule(_localctx, 96, RULE_rangeExpr); try { enterOuterAlt(_localctx, 1); { - setState(645); + setState(649); ((RangeExprContext)_localctx).main_expr = additiveExpr(); - setState(648); + setState(652); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,63,_ctx) ) { case 1: { - setState(646); + setState(650); match(Kto); - setState(647); + setState(651); ((RangeExprContext)_localctx).additiveExpr = additiveExpr(); ((RangeExprContext)_localctx).rhs.add(((RangeExprContext)_localctx).additiveExpr); } @@ -3886,10 +3892,10 @@ public final RangeExprContext rangeExpr() throws RecognitionException { public static class AdditiveExprContext extends ParserRuleContext { public MultiplicativeExprContext main_expr; - public Token s46; - public List op = new ArrayList(); public Token s47; - public Token _tset1292; + public List op = new ArrayList(); + public Token s48; + public Token _tset1303; public MultiplicativeExprContext multiplicativeExpr; public List rhs = new ArrayList(); public List multiplicativeExpr() { @@ -3911,40 +3917,40 @@ public T accept(ParseTreeVisitor visitor) { public final AdditiveExprContext additiveExpr() throws RecognitionException { AdditiveExprContext _localctx = new AdditiveExprContext(_ctx, getState()); - enterRule(_localctx, 96, RULE_additiveExpr); + enterRule(_localctx, 98, RULE_additiveExpr); int _la; try { int _alt; enterOuterAlt(_localctx, 1); { - setState(650); + setState(654); ((AdditiveExprContext)_localctx).main_expr = multiplicativeExpr(); - setState(655); + setState(659); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,64,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(651); - ((AdditiveExprContext)_localctx)._tset1292 = _input.LT(1); + setState(655); + ((AdditiveExprContext)_localctx)._tset1303 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__45 || _la==T__46) ) { - ((AdditiveExprContext)_localctx)._tset1292 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__46 || _la==T__47) ) { + ((AdditiveExprContext)_localctx)._tset1303 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1292); - setState(652); + ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1303); + setState(656); ((AdditiveExprContext)_localctx).multiplicativeExpr = multiplicativeExpr(); ((AdditiveExprContext)_localctx).rhs.add(((AdditiveExprContext)_localctx).multiplicativeExpr); } } } - setState(657); + setState(661); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,64,_ctx); } @@ -3963,12 +3969,12 @@ public final AdditiveExprContext additiveExpr() throws RecognitionException { public static class MultiplicativeExprContext extends ParserRuleContext { public InstanceOfExprContext main_expr; - public Token s33; + public Token s34; public List op = new ArrayList(); - public Token s48; public Token s49; public Token s50; - public Token _tset1320; + public Token s51; + public Token _tset1331; public InstanceOfExprContext instanceOfExpr; public List rhs = new ArrayList(); public List instanceOfExpr() { @@ -3990,37 +3996,37 @@ public T accept(ParseTreeVisitor visitor) { public final MultiplicativeExprContext multiplicativeExpr() throws RecognitionException { MultiplicativeExprContext _localctx = new MultiplicativeExprContext(_ctx, getState()); - enterRule(_localctx, 98, RULE_multiplicativeExpr); + enterRule(_localctx, 100, RULE_multiplicativeExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(658); + setState(662); ((MultiplicativeExprContext)_localctx).main_expr = instanceOfExpr(); - setState(663); + setState(667); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__49))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) { { { - setState(659); - ((MultiplicativeExprContext)_localctx)._tset1320 = _input.LT(1); + setState(663); + ((MultiplicativeExprContext)_localctx)._tset1331 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__49))) != 0)) ) { - ((MultiplicativeExprContext)_localctx)._tset1320 = (Token)_errHandler.recoverInline(this); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) ) { + ((MultiplicativeExprContext)_localctx)._tset1331 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1320); - setState(660); + ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1331); + setState(664); ((MultiplicativeExprContext)_localctx).instanceOfExpr = instanceOfExpr(); ((MultiplicativeExprContext)_localctx).rhs.add(((MultiplicativeExprContext)_localctx).instanceOfExpr); } } - setState(665); + setState(669); _errHandler.sync(this); _la = _input.LA(1); } @@ -4061,22 +4067,22 @@ public T accept(ParseTreeVisitor visitor) { public final InstanceOfExprContext instanceOfExpr() throws RecognitionException { InstanceOfExprContext _localctx = new InstanceOfExprContext(_ctx, getState()); - enterRule(_localctx, 100, RULE_instanceOfExpr); + enterRule(_localctx, 102, RULE_instanceOfExpr); try { enterOuterAlt(_localctx, 1); { - setState(666); - ((InstanceOfExprContext)_localctx).main_expr = isStaticallyExpr(); setState(670); + ((InstanceOfExprContext)_localctx).main_expr = isStaticallyExpr(); + setState(674); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,66,_ctx) ) { case 1: { - setState(667); + setState(671); match(Kinstance); - setState(668); + setState(672); match(Kof); - setState(669); + setState(673); ((InstanceOfExprContext)_localctx).seq = sequenceType(); } break; @@ -4118,22 +4124,22 @@ public T accept(ParseTreeVisitor visitor) { public final IsStaticallyExprContext isStaticallyExpr() throws RecognitionException { IsStaticallyExprContext _localctx = new IsStaticallyExprContext(_ctx, getState()); - enterRule(_localctx, 102, RULE_isStaticallyExpr); + enterRule(_localctx, 104, RULE_isStaticallyExpr); try { enterOuterAlt(_localctx, 1); { - setState(672); - ((IsStaticallyExprContext)_localctx).main_expr = treatExpr(); setState(676); + ((IsStaticallyExprContext)_localctx).main_expr = treatExpr(); + setState(680); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,67,_ctx) ) { case 1: { - setState(673); + setState(677); match(Kis); - setState(674); + setState(678); match(Kstatically); - setState(675); + setState(679); ((IsStaticallyExprContext)_localctx).seq = sequenceType(); } break; @@ -4175,22 +4181,22 @@ public T accept(ParseTreeVisitor visitor) { public final TreatExprContext treatExpr() throws RecognitionException { TreatExprContext _localctx = new TreatExprContext(_ctx, getState()); - enterRule(_localctx, 104, RULE_treatExpr); + enterRule(_localctx, 106, RULE_treatExpr); try { enterOuterAlt(_localctx, 1); { - setState(678); - ((TreatExprContext)_localctx).main_expr = castableExpr(); setState(682); + ((TreatExprContext)_localctx).main_expr = castableExpr(); + setState(686); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { case 1: { - setState(679); + setState(683); match(Ktreat); - setState(680); + setState(684); match(Kas); - setState(681); + setState(685); ((TreatExprContext)_localctx).seq = sequenceType(); } break; @@ -4232,22 +4238,22 @@ public T accept(ParseTreeVisitor visitor) { public final CastableExprContext castableExpr() throws RecognitionException { CastableExprContext _localctx = new CastableExprContext(_ctx, getState()); - enterRule(_localctx, 106, RULE_castableExpr); + enterRule(_localctx, 108, RULE_castableExpr); try { enterOuterAlt(_localctx, 1); { - setState(684); - ((CastableExprContext)_localctx).main_expr = castExpr(); setState(688); + ((CastableExprContext)_localctx).main_expr = castExpr(); + setState(692); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,69,_ctx) ) { case 1: { - setState(685); + setState(689); match(Kcastable); - setState(686); + setState(690); match(Kas); - setState(687); + setState(691); ((CastableExprContext)_localctx).single = singleType(); } break; @@ -4289,22 +4295,22 @@ public T accept(ParseTreeVisitor visitor) { public final CastExprContext castExpr() throws RecognitionException { CastExprContext _localctx = new CastExprContext(_ctx, getState()); - enterRule(_localctx, 108, RULE_castExpr); + enterRule(_localctx, 110, RULE_castExpr); try { enterOuterAlt(_localctx, 1); { - setState(690); - ((CastExprContext)_localctx).main_expr = arrowExpr(); setState(694); + ((CastExprContext)_localctx).main_expr = arrowExpr(); + setState(698); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,70,_ctx) ) { case 1: { - setState(691); + setState(695); match(Kcast); - setState(692); + setState(696); match(Kas); - setState(693); + setState(697); ((CastExprContext)_localctx).single = singleType(); } break; @@ -4348,14 +4354,14 @@ public T accept(ParseTreeVisitor visitor) { public final ArrowExprContext arrowExpr() throws RecognitionException { ArrowExprContext _localctx = new ArrowExprContext(_ctx, getState()); - enterRule(_localctx, 110, RULE_arrowExpr); + enterRule(_localctx, 112, RULE_arrowExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(696); + setState(700); ((ArrowExprContext)_localctx).main_expr = unaryExpr(); - setState(703); + setState(707); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -4363,18 +4369,18 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { { { { - setState(697); + setState(701); match(T__3); - setState(698); - match(T__42); + setState(702); + match(T__43); } - setState(700); + setState(704); ((ArrowExprContext)_localctx).functionCall = functionCall(); ((ArrowExprContext)_localctx).function_call_expr.add(((ArrowExprContext)_localctx).functionCall); } } } - setState(705); + setState(709); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,71,_ctx); } @@ -4392,10 +4398,10 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { } public static class UnaryExprContext extends ParserRuleContext { - public Token s47; + public Token s48; public List op = new ArrayList(); - public Token s46; - public Token _tset1480; + public Token s47; + public Token _tset1491; public ValueExprContext main_expr; public ValueExprContext valueExpr() { return getRuleContext(ValueExprContext.class,0); @@ -4413,36 +4419,36 @@ public T accept(ParseTreeVisitor visitor) { public final UnaryExprContext unaryExpr() throws RecognitionException { UnaryExprContext _localctx = new UnaryExprContext(_ctx, getState()); - enterRule(_localctx, 112, RULE_unaryExpr); + enterRule(_localctx, 114, RULE_unaryExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(709); + setState(713); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__45 || _la==T__46) { + while (_la==T__46 || _la==T__47) { { { - setState(706); - ((UnaryExprContext)_localctx)._tset1480 = _input.LT(1); + setState(710); + ((UnaryExprContext)_localctx)._tset1491 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__45 || _la==T__46) ) { - ((UnaryExprContext)_localctx)._tset1480 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__46 || _la==T__47) ) { + ((UnaryExprContext)_localctx)._tset1491 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1480); + ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1491); } } - setState(711); + setState(715); _errHandler.sync(this); _la = _input.LA(1); } - setState(712); + setState(716); ((UnaryExprContext)_localctx).main_expr = valueExpr(); } } @@ -4479,19 +4485,20 @@ public T accept(ParseTreeVisitor visitor) { public final ValueExprContext valueExpr() throws RecognitionException { ValueExprContext _localctx = new ValueExprContext(_ctx, getState()); - enterRule(_localctx, 114, RULE_valueExpr); + enterRule(_localctx, 116, RULE_valueExpr); try { - setState(716); + setState(720); _errHandler.sync(this); switch (_input.LA(1)) { case T__6: - case T__24: + case T__7: case T__25: - case T__27: - case T__30: - case T__52: - case T__55: - case T__57: + case T__26: + case T__28: + case T__31: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -4536,21 +4543,20 @@ public final ValueExprContext valueExpr() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(714); + setState(718); ((ValueExprContext)_localctx).simpleMap_expr = simpleMapExpr(); } break; - case T__50: + case T__51: enterOuterAlt(_localctx, 2); { - setState(715); + setState(719); ((ValueExprContext)_localctx).validate_expr = validateExpr(); } break; @@ -4589,22 +4595,22 @@ public T accept(ParseTreeVisitor visitor) { public final ValidateExprContext validateExpr() throws RecognitionException { ValidateExprContext _localctx = new ValidateExprContext(_ctx, getState()); - enterRule(_localctx, 116, RULE_validateExpr); + enterRule(_localctx, 118, RULE_validateExpr); try { enterOuterAlt(_localctx, 1); { - setState(718); - match(T__50); - setState(719); - match(T__29); - setState(720); - sequenceType(); - setState(721); - match(T__27); setState(722); - expr(); + match(T__51); setState(723); + match(T__30); + setState(724); + sequenceType(); + setState(725); match(T__28); + setState(726); + expr(); + setState(727); + match(T__29); } } catch (RecognitionException re) { @@ -4641,27 +4647,27 @@ public T accept(ParseTreeVisitor visitor) { public final SimpleMapExprContext simpleMapExpr() throws RecognitionException { SimpleMapExprContext _localctx = new SimpleMapExprContext(_ctx, getState()); - enterRule(_localctx, 118, RULE_simpleMapExpr); + enterRule(_localctx, 120, RULE_simpleMapExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(725); + setState(729); ((SimpleMapExprContext)_localctx).main_expr = postFixExpr(); - setState(730); + setState(734); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__51) { + while (_la==T__52) { { { - setState(726); - match(T__51); - setState(727); + setState(730); + match(T__52); + setState(731); ((SimpleMapExprContext)_localctx).postFixExpr = postFixExpr(); ((SimpleMapExprContext)_localctx).map_expr.add(((SimpleMapExprContext)_localctx).postFixExpr); } } - setState(732); + setState(736); _errHandler.sync(this); _la = _input.LA(1); } @@ -4726,56 +4732,56 @@ public T accept(ParseTreeVisitor visitor) { public final PostFixExprContext postFixExpr() throws RecognitionException { PostFixExprContext _localctx = new PostFixExprContext(_ctx, getState()); - enterRule(_localctx, 120, RULE_postFixExpr); + enterRule(_localctx, 122, RULE_postFixExpr); try { int _alt; enterOuterAlt(_localctx, 1); { - setState(733); + setState(737); ((PostFixExprContext)_localctx).main_expr = primaryExpr(); - setState(741); + setState(745); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { - setState(739); + setState(743); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,75,_ctx) ) { case 1: { - setState(734); + setState(738); arrayLookup(); } break; case 2: { - setState(735); + setState(739); predicate(); } break; case 3: { - setState(736); + setState(740); objectLookup(); } break; case 4: { - setState(737); + setState(741); arrayUnboxing(); } break; case 5: { - setState(738); + setState(742); argumentList(); } break; } } } - setState(743); + setState(747); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); } @@ -4809,20 +4815,20 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayLookupContext arrayLookup() throws RecognitionException { ArrayLookupContext _localctx = new ArrayLookupContext(_ctx, getState()); - enterRule(_localctx, 122, RULE_arrayLookup); + enterRule(_localctx, 124, RULE_arrayLookup); try { enterOuterAlt(_localctx, 1); { - setState(744); - match(T__52); - setState(745); - match(T__52); - setState(746); - expr(); - setState(747); - match(T__53); setState(748); match(T__53); + setState(749); + match(T__53); + setState(750); + expr(); + setState(751); + match(T__54); + setState(752); + match(T__54); } } catch (RecognitionException re) { @@ -4850,14 +4856,14 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayUnboxingContext arrayUnboxing() throws RecognitionException { ArrayUnboxingContext _localctx = new ArrayUnboxingContext(_ctx, getState()); - enterRule(_localctx, 124, RULE_arrayUnboxing); + enterRule(_localctx, 126, RULE_arrayUnboxing); try { enterOuterAlt(_localctx, 1); { - setState(750); - match(T__52); - setState(751); + setState(754); match(T__53); + setState(755); + match(T__54); } } catch (RecognitionException re) { @@ -4888,16 +4894,16 @@ public T accept(ParseTreeVisitor visitor) { public final PredicateContext predicate() throws RecognitionException { PredicateContext _localctx = new PredicateContext(_ctx, getState()); - enterRule(_localctx, 126, RULE_predicate); + enterRule(_localctx, 128, RULE_predicate); try { enterOuterAlt(_localctx, 1); { - setState(753); - match(T__52); - setState(754); - expr(); - setState(755); + setState(757); match(T__53); + setState(758); + expr(); + setState(759); + match(T__54); } } catch (RecognitionException re) { @@ -4947,13 +4953,13 @@ public T accept(ParseTreeVisitor visitor) { public final ObjectLookupContext objectLookup() throws RecognitionException { ObjectLookupContext _localctx = new ObjectLookupContext(_ctx, getState()); - enterRule(_localctx, 128, RULE_objectLookup); + enterRule(_localctx, 130, RULE_objectLookup); try { enterOuterAlt(_localctx, 1); { - setState(757); - match(T__54); - setState(764); + setState(761); + match(T__55); + setState(768); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -5000,40 +5006,39 @@ public final ObjectLookupContext objectLookup() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: { - setState(758); + setState(762); ((ObjectLookupContext)_localctx).kw = keyWords(); } break; case STRING: { - setState(759); + setState(763); ((ObjectLookupContext)_localctx).lt = stringLiteral(); } break; case NCName: { - setState(760); + setState(764); ((ObjectLookupContext)_localctx).nc = match(NCName); } break; - case T__25: + case T__26: { - setState(761); + setState(765); ((ObjectLookupContext)_localctx).pe = parenthesizedExpr(); } break; - case T__30: + case T__31: { - setState(762); + setState(766); ((ObjectLookupContext)_localctx).vr = varRef(); } break; - case T__55: + case T__56: { - setState(763); + setState(767); ((ObjectLookupContext)_localctx).ci = contextItemExpr(); } break; @@ -5099,92 +5104,92 @@ public T accept(ParseTreeVisitor visitor) { public final PrimaryExprContext primaryExpr() throws RecognitionException { PrimaryExprContext _localctx = new PrimaryExprContext(_ctx, getState()); - enterRule(_localctx, 130, RULE_primaryExpr); + enterRule(_localctx, 132, RULE_primaryExpr); try { - setState(778); + setState(782); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,78,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(766); + setState(770); match(NullLiteral); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(767); + setState(771); match(Literal); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(768); + setState(772); stringLiteral(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(769); + setState(773); varRef(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(770); + setState(774); parenthesizedExpr(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(771); + setState(775); contextItemExpr(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(772); + setState(776); objectConstructor(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(773); + setState(777); functionCall(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(774); + setState(778); orderedExpr(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(775); + setState(779); unorderedExpr(); } break; case 11: enterOuterAlt(_localctx, 11); { - setState(776); + setState(780); arrayConstructor(); } break; case 12: enterOuterAlt(_localctx, 12); { - setState(777); + setState(781); functionItemExpr(); } break; @@ -5219,13 +5224,13 @@ public T accept(ParseTreeVisitor visitor) { public final VarRefContext varRef() throws RecognitionException { VarRefContext _localctx = new VarRefContext(_ctx, getState()); - enterRule(_localctx, 132, RULE_varRef); + enterRule(_localctx, 134, RULE_varRef); try { enterOuterAlt(_localctx, 1); { - setState(780); - match(T__30); - setState(781); + setState(784); + match(T__31); + setState(785); ((VarRefContext)_localctx).var_name = qname(); } } @@ -5257,25 +5262,25 @@ public T accept(ParseTreeVisitor visitor) { public final ParenthesizedExprContext parenthesizedExpr() throws RecognitionException { ParenthesizedExprContext _localctx = new ParenthesizedExprContext(_ctx, getState()); - enterRule(_localctx, 134, RULE_parenthesizedExpr); + enterRule(_localctx, 136, RULE_parenthesizedExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(783); - match(T__25); - setState(785); + setState(787); + match(T__26); + setState(789); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(784); + setState(788); expr(); } } - setState(787); - match(T__26); + setState(791); + match(T__27); } } catch (RecognitionException re) { @@ -5303,12 +5308,12 @@ public T accept(ParseTreeVisitor visitor) { public final ContextItemExprContext contextItemExpr() throws RecognitionException { ContextItemExprContext _localctx = new ContextItemExprContext(_ctx, getState()); - enterRule(_localctx, 136, RULE_contextItemExpr); + enterRule(_localctx, 138, RULE_contextItemExpr); try { enterOuterAlt(_localctx, 1); { - setState(789); - match(T__55); + setState(793); + match(T__56); } } catch (RecognitionException re) { @@ -5339,18 +5344,18 @@ public T accept(ParseTreeVisitor visitor) { public final OrderedExprContext orderedExpr() throws RecognitionException { OrderedExprContext _localctx = new OrderedExprContext(_ctx, getState()); - enterRule(_localctx, 138, RULE_orderedExpr); + enterRule(_localctx, 140, RULE_orderedExpr); try { enterOuterAlt(_localctx, 1); { - setState(791); + setState(795); match(T__6); - setState(792); - match(T__27); - setState(793); - expr(); - setState(794); + setState(796); match(T__28); + setState(797); + expr(); + setState(798); + match(T__29); } } catch (RecognitionException re) { @@ -5381,18 +5386,18 @@ public T accept(ParseTreeVisitor visitor) { public final UnorderedExprContext unorderedExpr() throws RecognitionException { UnorderedExprContext _localctx = new UnorderedExprContext(_ctx, getState()); - enterRule(_localctx, 140, RULE_unorderedExpr); + enterRule(_localctx, 142, RULE_unorderedExpr); try { enterOuterAlt(_localctx, 1); { - setState(796); - match(Kunordered); - setState(797); - match(T__27); - setState(798); - expr(); - setState(799); + setState(800); + match(T__7); + setState(801); match(T__28); + setState(802); + expr(); + setState(803); + match(T__29); } } catch (RecognitionException re) { @@ -5427,13 +5432,13 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionCallContext functionCall() throws RecognitionException { FunctionCallContext _localctx = new FunctionCallContext(_ctx, getState()); - enterRule(_localctx, 142, RULE_functionCall); + enterRule(_localctx, 144, RULE_functionCall); try { enterOuterAlt(_localctx, 1); { - setState(801); + setState(805); ((FunctionCallContext)_localctx).fn_name = qname(); - setState(802); + setState(806); argumentList(); } } @@ -5470,40 +5475,40 @@ public T accept(ParseTreeVisitor visitor) { public final ArgumentListContext argumentList() throws RecognitionException { ArgumentListContext _localctx = new ArgumentListContext(_ctx, getState()); - enterRule(_localctx, 144, RULE_argumentList); + enterRule(_localctx, 146, RULE_argumentList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(804); - match(T__25); - setState(811); + setState(808); + match(T__26); + setState(815); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (ArgumentPlaceholder - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (ArgumentPlaceholder - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { { - setState(805); + setState(809); ((ArgumentListContext)_localctx).argument = argument(); ((ArgumentListContext)_localctx).args.add(((ArgumentListContext)_localctx).argument); - setState(807); + setState(811); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__20) { + if (_la==T__21) { { - setState(806); - match(T__20); + setState(810); + match(T__21); } } } } - setState(813); + setState(817); _errHandler.sync(this); _la = _input.LA(1); } - setState(814); - match(T__26); + setState(818); + match(T__27); } } catch (RecognitionException re) { @@ -5535,22 +5540,23 @@ public T accept(ParseTreeVisitor visitor) { public final ArgumentContext argument() throws RecognitionException { ArgumentContext _localctx = new ArgumentContext(_ctx, getState()); - enterRule(_localctx, 146, RULE_argument); + enterRule(_localctx, 148, RULE_argument); try { - setState(818); + setState(822); _errHandler.sync(this); switch (_input.LA(1)) { case T__6: - case T__24: + case T__7: case T__25: - case T__27: - case T__30: - case T__45: + case T__26: + case T__28: + case T__31: case T__46: - case T__50: - case T__52: - case T__55: - case T__57: + case T__47: + case T__51: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -5595,21 +5601,20 @@ public final ArgumentContext argument() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(816); + setState(820); exprSingle(); } break; case ArgumentPlaceholder: enterOuterAlt(_localctx, 2); { - setState(817); + setState(821); match(ArgumentPlaceholder); } break; @@ -5648,9 +5653,9 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionItemExprContext functionItemExpr() throws RecognitionException { FunctionItemExprContext _localctx = new FunctionItemExprContext(_ctx, getState()); - enterRule(_localctx, 148, RULE_functionItemExpr); + enterRule(_localctx, 150, RULE_functionItemExpr); try { - setState(822); + setState(826); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -5697,19 +5702,18 @@ public final FunctionItemExprContext functionItemExpr() throws RecognitionExcept case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: case NCName: enterOuterAlt(_localctx, 1); { - setState(820); + setState(824); namedFunctionRef(); } break; - case T__24: + case T__25: enterOuterAlt(_localctx, 2); { - setState(821); + setState(825); inlineFunctionExpr(); } break; @@ -5748,15 +5752,15 @@ public T accept(ParseTreeVisitor visitor) { public final NamedFunctionRefContext namedFunctionRef() throws RecognitionException { NamedFunctionRefContext _localctx = new NamedFunctionRefContext(_ctx, getState()); - enterRule(_localctx, 150, RULE_namedFunctionRef); + enterRule(_localctx, 152, RULE_namedFunctionRef); try { enterOuterAlt(_localctx, 1); { - setState(824); + setState(828); ((NamedFunctionRefContext)_localctx).fn_name = qname(); - setState(825); - match(T__56); - setState(826); + setState(829); + match(T__57); + setState(830); ((NamedFunctionRefContext)_localctx).arity = match(Literal); } } @@ -5797,54 +5801,54 @@ public T accept(ParseTreeVisitor visitor) { public final InlineFunctionExprContext inlineFunctionExpr() throws RecognitionException { InlineFunctionExprContext _localctx = new InlineFunctionExprContext(_ctx, getState()); - enterRule(_localctx, 152, RULE_inlineFunctionExpr); + enterRule(_localctx, 154, RULE_inlineFunctionExpr); int _la; try { enterOuterAlt(_localctx, 1); { - setState(828); - match(T__24); - setState(829); + setState(832); match(T__25); - setState(831); + setState(833); + match(T__26); + setState(835); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__30) { + if (_la==T__31) { { - setState(830); + setState(834); paramList(); } } - setState(833); - match(T__26); - setState(836); + setState(837); + match(T__27); + setState(840); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(834); + setState(838); match(Kas); - setState(835); + setState(839); ((InlineFunctionExprContext)_localctx).return_type = sequenceType(); } } { - setState(838); - match(T__27); - setState(840); + setState(842); + match(T__28); + setState(844); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(839); + setState(843); ((InlineFunctionExprContext)_localctx).fn_body = expr(); } } - setState(842); - match(T__28); + setState(846); + match(T__29); } } } @@ -5863,9 +5867,9 @@ public static class SequenceTypeContext extends ParserRuleContext { public ItemTypeContext item; public Token s106; public List question = new ArrayList(); - public Token s33; + public Token s34; public List star = new ArrayList(); - public Token s46; + public Token s47; public List plus = new ArrayList(); public ItemTypeContext itemType() { return getRuleContext(ItemTypeContext.class,0); @@ -5883,21 +5887,21 @@ public T accept(ParseTreeVisitor visitor) { public final SequenceTypeContext sequenceType() throws RecognitionException { SequenceTypeContext _localctx = new SequenceTypeContext(_ctx, getState()); - enterRule(_localctx, 154, RULE_sequenceType); + enterRule(_localctx, 156, RULE_sequenceType); try { - setState(852); + setState(856); _errHandler.sync(this); switch (_input.LA(1)) { - case T__25: + case T__26: enterOuterAlt(_localctx, 1); { - setState(844); - match(T__25); - setState(845); + setState(848); match(T__26); + setState(849); + match(T__27); } break; - case T__24: + case T__25: case Kfor: case Klet: case Kwhere: @@ -5942,35 +5946,34 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { case Kcastable: case Kversion: case Kjsoniq: - case Kunordered: case NullLiteral: case NCName: enterOuterAlt(_localctx, 2); { - setState(846); - ((SequenceTypeContext)_localctx).item = itemType(); setState(850); + ((SequenceTypeContext)_localctx).item = itemType(); + setState(854); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,87,_ctx) ) { case 1: { - setState(847); + setState(851); ((SequenceTypeContext)_localctx).s106 = match(ArgumentPlaceholder); ((SequenceTypeContext)_localctx).question.add(((SequenceTypeContext)_localctx).s106); } break; case 2: { - setState(848); - ((SequenceTypeContext)_localctx).s33 = match(T__32); - ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s33); + setState(852); + ((SequenceTypeContext)_localctx).s34 = match(T__33); + ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s34); } break; case 3: { - setState(849); - ((SequenceTypeContext)_localctx).s46 = match(T__45); - ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s46); + setState(853); + ((SequenceTypeContext)_localctx).s47 = match(T__46); + ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s47); } break; } @@ -5992,7 +5995,7 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { } public static class ObjectConstructorContext extends ParserRuleContext { - public Token s58; + public Token s59; public List merge_operator = new ArrayList(); public List pairConstructor() { return getRuleContexts(PairConstructorContext.class); @@ -6016,57 +6019,57 @@ public T accept(ParseTreeVisitor visitor) { public final ObjectConstructorContext objectConstructor() throws RecognitionException { ObjectConstructorContext _localctx = new ObjectConstructorContext(_ctx, getState()); - enterRule(_localctx, 156, RULE_objectConstructor); + enterRule(_localctx, 158, RULE_objectConstructor); int _la; try { - setState(870); + setState(874); _errHandler.sync(this); switch (_input.LA(1)) { - case T__27: + case T__28: enterOuterAlt(_localctx, 1); { - setState(854); - match(T__27); - setState(863); + setState(858); + match(T__28); + setState(867); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(855); + setState(859); pairConstructor(); - setState(860); + setState(864); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(856); - match(T__20); - setState(857); + setState(860); + match(T__21); + setState(861); pairConstructor(); } } - setState(862); + setState(866); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(865); - match(T__28); + setState(869); + match(T__29); } break; - case T__57: + case T__58: enterOuterAlt(_localctx, 2); { - setState(866); - ((ObjectConstructorContext)_localctx).s58 = match(T__57); - ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s58); - setState(867); + setState(870); + ((ObjectConstructorContext)_localctx).s59 = match(T__58); + ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s59); + setState(871); expr(); - setState(868); - match(T__58); + setState(872); + match(T__59); } break; default: @@ -6105,29 +6108,29 @@ public T accept(ParseTreeVisitor visitor) { public final ItemTypeContext itemType() throws RecognitionException { ItemTypeContext _localctx = new ItemTypeContext(_ctx, getState()); - enterRule(_localctx, 158, RULE_itemType); + enterRule(_localctx, 160, RULE_itemType); try { - setState(875); + setState(879); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,92,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(872); + setState(876); qname(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(873); + setState(877); match(NullLiteral); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(874); + setState(878); functionTest(); } break; @@ -6164,22 +6167,22 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionTestContext functionTest() throws RecognitionException { FunctionTestContext _localctx = new FunctionTestContext(_ctx, getState()); - enterRule(_localctx, 160, RULE_functionTest); + enterRule(_localctx, 162, RULE_functionTest); try { enterOuterAlt(_localctx, 1); { - setState(879); + setState(883); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,93,_ctx) ) { case 1: { - setState(877); + setState(881); anyFunctionTest(); } break; case 2: { - setState(878); + setState(882); typedFunctionTest(); } break; @@ -6211,18 +6214,18 @@ public T accept(ParseTreeVisitor visitor) { public final AnyFunctionTestContext anyFunctionTest() throws RecognitionException { AnyFunctionTestContext _localctx = new AnyFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 162, RULE_anyFunctionTest); + enterRule(_localctx, 164, RULE_anyFunctionTest); try { enterOuterAlt(_localctx, 1); { - setState(881); - match(T__24); - setState(882); + setState(885); match(T__25); - setState(883); - match(T__32); - setState(884); + setState(886); match(T__26); + setState(887); + match(T__33); + setState(888); + match(T__27); } } catch (RecognitionException re) { @@ -6259,48 +6262,48 @@ public T accept(ParseTreeVisitor visitor) { public final TypedFunctionTestContext typedFunctionTest() throws RecognitionException { TypedFunctionTestContext _localctx = new TypedFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 164, RULE_typedFunctionTest); + enterRule(_localctx, 166, RULE_typedFunctionTest); int _la; try { enterOuterAlt(_localctx, 1); { - setState(886); - match(T__24); - setState(887); + setState(890); match(T__25); - setState(896); + setState(891); + match(T__26); + setState(900); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__24) | (1L << T__25) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (NullLiteral - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__25) | (1L << T__26) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (NullLiteral - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(888); + setState(892); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); - setState(893); + setState(897); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__20) { + while (_la==T__21) { { { - setState(889); - match(T__20); - setState(890); + setState(893); + match(T__21); + setState(894); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); } } - setState(895); + setState(899); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(898); - match(T__26); - setState(899); + setState(902); + match(T__27); + setState(903); match(Kas); - setState(900); + setState(904); ((TypedFunctionTestContext)_localctx).rt = sequenceType(); } } @@ -6335,18 +6338,18 @@ public T accept(ParseTreeVisitor visitor) { public final SingleTypeContext singleType() throws RecognitionException { SingleTypeContext _localctx = new SingleTypeContext(_ctx, getState()); - enterRule(_localctx, 166, RULE_singleType); + enterRule(_localctx, 168, RULE_singleType); try { enterOuterAlt(_localctx, 1); { - setState(902); + setState(906); ((SingleTypeContext)_localctx).item = itemType(); - setState(904); + setState(908); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,96,_ctx) ) { case 1: { - setState(903); + setState(907); ((SingleTypeContext)_localctx).s106 = match(ArgumentPlaceholder); ((SingleTypeContext)_localctx).question.add(((SingleTypeContext)_localctx).s106); } @@ -6389,30 +6392,30 @@ public T accept(ParseTreeVisitor visitor) { public final PairConstructorContext pairConstructor() throws RecognitionException { PairConstructorContext _localctx = new PairConstructorContext(_ctx, getState()); - enterRule(_localctx, 168, RULE_pairConstructor); + enterRule(_localctx, 170, RULE_pairConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(908); + setState(912); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,97,_ctx) ) { case 1: { - setState(906); + setState(910); ((PairConstructorContext)_localctx).lhs = exprSingle(); } break; case 2: { - setState(907); + setState(911); ((PairConstructorContext)_localctx).name = match(NCName); } break; } - setState(910); + setState(914); _la = _input.LA(1); - if ( !(_la==T__8 || _la==ArgumentPlaceholder) ) { + if ( !(_la==T__9 || _la==ArgumentPlaceholder) ) { _errHandler.recoverInline(this); } else { @@ -6420,7 +6423,7 @@ public final PairConstructorContext pairConstructor() throws RecognitionExceptio _errHandler.reportMatch(this); consume(); } - setState(911); + setState(915); ((PairConstructorContext)_localctx).rhs = exprSingle(); } } @@ -6452,25 +6455,25 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayConstructorContext arrayConstructor() throws RecognitionException { ArrayConstructorContext _localctx = new ArrayConstructorContext(_ctx, getState()); - enterRule(_localctx, 170, RULE_arrayConstructor); + enterRule(_localctx, 172, RULE_arrayConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(913); - match(T__52); - setState(915); + setState(917); + match(T__53); + setState(919); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__24) | (1L << T__25) | (1L << T__27) | (1L << T__30) | (1L << T__45) | (1L << T__46) | (1L << T__50) | (1L << T__52) | (1L << T__55) | (1L << T__57) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere) | (1L << Kgroup))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (Kunordered - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__6) | (1L << T__7) | (1L << T__25) | (1L << T__26) | (1L << T__28) | (1L << T__31) | (1L << T__46) | (1L << T__47) | (1L << T__51) | (1L << T__53) | (1L << T__56) | (1L << T__58) | (1L << Kfor) | (1L << Klet) | (1L << Kwhere))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kgroup - 64)) | (1L << (Kby - 64)) | (1L << (Korder - 64)) | (1L << (Kreturn - 64)) | (1L << (Kif - 64)) | (1L << (Kin - 64)) | (1L << (Kas - 64)) | (1L << (Kat - 64)) | (1L << (Kallowing - 64)) | (1L << (Kempty - 64)) | (1L << (Kcount - 64)) | (1L << (Kstable - 64)) | (1L << (Kascending - 64)) | (1L << (Kdescending - 64)) | (1L << (Ksome - 64)) | (1L << (Kevery - 64)) | (1L << (Ksatisfies - 64)) | (1L << (Kcollation - 64)) | (1L << (Kgreatest - 64)) | (1L << (Kleast - 64)) | (1L << (Kswitch - 64)) | (1L << (Kcase - 64)) | (1L << (Ktry - 64)) | (1L << (Kcatch - 64)) | (1L << (Kdefault - 64)) | (1L << (Kthen - 64)) | (1L << (Kelse - 64)) | (1L << (Ktypeswitch - 64)) | (1L << (Kor - 64)) | (1L << (Kand - 64)) | (1L << (Knot - 64)) | (1L << (Kto - 64)) | (1L << (Kinstance - 64)) | (1L << (Kof - 64)) | (1L << (Kstatically - 64)) | (1L << (Kis - 64)) | (1L << (Ktreat - 64)) | (1L << (Kcast - 64)) | (1L << (Kcastable - 64)) | (1L << (Kversion - 64)) | (1L << (Kjsoniq - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { { - setState(914); + setState(918); expr(); } } - setState(917); - match(T__53); + setState(921); + match(T__54); } } catch (RecognitionException re) { @@ -6501,11 +6504,11 @@ public T accept(ParseTreeVisitor visitor) { public final UriLiteralContext uriLiteral() throws RecognitionException { UriLiteralContext _localctx = new UriLiteralContext(_ctx, getState()); - enterRule(_localctx, 172, RULE_uriLiteral); + enterRule(_localctx, 174, RULE_uriLiteral); try { enterOuterAlt(_localctx, 1); { - setState(919); + setState(923); stringLiteral(); } } @@ -6535,11 +6538,11 @@ public T accept(ParseTreeVisitor visitor) { public final StringLiteralContext stringLiteral() throws RecognitionException { StringLiteralContext _localctx = new StringLiteralContext(_ctx, getState()); - enterRule(_localctx, 174, RULE_stringLiteral); + enterRule(_localctx, 176, RULE_stringLiteral); try { enterOuterAlt(_localctx, 1); { - setState(921); + setState(925); match(STRING); } } @@ -6600,7 +6603,6 @@ public static class KeyWordsContext extends ParserRuleContext { public TerminalNode Korder() { return getToken(JsoniqParser.Korder, 0); } public TerminalNode Kcount() { return getToken(JsoniqParser.Kcount, 0); } public TerminalNode Kreturn() { return getToken(JsoniqParser.Kreturn, 0); } - public TerminalNode Kunordered() { return getToken(JsoniqParser.Kunordered, 0); } public KeyWordsContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -6614,14 +6616,14 @@ public T accept(ParseTreeVisitor visitor) { public final KeyWordsContext keyWords() throws RecognitionException { KeyWordsContext _localctx = new KeyWordsContext(_ctx, getState()); - enterRule(_localctx, 176, RULE_keyWords); + enterRule(_localctx, 178, RULE_keyWords); int _la; try { enterOuterAlt(_localctx, 1); { - setState(923); + setState(927); _la = _input.LA(1); - if ( !(((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (Kfor - 60)) | (1L << (Klet - 60)) | (1L << (Kwhere - 60)) | (1L << (Kgroup - 60)) | (1L << (Kby - 60)) | (1L << (Korder - 60)) | (1L << (Kreturn - 60)) | (1L << (Kif - 60)) | (1L << (Kin - 60)) | (1L << (Kas - 60)) | (1L << (Kat - 60)) | (1L << (Kallowing - 60)) | (1L << (Kempty - 60)) | (1L << (Kcount - 60)) | (1L << (Kstable - 60)) | (1L << (Kascending - 60)) | (1L << (Kdescending - 60)) | (1L << (Ksome - 60)) | (1L << (Kevery - 60)) | (1L << (Ksatisfies - 60)) | (1L << (Kcollation - 60)) | (1L << (Kgreatest - 60)) | (1L << (Kleast - 60)) | (1L << (Kswitch - 60)) | (1L << (Kcase - 60)) | (1L << (Ktry - 60)) | (1L << (Kcatch - 60)) | (1L << (Kdefault - 60)) | (1L << (Kthen - 60)) | (1L << (Kelse - 60)) | (1L << (Ktypeswitch - 60)) | (1L << (Kor - 60)) | (1L << (Kand - 60)) | (1L << (Knot - 60)) | (1L << (Kto - 60)) | (1L << (Kinstance - 60)) | (1L << (Kof - 60)) | (1L << (Kstatically - 60)) | (1L << (Kis - 60)) | (1L << (Ktreat - 60)) | (1L << (Kcast - 60)) | (1L << (Kcastable - 60)) | (1L << (Kversion - 60)) | (1L << (Kjsoniq - 60)) | (1L << (Kunordered - 60)) | (1L << (NullLiteral - 60)))) != 0)) ) { + if ( !(((((_la - 61)) & ~0x3f) == 0 && ((1L << (_la - 61)) & ((1L << (Kfor - 61)) | (1L << (Klet - 61)) | (1L << (Kwhere - 61)) | (1L << (Kgroup - 61)) | (1L << (Kby - 61)) | (1L << (Korder - 61)) | (1L << (Kreturn - 61)) | (1L << (Kif - 61)) | (1L << (Kin - 61)) | (1L << (Kas - 61)) | (1L << (Kat - 61)) | (1L << (Kallowing - 61)) | (1L << (Kempty - 61)) | (1L << (Kcount - 61)) | (1L << (Kstable - 61)) | (1L << (Kascending - 61)) | (1L << (Kdescending - 61)) | (1L << (Ksome - 61)) | (1L << (Kevery - 61)) | (1L << (Ksatisfies - 61)) | (1L << (Kcollation - 61)) | (1L << (Kgreatest - 61)) | (1L << (Kleast - 61)) | (1L << (Kswitch - 61)) | (1L << (Kcase - 61)) | (1L << (Ktry - 61)) | (1L << (Kcatch - 61)) | (1L << (Kdefault - 61)) | (1L << (Kthen - 61)) | (1L << (Kelse - 61)) | (1L << (Ktypeswitch - 61)) | (1L << (Kor - 61)) | (1L << (Kand - 61)) | (1L << (Knot - 61)) | (1L << (Kto - 61)) | (1L << (Kinstance - 61)) | (1L << (Kof - 61)) | (1L << (Kstatically - 61)) | (1L << (Kis - 61)) | (1L << (Ktreat - 61)) | (1L << (Kcast - 61)) | (1L << (Kcastable - 61)) | (1L << (Kversion - 61)) | (1L << (Kjsoniq - 61)) | (1L << (NullLiteral - 61)))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -6643,7 +6645,7 @@ public final KeyWordsContext keyWords() throws RecognitionException { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3w\u03a0\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3w\u03a4\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -6653,341 +6655,342 @@ public final KeyWordsContext keyWords() throws RecognitionException { "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+ "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ - "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\5"+ - "\3\u00bd\n\3\3\3\3\3\5\3\u00c1\n\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5"+ - "\3\5\3\5\3\6\3\6\3\6\5\6\u00d1\n\6\3\6\3\6\7\6\u00d5\n\6\f\6\16\6\u00d8"+ - "\13\6\3\6\3\6\3\6\7\6\u00dd\n\6\f\6\16\6\u00e0\13\6\3\7\3\7\3\7\3\7\5"+ - "\7\u00e6\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\t\u00f1\n\t\3\n\3\n"+ - "\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3"+ - "\r\3\r\5\r\u0107\n\r\3\r\3\r\3\r\3\r\7\r\u010d\n\r\f\r\16\r\u0110\13\r"+ - "\3\16\3\16\5\16\u0114\n\16\3\16\5\16\u0117\n\16\3\16\3\16\5\16\u011b\n"+ - "\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\5\20\u0124\n\20\3\20\3\20\3\20"+ - "\3\20\3\20\7\20\u012b\n\20\f\20\16\20\u012e\13\20\5\20\u0130\n\20\3\21"+ - "\3\21\3\21\3\21\3\21\5\21\u0137\n\21\3\21\3\21\3\21\3\21\3\21\5\21\u013e"+ - "\n\21\5\21\u0140\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u0147\n\22\3\22\3"+ - "\22\3\22\5\22\u014c\n\22\3\22\3\22\5\22\u0150\n\22\3\22\3\22\5\22\u0154"+ - "\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\7\24\u015f\n\24\f\24"+ - "\16\24\u0162\13\24\3\25\3\25\3\25\3\25\5\25\u0168\n\25\3\26\3\26\3\26"+ - "\7\26\u016d\n\26\f\26\16\26\u0170\13\26\3\27\3\27\3\27\3\27\3\27\3\27"+ - "\3\27\5\27\u0179\n\27\3\30\3\30\5\30\u017d\n\30\3\30\3\30\3\30\3\30\3"+ - "\30\3\30\7\30\u0185\n\30\f\30\16\30\u0188\13\30\3\30\3\30\3\30\3\31\3"+ - "\31\3\31\3\31\7\31\u0191\n\31\f\31\16\31\u0194\13\31\3\32\3\32\3\32\5"+ - "\32\u0199\n\32\3\32\3\32\5\32\u019d\n\32\3\32\3\32\5\32\u01a1\n\32\3\32"+ - "\3\32\3\32\3\33\3\33\3\33\3\33\7\33\u01aa\n\33\f\33\16\33\u01ad\13\33"+ - "\3\34\3\34\3\34\5\34\u01b2\n\34\3\34\3\34\3\34\3\35\3\35\3\35\3\36\3\36"+ - "\3\36\3\36\3\36\7\36\u01bf\n\36\f\36\16\36\u01c2\13\36\3\37\3\37\3\37"+ - "\5\37\u01c7\n\37\3\37\3\37\5\37\u01cb\n\37\3\37\3\37\5\37\u01cf\n\37\3"+ - " \3 \3 \3 \3 \5 \u01d6\n \3 \3 \3 \7 \u01db\n \f \16 \u01de\13 \3!\3!"+ - "\3!\5!\u01e3\n!\3!\3!\3!\5!\u01e8\n!\5!\u01ea\n!\3!\3!\5!\u01ee\n!\3\""+ - "\3\"\3\"\3#\3#\5#\u01f5\n#\3#\3#\3#\7#\u01fa\n#\f#\16#\u01fd\13#\3#\3"+ - "#\3#\3$\3$\3$\5$\u0205\n$\3$\3$\3$\3%\3%\3%\3%\3%\6%\u020f\n%\r%\16%\u0210"+ - "\3%\3%\3%\3%\3&\3&\6&\u0219\n&\r&\16&\u021a\3&\3&\3&\3\'\3\'\3\'\3\'\3"+ - "\'\6\'\u0225\n\'\r\'\16\'\u0226\3\'\3\'\5\'\u022b\n\'\3\'\3\'\3\'\3(\3"+ - "(\3(\3(\5(\u0234\n(\3(\3(\3(\7(\u0239\n(\f(\16(\u023c\13(\3(\3(\3(\3)"+ - "\3)\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\6*\u024f\n*\r*\16*\u0250\3+\3"+ - "+\3+\5+\u0256\n+\3+\3+\3+\5+\u025b\n+\7+\u025d\n+\f+\16+\u0260\13+\3+"+ - "\3+\3+\3+\3,\3,\3,\7,\u0269\n,\f,\16,\u026c\13,\3-\3-\3-\7-\u0271\n-\f"+ - "-\16-\u0274\13-\3.\5.\u0277\n.\3.\3.\3/\3/\3/\5/\u027e\n/\3\60\3\60\3"+ - "\60\7\60\u0283\n\60\f\60\16\60\u0286\13\60\3\61\3\61\3\61\5\61\u028b\n"+ - "\61\3\62\3\62\3\62\7\62\u0290\n\62\f\62\16\62\u0293\13\62\3\63\3\63\3"+ - "\63\7\63\u0298\n\63\f\63\16\63\u029b\13\63\3\64\3\64\3\64\3\64\5\64\u02a1"+ - "\n\64\3\65\3\65\3\65\3\65\5\65\u02a7\n\65\3\66\3\66\3\66\3\66\5\66\u02ad"+ - "\n\66\3\67\3\67\3\67\3\67\5\67\u02b3\n\67\38\38\38\38\58\u02b9\n8\39\3"+ - "9\39\39\39\79\u02c0\n9\f9\169\u02c3\139\3:\7:\u02c6\n:\f:\16:\u02c9\13"+ - ":\3:\3:\3;\3;\5;\u02cf\n;\3<\3<\3<\3<\3<\3<\3<\3=\3=\3=\7=\u02db\n=\f"+ - "=\16=\u02de\13=\3>\3>\3>\3>\3>\3>\7>\u02e6\n>\f>\16>\u02e9\13>\3?\3?\3"+ - "?\3?\3?\3?\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\5B\u02ff\nB\3C\3"+ - "C\3C\3C\3C\3C\3C\3C\3C\3C\3C\3C\5C\u030d\nC\3D\3D\3D\3E\3E\5E\u0314\n"+ - "E\3E\3E\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3J\3J\3J\5J\u032a"+ - "\nJ\7J\u032c\nJ\fJ\16J\u032f\13J\3J\3J\3K\3K\5K\u0335\nK\3L\3L\5L\u0339"+ - "\nL\3M\3M\3M\3M\3N\3N\3N\5N\u0342\nN\3N\3N\3N\5N\u0347\nN\3N\3N\5N\u034b"+ - "\nN\3N\3N\3O\3O\3O\3O\3O\3O\5O\u0355\nO\5O\u0357\nO\3P\3P\3P\3P\7P\u035d"+ - "\nP\fP\16P\u0360\13P\5P\u0362\nP\3P\3P\3P\3P\3P\5P\u0369\nP\3Q\3Q\3Q\5"+ - "Q\u036e\nQ\3R\3R\5R\u0372\nR\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\7T\u037e\n"+ - "T\fT\16T\u0381\13T\5T\u0383\nT\3T\3T\3T\3T\3U\3U\5U\u038b\nU\3V\3V\5V"+ - "\u038f\nV\3V\3V\3V\3W\3W\5W\u0396\nW\3W\3W\3X\3X\3Y\3Y\3Z\3Z\3Z\2\2[\2"+ - "\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL"+ - "NPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e"+ - "\u0090\u0092\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6"+ - "\u00a8\u00aa\u00ac\u00ae\u00b0\u00b2\2\n\4\2\t\tjj\3\2ST\3\2\f\25\4\2"+ - "\6\6$.\3\2\60\61\4\2##\62\64\4\2\13\13ll\4\2>jmm\2\u03cb\2\u00b4\3\2\2"+ - "\2\4\u00bc\3\2\2\2\6\u00c2\3\2\2\2\b\u00c5\3\2\2\2\n\u00d6\3\2\2\2\f\u00e5"+ - "\3\2\2\2\16\u00e7\3\2\2\2\20\u00f0\3\2\2\2\22\u00f2\3\2\2\2\24\u00f7\3"+ - "\2\2\2\26\u00fb\3\2\2\2\30\u0101\3\2\2\2\32\u0116\3\2\2\2\34\u011c\3\2"+ - "\2\2\36\u011e\3\2\2\2 \u0131\3\2\2\2\"\u0141\3\2\2\2$\u0155\3\2\2\2&\u015b"+ - "\3\2\2\2(\u0163\3\2\2\2*\u0169\3\2\2\2,\u0178\3\2\2\2.\u017c\3\2\2\2\60"+ - "\u018c\3\2\2\2\62\u0195\3\2\2\2\64\u01a5\3\2\2\2\66\u01ae\3\2\2\28\u01b6"+ - "\3\2\2\2:\u01b9\3\2\2\2<\u01c3\3\2\2\2>\u01d5\3\2\2\2@\u01df\3\2\2\2B"+ - "\u01ef\3\2\2\2D\u01f4\3\2\2\2F\u0201\3\2\2\2H\u0209\3\2\2\2J\u0218\3\2"+ - "\2\2L\u021f\3\2\2\2N\u022f\3\2\2\2P\u0240\3\2\2\2R\u0249\3\2\2\2T\u0252"+ - "\3\2\2\2V\u0265\3\2\2\2X\u026d\3\2\2\2Z\u0276\3\2\2\2\\\u027a\3\2\2\2"+ - "^\u027f\3\2\2\2`\u0287\3\2\2\2b\u028c\3\2\2\2d\u0294\3\2\2\2f\u029c\3"+ - "\2\2\2h\u02a2\3\2\2\2j\u02a8\3\2\2\2l\u02ae\3\2\2\2n\u02b4\3\2\2\2p\u02ba"+ - "\3\2\2\2r\u02c7\3\2\2\2t\u02ce\3\2\2\2v\u02d0\3\2\2\2x\u02d7\3\2\2\2z"+ - "\u02df\3\2\2\2|\u02ea\3\2\2\2~\u02f0\3\2\2\2\u0080\u02f3\3\2\2\2\u0082"+ - "\u02f7\3\2\2\2\u0084\u030c\3\2\2\2\u0086\u030e\3\2\2\2\u0088\u0311\3\2"+ - "\2\2\u008a\u0317\3\2\2\2\u008c\u0319\3\2\2\2\u008e\u031e\3\2\2\2\u0090"+ - "\u0323\3\2\2\2\u0092\u0326\3\2\2\2\u0094\u0334\3\2\2\2\u0096\u0338\3\2"+ - "\2\2\u0098\u033a\3\2\2\2\u009a\u033e\3\2\2\2\u009c\u0356\3\2\2\2\u009e"+ - "\u0368\3\2\2\2\u00a0\u036d\3\2\2\2\u00a2\u0371\3\2\2\2\u00a4\u0373\3\2"+ - "\2\2\u00a6\u0378\3\2\2\2\u00a8\u0388\3\2\2\2\u00aa\u038e\3\2\2\2\u00ac"+ - "\u0393\3\2\2\2\u00ae\u0399\3\2\2\2\u00b0\u039b\3\2\2\2\u00b2\u039d\3\2"+ - "\2\2\u00b4\u00b5\5\4\3\2\u00b5\u00b6\7\2\2\3\u00b6\3\3\2\2\2\u00b7\u00b8"+ - "\7i\2\2\u00b8\u00b9\7h\2\2\u00b9\u00ba\5\u00b0Y\2\u00ba\u00bb\7\3\2\2"+ - "\u00bb\u00bd\3\2\2\2\u00bc\u00b7\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00c0"+ - "\3\2\2\2\u00be\u00c1\5\b\5\2\u00bf\u00c1\5\6\4\2\u00c0\u00be\3\2\2\2\u00c0"+ - "\u00bf\3\2\2\2\u00c1\5\3\2\2\2\u00c2\u00c3\5\n\6\2\u00c3\u00c4\5*\26\2"+ - "\u00c4\7\3\2\2\2\u00c5\u00c6\7\4\2\2\u00c6\u00c7\7\5\2\2\u00c7\u00c8\7"+ - "u\2\2\u00c8\u00c9\7\6\2\2\u00c9\u00ca\5\u00aeX\2\u00ca\u00cb\7\3\2\2\u00cb"+ - "\u00cc\5\n\6\2\u00cc\t\3\2\2\2\u00cd\u00d1\5\f\7\2\u00ce\u00d1\5\16\b"+ - "\2\u00cf\u00d1\5\36\20\2\u00d0\u00cd\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d0"+ - "\u00cf\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\7\3\2\2\u00d3\u00d5\3\2"+ - "\2\2\u00d4\u00d0\3\2\2\2\u00d5\u00d8\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6"+ - "\u00d7\3\2\2\2\u00d7\u00de\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d9\u00da\5\20"+ - "\t\2\u00da\u00db\7\3\2\2\u00db\u00dd\3\2\2\2\u00dc\u00d9\3\2\2\2\u00dd"+ - "\u00e0\3\2\2\2\u00de\u00dc\3\2\2\2\u00de\u00df\3\2\2\2\u00df\13\3\2\2"+ - "\2\u00e0\u00de\3\2\2\2\u00e1\u00e6\5\22\n\2\u00e2\u00e6\5\24\13\2\u00e3"+ - "\u00e6\5\26\f\2\u00e4\u00e6\5\30\r\2\u00e5\u00e1\3\2\2\2\u00e5\u00e2\3"+ - "\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e4\3\2\2\2\u00e6\r\3\2\2\2\u00e7\u00e8"+ - "\7\7\2\2\u00e8\u00e9\7\5\2\2\u00e9\u00ea\7u\2\2\u00ea\u00eb\7\6\2\2\u00eb"+ - "\u00ec\5\u00aeX\2\u00ec\17\3\2\2\2\u00ed\u00f1\5\"\22\2\u00ee\u00f1\5"+ - " \21\2\u00ef\u00f1\5$\23\2\u00f0\u00ed\3\2\2\2\u00f0\u00ee\3\2\2\2\u00f0"+ - "\u00ef\3\2\2\2\u00f1\21\3\2\2\2\u00f2\u00f3\7\7\2\2\u00f3\u00f4\7Y\2\2"+ - "\u00f4\u00f5\7R\2\2\u00f5\u00f6\5\u00aeX\2\u00f6\23\3\2\2\2\u00f7\u00f8"+ - "\7\7\2\2\u00f8\u00f9\7\b\2\2\u00f9\u00fa\t\2\2\2\u00fa\25\3\2\2\2\u00fb"+ - "\u00fc\7\7\2\2\u00fc\u00fd\7Y\2\2\u00fd\u00fe\7C\2\2\u00fe\u00ff\7J\2"+ - "\2\u00ff\u0100\t\3\2\2\u0100\27\3\2\2\2\u0101\u0106\7\7\2\2\u0102\u0103"+ - "\7\n\2\2\u0103\u0107\5\32\16\2\u0104\u0105\7Y\2\2\u0105\u0107\7\n\2\2"+ - "\u0106\u0102\3\2\2\2\u0106\u0104\3\2\2\2\u0107\u010e\3\2\2\2\u0108\u0109"+ - "\5\34\17\2\u0109\u010a\7\6\2\2\u010a\u010b\5\u00b0Y\2\u010b\u010d\3\2"+ - "\2\2\u010c\u0108\3\2\2\2\u010d\u0110\3\2\2\2\u010e\u010c\3\2\2\2\u010e"+ - "\u010f\3\2\2\2\u010f\31\3\2\2\2\u0110\u010e\3\2\2\2\u0111\u0114\7u\2\2"+ - "\u0112\u0114\5\u00b2Z\2\u0113\u0111\3\2\2\2\u0113\u0112\3\2\2\2\u0114"+ - "\u0115\3\2\2\2\u0115\u0117\7\13\2\2\u0116\u0113\3\2\2\2\u0116\u0117\3"+ - "\2\2\2\u0117\u011a\3\2\2\2\u0118\u011b\7u\2\2\u0119\u011b\5\u00b2Z\2\u011a"+ - "\u0118\3\2\2\2\u011a\u0119\3\2\2\2\u011b\33\3\2\2\2\u011c\u011d\t\4\2"+ - "\2\u011d\35\3\2\2\2\u011e\u011f\7\26\2\2\u011f\u0123\7\4\2\2\u0120\u0121"+ - "\7\5\2\2\u0121\u0122\7u\2\2\u0122\u0124\7\6\2\2\u0123\u0120\3\2\2\2\u0123"+ - "\u0124\3\2\2\2\u0124\u0125\3\2\2\2\u0125\u012f\5\u00aeX\2\u0126\u0127"+ - "\7H\2\2\u0127\u012c\5\u00aeX\2\u0128\u0129\7\27\2\2\u0129\u012b\5\u00ae"+ - "X\2\u012a\u0128\3\2\2\2\u012b\u012e\3\2\2\2\u012c\u012a\3\2\2\2\u012c"+ - "\u012d\3\2\2\2\u012d\u0130\3\2\2\2\u012e\u012c\3\2\2\2\u012f\u0126\3\2"+ - "\2\2\u012f\u0130\3\2\2\2\u0130\37\3\2\2\2\u0131\u0132\7\7\2\2\u0132\u0133"+ - "\7\30\2\2\u0133\u0136\5\u0086D\2\u0134\u0135\7G\2\2\u0135\u0137\5\u009c"+ - "O\2\u0136\u0134\3\2\2\2\u0136\u0137\3\2\2\2\u0137\u013f\3\2\2\2\u0138"+ - "\u0139\7\31\2\2\u0139\u0140\5,\27\2\u013a\u013d\7\32\2\2\u013b\u013c\7"+ - "\31\2\2\u013c\u013e\5,\27\2\u013d\u013b\3\2\2\2\u013d\u013e\3\2\2\2\u013e"+ - "\u0140\3\2\2\2\u013f\u0138\3\2\2\2\u013f\u013a\3\2\2\2\u0140!\3\2\2\2"+ - "\u0141\u0142\7\7\2\2\u0142\u0143\7\33\2\2\u0143\u0144\5\32\16\2\u0144"+ - "\u0146\7\34\2\2\u0145\u0147\5&\24\2\u0146\u0145\3\2\2\2\u0146\u0147\3"+ - "\2\2\2\u0147\u0148\3\2\2\2\u0148\u014b\7\35\2\2\u0149\u014a\7G\2\2\u014a"+ - "\u014c\5\u009cO\2\u014b\u0149\3\2\2\2\u014b\u014c\3\2\2\2\u014c\u0153"+ - "\3\2\2\2\u014d\u014f\7\36\2\2\u014e\u0150\5*\26\2\u014f\u014e\3\2\2\2"+ - "\u014f\u0150\3\2\2\2\u0150\u0151\3\2\2\2\u0151\u0154\7\37\2\2\u0152\u0154"+ - "\7\32\2\2\u0153\u014d\3\2\2\2\u0153\u0152\3\2\2\2\u0154#\3\2\2\2\u0155"+ - "\u0156\7\7\2\2\u0156\u0157\7 \2\2\u0157\u0158\5\32\16\2\u0158\u0159\7"+ - "G\2\2\u0159\u015a\5,\27\2\u015a%\3\2\2\2\u015b\u0160\5(\25\2\u015c\u015d"+ - "\7\27\2\2\u015d\u015f\5(\25\2\u015e\u015c\3\2\2\2\u015f\u0162\3\2\2\2"+ - "\u0160\u015e\3\2\2\2\u0160\u0161\3\2\2\2\u0161\'\3\2\2\2\u0162\u0160\3"+ - "\2\2\2\u0163\u0164\7!\2\2\u0164\u0167\5\32\16\2\u0165\u0166\7G\2\2\u0166"+ - "\u0168\5\u009cO\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168)\3\2\2"+ - "\2\u0169\u016e\5,\27\2\u016a\u016b\7\27\2\2\u016b\u016d\5,\27\2\u016c"+ - "\u016a\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2"+ - "\2\2\u016f+\3\2\2\2\u0170\u016e\3\2\2\2\u0171\u0179\5.\30\2\u0172\u0179"+ - "\5D#\2\u0173\u0179\5H%\2\u0174\u0179\5L\'\2\u0175\u0179\5P)\2\u0176\u0179"+ - "\5R*\2\u0177\u0179\5V,\2\u0178\u0171\3\2\2\2\u0178\u0172\3\2\2\2\u0178"+ - "\u0173\3\2\2\2\u0178\u0174\3\2\2\2\u0178\u0175\3\2\2\2\u0178\u0176\3\2"+ - "\2\2\u0178\u0177\3\2\2\2\u0179-\3\2\2\2\u017a\u017d\5\60\31\2\u017b\u017d"+ - "\5\64\33\2\u017c\u017a\3\2\2\2\u017c\u017b\3\2\2\2\u017d\u0186\3\2\2\2"+ - "\u017e\u0185\5\60\31\2\u017f\u0185\58\35\2\u0180\u0185\5\64\33\2\u0181"+ - "\u0185\5:\36\2\u0182\u0185\5> \2\u0183\u0185\5B\"\2\u0184\u017e\3\2\2"+ - "\2\u0184\u017f\3\2\2\2\u0184\u0180\3\2\2\2\u0184\u0181\3\2\2\2\u0184\u0182"+ - "\3\2\2\2\u0184\u0183\3\2\2\2\u0185\u0188\3\2\2\2\u0186\u0184\3\2\2\2\u0186"+ - "\u0187\3\2\2\2\u0187\u0189\3\2\2\2\u0188\u0186\3\2\2\2\u0189\u018a\7D"+ - "\2\2\u018a\u018b\5,\27\2\u018b/\3\2\2\2\u018c\u018d\7>\2\2\u018d\u0192"+ - "\5\62\32\2\u018e\u018f\7\27\2\2\u018f\u0191\5\62\32\2\u0190\u018e\3\2"+ - "\2\2\u0191\u0194\3\2\2\2\u0192\u0190\3\2\2\2\u0192\u0193\3\2\2\2\u0193"+ - "\61\3\2\2\2\u0194\u0192\3\2\2\2\u0195\u0198\5\u0086D\2\u0196\u0197\7G"+ - "\2\2\u0197\u0199\5\u009cO\2\u0198\u0196\3\2\2\2\u0198\u0199\3\2\2\2\u0199"+ - "\u019c\3\2\2\2\u019a\u019b\7I\2\2\u019b\u019d\7J\2\2\u019c\u019a\3\2\2"+ - "\2\u019c\u019d\3\2\2\2\u019d\u01a0\3\2\2\2\u019e\u019f\7H\2\2\u019f\u01a1"+ - "\5\u0086D\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2\2\2\u01a1\u01a2\3\2\2"+ - "\2\u01a2\u01a3\7F\2\2\u01a3\u01a4\5,\27\2\u01a4\63\3\2\2\2\u01a5\u01a6"+ - "\7?\2\2\u01a6\u01ab\5\66\34\2\u01a7\u01a8\7\27\2\2\u01a8\u01aa\5\66\34"+ - "\2\u01a9\u01a7\3\2\2\2\u01aa\u01ad\3\2\2\2\u01ab\u01a9\3\2\2\2\u01ab\u01ac"+ - "\3\2\2\2\u01ac\65\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ae\u01b1\5\u0086D\2\u01af"+ - "\u01b0\7G\2\2\u01b0\u01b2\5\u009cO\2\u01b1\u01af\3\2\2\2\u01b1\u01b2\3"+ - "\2\2\2\u01b2\u01b3\3\2\2\2\u01b3\u01b4\7\31\2\2\u01b4\u01b5\5,\27\2\u01b5"+ - "\67\3\2\2\2\u01b6\u01b7\7@\2\2\u01b7\u01b8\5,\27\2\u01b89\3\2\2\2\u01b9"+ - "\u01ba\7A\2\2\u01ba\u01bb\7B\2\2\u01bb\u01c0\5<\37\2\u01bc\u01bd\7\27"+ - "\2\2\u01bd\u01bf\5<\37\2\u01be\u01bc\3\2\2\2\u01bf\u01c2\3\2\2\2\u01c0"+ - "\u01be\3\2\2\2\u01c0\u01c1\3\2\2\2\u01c1;\3\2\2\2\u01c2\u01c0\3\2\2\2"+ - "\u01c3\u01ca\5\u0086D\2\u01c4\u01c5\7G\2\2\u01c5\u01c7\5\u009cO\2\u01c6"+ - "\u01c4\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01c9\7\31"+ - "\2\2\u01c9\u01cb\5,\27\2\u01ca\u01c6\3\2\2\2\u01ca\u01cb\3\2\2\2\u01cb"+ - "\u01ce\3\2\2\2\u01cc\u01cd\7R\2\2\u01cd\u01cf\5\u00aeX\2\u01ce\u01cc\3"+ - "\2\2\2\u01ce\u01cf\3\2\2\2\u01cf=\3\2\2\2\u01d0\u01d1\7C\2\2\u01d1\u01d6"+ - "\7B\2\2\u01d2\u01d3\7L\2\2\u01d3\u01d4\7C\2\2\u01d4\u01d6\7B\2\2\u01d5"+ - "\u01d0\3\2\2\2\u01d5\u01d2\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u01dc\5@"+ - "!\2\u01d8\u01d9\7\27\2\2\u01d9\u01db\5@!\2\u01da\u01d8\3\2\2\2\u01db\u01de"+ - "\3\2\2\2\u01dc\u01da\3\2\2\2\u01dc\u01dd\3\2\2\2\u01dd?\3\2\2\2\u01de"+ - "\u01dc\3\2\2\2\u01df\u01e2\5,\27\2\u01e0\u01e3\7M\2\2\u01e1\u01e3\7N\2"+ - "\2\u01e2\u01e0\3\2\2\2\u01e2\u01e1\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3\u01e9"+ - "\3\2\2\2\u01e4\u01e7\7J\2\2\u01e5\u01e8\7S\2\2\u01e6\u01e8\7T\2\2\u01e7"+ - "\u01e5\3\2\2\2\u01e7\u01e6\3\2\2\2\u01e8\u01ea\3\2\2\2\u01e9\u01e4\3\2"+ - "\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\7R\2\2\u01ec"+ - "\u01ee\5\u00aeX\2\u01ed\u01eb\3\2\2\2\u01ed\u01ee\3\2\2\2\u01eeA\3\2\2"+ - "\2\u01ef\u01f0\7K\2\2\u01f0\u01f1\5\u0086D\2\u01f1C\3\2\2\2\u01f2\u01f5"+ - "\7O\2\2\u01f3\u01f5\7P\2\2\u01f4\u01f2\3\2\2\2\u01f4\u01f3\3\2\2\2\u01f5"+ - "\u01f6\3\2\2\2\u01f6\u01fb\5F$\2\u01f7\u01f8\7\27\2\2\u01f8\u01fa\5F$"+ - "\2\u01f9\u01f7\3\2\2\2\u01fa\u01fd\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fb\u01fc"+ - "\3\2\2\2\u01fc\u01fe\3\2\2\2\u01fd\u01fb\3\2\2\2\u01fe\u01ff\7Q\2\2\u01ff"+ - "\u0200\5,\27\2\u0200E\3\2\2\2\u0201\u0204\5\u0086D\2\u0202\u0203\7G\2"+ - "\2\u0203\u0205\5\u009cO\2\u0204\u0202\3\2\2\2\u0204\u0205\3\2\2\2\u0205"+ - "\u0206\3\2\2\2\u0206\u0207\7F\2\2\u0207\u0208\5,\27\2\u0208G\3\2\2\2\u0209"+ - "\u020a\7U\2\2\u020a\u020b\7\34\2\2\u020b\u020c\5*\26\2\u020c\u020e\7\35"+ - "\2\2\u020d\u020f\5J&\2\u020e\u020d\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u020e"+ - "\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u0212\3\2\2\2\u0212\u0213\7Y\2\2\u0213"+ - "\u0214\7D\2\2\u0214\u0215\5,\27\2\u0215I\3\2\2\2\u0216\u0217\7V\2\2\u0217"+ - "\u0219\5,\27\2\u0218\u0216\3\2\2\2\u0219\u021a\3\2\2\2\u021a\u0218\3\2"+ - "\2\2\u021a\u021b\3\2\2\2\u021b\u021c\3\2\2\2\u021c\u021d\7D\2\2\u021d"+ - "\u021e\5,\27\2\u021eK\3\2\2\2\u021f\u0220\7\\\2\2\u0220\u0221\7\34\2\2"+ - "\u0221\u0222\5*\26\2\u0222\u0224\7\35\2\2\u0223\u0225\5N(\2\u0224\u0223"+ - "\3\2\2\2\u0225\u0226\3\2\2\2\u0226\u0224\3\2\2\2\u0226\u0227\3\2\2\2\u0227"+ - "\u0228\3\2\2\2\u0228\u022a\7Y\2\2\u0229\u022b\5\u0086D\2\u022a\u0229\3"+ - "\2\2\2\u022a\u022b\3\2\2\2\u022b\u022c\3\2\2\2\u022c\u022d\7D\2\2\u022d"+ - "\u022e\5,\27\2\u022eM\3\2\2\2\u022f\u0233\7V\2\2\u0230\u0231\5\u0086D"+ - "\2\u0231\u0232\7G\2\2\u0232\u0234\3\2\2\2\u0233\u0230\3\2\2\2\u0233\u0234"+ - "\3\2\2\2\u0234\u0235\3\2\2\2\u0235\u023a\5\u009cO\2\u0236\u0237\7\"\2"+ - "\2\u0237\u0239\5\u009cO\2\u0238\u0236\3\2\2\2\u0239\u023c\3\2\2\2\u023a"+ - "\u0238\3\2\2\2\u023a\u023b\3\2\2\2\u023b\u023d\3\2\2\2\u023c\u023a\3\2"+ - "\2\2\u023d\u023e\7D\2\2\u023e\u023f\5,\27\2\u023fO\3\2\2\2\u0240\u0241"+ - "\7E\2\2\u0241\u0242\7\34\2\2\u0242\u0243\5*\26\2\u0243\u0244\7\35\2\2"+ - "\u0244\u0245\7Z\2\2\u0245\u0246\5,\27\2\u0246\u0247\7[\2\2\u0247\u0248"+ - "\5,\27\2\u0248Q\3\2\2\2\u0249\u024a\7W\2\2\u024a\u024b\7\36\2\2\u024b"+ - "\u024c\5*\26\2\u024c\u024e\7\37\2\2\u024d\u024f\5T+\2\u024e\u024d\3\2"+ - "\2\2\u024f\u0250\3\2\2\2\u0250\u024e\3\2\2\2\u0250\u0251\3\2\2\2\u0251"+ - "S\3\2\2\2\u0252\u0255\7X\2\2\u0253\u0256\7#\2\2\u0254\u0256\5\32\16\2"+ - "\u0255\u0253\3\2\2\2\u0255\u0254\3\2\2\2\u0256\u025e\3\2\2\2\u0257\u025a"+ - "\7\"\2\2\u0258\u025b\7#\2\2\u0259\u025b\5\32\16\2\u025a\u0258\3\2\2\2"+ - "\u025a\u0259\3\2\2\2\u025b\u025d\3\2\2\2\u025c\u0257\3\2\2\2\u025d\u0260"+ - "\3\2\2\2\u025e\u025c\3\2\2\2\u025e\u025f\3\2\2\2\u025f\u0261\3\2\2\2\u0260"+ - "\u025e\3\2\2\2\u0261\u0262\7\36\2\2\u0262\u0263\5*\26\2\u0263\u0264\7"+ - "\37\2\2\u0264U\3\2\2\2\u0265\u026a\5X-\2\u0266\u0267\7]\2\2\u0267\u0269"+ - "\5X-\2\u0268\u0266\3\2\2\2\u0269\u026c\3\2\2\2\u026a\u0268\3\2\2\2\u026a"+ - "\u026b\3\2\2\2\u026bW\3\2\2\2\u026c\u026a\3\2\2\2\u026d\u0272\5Z.\2\u026e"+ - "\u026f\7^\2\2\u026f\u0271\5Z.\2\u0270\u026e\3\2\2\2\u0271\u0274\3\2\2"+ - "\2\u0272\u0270\3\2\2\2\u0272\u0273\3\2\2\2\u0273Y\3\2\2\2\u0274\u0272"+ - "\3\2\2\2\u0275\u0277\7_\2\2\u0276\u0275\3\2\2\2\u0276\u0277\3\2\2\2\u0277"+ - "\u0278\3\2\2\2\u0278\u0279\5\\/\2\u0279[\3\2\2\2\u027a\u027d\5^\60\2\u027b"+ - "\u027c\t\5\2\2\u027c\u027e\5^\60\2\u027d\u027b\3\2\2\2\u027d\u027e\3\2"+ - "\2\2\u027e]\3\2\2\2\u027f\u0284\5`\61\2\u0280\u0281\7/\2\2\u0281\u0283"+ - "\5`\61\2\u0282\u0280\3\2\2\2\u0283\u0286\3\2\2\2\u0284\u0282\3\2\2\2\u0284"+ - "\u0285\3\2\2\2\u0285_\3\2\2\2\u0286\u0284\3\2\2\2\u0287\u028a\5b\62\2"+ - "\u0288\u0289\7`\2\2\u0289\u028b\5b\62\2\u028a\u0288\3\2\2\2\u028a\u028b"+ - "\3\2\2\2\u028ba\3\2\2\2\u028c\u0291\5d\63\2\u028d\u028e\t\6\2\2\u028e"+ - "\u0290\5d\63\2\u028f\u028d\3\2\2\2\u0290\u0293\3\2\2\2\u0291\u028f\3\2"+ - "\2\2\u0291\u0292\3\2\2\2\u0292c\3\2\2\2\u0293\u0291\3\2\2\2\u0294\u0299"+ - "\5f\64\2\u0295\u0296\t\7\2\2\u0296\u0298\5f\64\2\u0297\u0295\3\2\2\2\u0298"+ - "\u029b\3\2\2\2\u0299\u0297\3\2\2\2\u0299\u029a\3\2\2\2\u029ae\3\2\2\2"+ - "\u029b\u0299\3\2\2\2\u029c\u02a0\5h\65\2\u029d\u029e\7a\2\2\u029e\u029f"+ - "\7b\2\2\u029f\u02a1\5\u009cO\2\u02a0\u029d\3\2\2\2\u02a0\u02a1\3\2\2\2"+ - "\u02a1g\3\2\2\2\u02a2\u02a6\5j\66\2\u02a3\u02a4\7d\2\2\u02a4\u02a5\7c"+ - "\2\2\u02a5\u02a7\5\u009cO\2\u02a6\u02a3\3\2\2\2\u02a6\u02a7\3\2\2\2\u02a7"+ - "i\3\2\2\2\u02a8\u02ac\5l\67\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7G\2\2\u02ab"+ - "\u02ad\5\u009cO\2\u02ac\u02a9\3\2\2\2\u02ac\u02ad\3\2\2\2\u02adk\3\2\2"+ - "\2\u02ae\u02b2\5n8\2\u02af\u02b0\7g\2\2\u02b0\u02b1\7G\2\2\u02b1\u02b3"+ - "\5\u00a8U\2\u02b2\u02af\3\2\2\2\u02b2\u02b3\3\2\2\2\u02b3m\3\2\2\2\u02b4"+ - "\u02b8\5p9\2\u02b5\u02b6\7f\2\2\u02b6\u02b7\7G\2\2\u02b7\u02b9\5\u00a8"+ - "U\2\u02b8\u02b5\3\2\2\2\u02b8\u02b9\3\2\2\2\u02b9o\3\2\2\2\u02ba\u02c1"+ - "\5r:\2\u02bb\u02bc\7\6\2\2\u02bc\u02bd\7-\2\2\u02bd\u02be\3\2\2\2\u02be"+ - "\u02c0\5\u0090I\2\u02bf\u02bb\3\2\2\2\u02c0\u02c3\3\2\2\2\u02c1\u02bf"+ - "\3\2\2\2\u02c1\u02c2\3\2\2\2\u02c2q\3\2\2\2\u02c3\u02c1\3\2\2\2\u02c4"+ - "\u02c6\t\6\2\2\u02c5\u02c4\3\2\2\2\u02c6\u02c9\3\2\2\2\u02c7\u02c5\3\2"+ - "\2\2\u02c7\u02c8\3\2\2\2\u02c8\u02ca\3\2\2\2\u02c9\u02c7\3\2\2\2\u02ca"+ - "\u02cb\5t;\2\u02cbs\3\2\2\2\u02cc\u02cf\5x=\2\u02cd\u02cf\5v<\2\u02ce"+ - "\u02cc\3\2\2\2\u02ce\u02cd\3\2\2\2\u02cfu\3\2\2\2\u02d0\u02d1\7\65\2\2"+ - "\u02d1\u02d2\7 \2\2\u02d2\u02d3\5\u009cO\2\u02d3\u02d4\7\36\2\2\u02d4"+ - "\u02d5\5*\26\2\u02d5\u02d6\7\37\2\2\u02d6w\3\2\2\2\u02d7\u02dc\5z>\2\u02d8"+ - "\u02d9\7\66\2\2\u02d9\u02db\5z>\2\u02da\u02d8\3\2\2\2\u02db\u02de\3\2"+ - "\2\2\u02dc\u02da\3\2\2\2\u02dc\u02dd\3\2\2\2\u02ddy\3\2\2\2\u02de\u02dc"+ - "\3\2\2\2\u02df\u02e7\5\u0084C\2\u02e0\u02e6\5|?\2\u02e1\u02e6\5\u0080"+ - "A\2\u02e2\u02e6\5\u0082B\2\u02e3\u02e6\5~@\2\u02e4\u02e6\5\u0092J\2\u02e5"+ - "\u02e0\3\2\2\2\u02e5\u02e1\3\2\2\2\u02e5\u02e2\3\2\2\2\u02e5\u02e3\3\2"+ - "\2\2\u02e5\u02e4\3\2\2\2\u02e6\u02e9\3\2\2\2\u02e7\u02e5\3\2\2\2\u02e7"+ - "\u02e8\3\2\2\2\u02e8{\3\2\2\2\u02e9\u02e7\3\2\2\2\u02ea\u02eb\7\67\2\2"+ - "\u02eb\u02ec\7\67\2\2\u02ec\u02ed\5*\26\2\u02ed\u02ee\78\2\2\u02ee\u02ef"+ - "\78\2\2\u02ef}\3\2\2\2\u02f0\u02f1\7\67\2\2\u02f1\u02f2\78\2\2\u02f2\177"+ - "\3\2\2\2\u02f3\u02f4\7\67\2\2\u02f4\u02f5\5*\26\2\u02f5\u02f6\78\2\2\u02f6"+ - "\u0081\3\2\2\2\u02f7\u02fe\79\2\2\u02f8\u02ff\5\u00b2Z\2\u02f9\u02ff\5"+ - "\u00b0Y\2\u02fa\u02ff\7u\2\2\u02fb\u02ff\5\u0088E\2\u02fc\u02ff\5\u0086"+ - "D\2\u02fd\u02ff\5\u008aF\2\u02fe\u02f8\3\2\2\2\u02fe\u02f9\3\2\2\2\u02fe"+ - "\u02fa\3\2\2\2\u02fe\u02fb\3\2\2\2\u02fe\u02fc\3\2\2\2\u02fe\u02fd\3\2"+ - "\2\2\u02ff\u0083\3\2\2\2\u0300\u030d\7m\2\2\u0301\u030d\7n\2\2\u0302\u030d"+ - "\5\u00b0Y\2\u0303\u030d\5\u0086D\2\u0304\u030d\5\u0088E\2\u0305\u030d"+ - "\5\u008aF\2\u0306\u030d\5\u009eP\2\u0307\u030d\5\u0090I\2\u0308\u030d"+ - "\5\u008cG\2\u0309\u030d\5\u008eH\2\u030a\u030d\5\u00acW\2\u030b\u030d"+ - "\5\u0096L\2\u030c\u0300\3\2\2\2\u030c\u0301\3\2\2\2\u030c\u0302\3\2\2"+ - "\2\u030c\u0303\3\2\2\2\u030c\u0304\3\2\2\2\u030c\u0305\3\2\2\2\u030c\u0306"+ - "\3\2\2\2\u030c\u0307\3\2\2\2\u030c\u0308\3\2\2\2\u030c\u0309\3\2\2\2\u030c"+ - "\u030a\3\2\2\2\u030c\u030b\3\2\2\2\u030d\u0085\3\2\2\2\u030e\u030f\7!"+ - "\2\2\u030f\u0310\5\32\16\2\u0310\u0087\3\2\2\2\u0311\u0313\7\34\2\2\u0312"+ - "\u0314\5*\26\2\u0313\u0312\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0315\3\2"+ - "\2\2\u0315\u0316\7\35\2\2\u0316\u0089\3\2\2\2\u0317\u0318\7:\2\2\u0318"+ - "\u008b\3\2\2\2\u0319\u031a\7\t\2\2\u031a\u031b\7\36\2\2\u031b\u031c\5"+ - "*\26\2\u031c\u031d\7\37\2\2\u031d\u008d\3\2\2\2\u031e\u031f\7j\2\2\u031f"+ - "\u0320\7\36\2\2\u0320\u0321\5*\26\2\u0321\u0322\7\37\2\2\u0322\u008f\3"+ - "\2\2\2\u0323\u0324\5\32\16\2\u0324\u0325\5\u0092J\2\u0325\u0091\3\2\2"+ - "\2\u0326\u032d\7\34\2\2\u0327\u0329\5\u0094K\2\u0328\u032a\7\27\2\2\u0329"+ - "\u0328\3\2\2\2\u0329\u032a\3\2\2\2\u032a\u032c\3\2\2\2\u032b\u0327\3\2"+ - "\2\2\u032c\u032f\3\2\2\2\u032d\u032b\3\2\2\2\u032d\u032e\3\2\2\2\u032e"+ - "\u0330\3\2\2\2\u032f\u032d\3\2\2\2\u0330\u0331\7\35\2\2\u0331\u0093\3"+ - "\2\2\2\u0332\u0335\5,\27\2\u0333\u0335\7l\2\2\u0334\u0332\3\2\2\2\u0334"+ - "\u0333\3\2\2\2\u0335\u0095\3\2\2\2\u0336\u0339\5\u0098M\2\u0337\u0339"+ - "\5\u009aN\2\u0338\u0336\3\2\2\2\u0338\u0337\3\2\2\2\u0339\u0097\3\2\2"+ - "\2\u033a\u033b\5\32\16\2\u033b\u033c\7;\2\2\u033c\u033d\7n\2\2\u033d\u0099"+ - "\3\2\2\2\u033e\u033f\7\33\2\2\u033f\u0341\7\34\2\2\u0340\u0342\5&\24\2"+ - "\u0341\u0340\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\3\2\2\2\u0343\u0346"+ - "\7\35\2\2\u0344\u0345\7G\2\2\u0345\u0347\5\u009cO\2\u0346\u0344\3\2\2"+ - "\2\u0346\u0347\3\2\2\2\u0347\u0348\3\2\2\2\u0348\u034a\7\36\2\2\u0349"+ - "\u034b\5*\26\2\u034a\u0349\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ - "\2\2\u034c\u034d\7\37\2\2\u034d\u009b\3\2\2\2\u034e\u034f\7\34\2\2\u034f"+ - "\u0357\7\35\2\2\u0350\u0354\5\u00a0Q\2\u0351\u0355\7l\2\2\u0352\u0355"+ - "\7#\2\2\u0353\u0355\7\60\2\2\u0354\u0351\3\2\2\2\u0354\u0352\3\2\2\2\u0354"+ - "\u0353\3\2\2\2\u0354\u0355\3\2\2\2\u0355\u0357\3\2\2\2\u0356\u034e\3\2"+ - "\2\2\u0356\u0350\3\2\2\2\u0357\u009d\3\2\2\2\u0358\u0361\7\36\2\2\u0359"+ - "\u035e\5\u00aaV\2\u035a\u035b\7\27\2\2\u035b\u035d\5\u00aaV\2\u035c\u035a"+ - "\3\2\2\2\u035d\u0360\3\2\2\2\u035e\u035c\3\2\2\2\u035e\u035f\3\2\2\2\u035f"+ - "\u0362\3\2\2\2\u0360\u035e\3\2\2\2\u0361\u0359\3\2\2\2\u0361\u0362\3\2"+ - "\2\2\u0362\u0363\3\2\2\2\u0363\u0369\7\37\2\2\u0364\u0365\7<\2\2\u0365"+ - "\u0366\5*\26\2\u0366\u0367\7=\2\2\u0367\u0369\3\2\2\2\u0368\u0358\3\2"+ - "\2\2\u0368\u0364\3\2\2\2\u0369\u009f\3\2\2\2\u036a\u036e\5\32\16\2\u036b"+ - "\u036e\7m\2\2\u036c\u036e\5\u00a2R\2\u036d\u036a\3\2\2\2\u036d\u036b\3"+ - "\2\2\2\u036d\u036c\3\2\2\2\u036e\u00a1\3\2\2\2\u036f\u0372\5\u00a4S\2"+ - "\u0370\u0372\5\u00a6T\2\u0371\u036f\3\2\2\2\u0371\u0370\3\2\2\2\u0372"+ - "\u00a3\3\2\2\2\u0373\u0374\7\33\2\2\u0374\u0375\7\34\2\2\u0375\u0376\7"+ - "#\2\2\u0376\u0377\7\35\2\2\u0377\u00a5\3\2\2\2\u0378\u0379\7\33\2\2\u0379"+ - "\u0382\7\34\2\2\u037a\u037f\5\u009cO\2\u037b\u037c\7\27\2\2\u037c\u037e"+ - "\5\u009cO\2\u037d\u037b\3\2\2\2\u037e\u0381\3\2\2\2\u037f\u037d\3\2\2"+ - "\2\u037f\u0380\3\2\2\2\u0380\u0383\3\2\2\2\u0381\u037f\3\2\2\2\u0382\u037a"+ - "\3\2\2\2\u0382\u0383\3\2\2\2\u0383\u0384\3\2\2\2\u0384\u0385\7\35\2\2"+ - "\u0385\u0386\7G\2\2\u0386\u0387\5\u009cO\2\u0387\u00a7\3\2\2\2\u0388\u038a"+ - "\5\u00a0Q\2\u0389\u038b\7l\2\2\u038a\u0389\3\2\2\2\u038a\u038b\3\2\2\2"+ - "\u038b\u00a9\3\2\2\2\u038c\u038f\5,\27\2\u038d\u038f\7u\2\2\u038e\u038c"+ - "\3\2\2\2\u038e\u038d\3\2\2\2\u038f\u0390\3\2\2\2\u0390\u0391\t\b\2\2\u0391"+ - "\u0392\5,\27\2\u0392\u00ab\3\2\2\2\u0393\u0395\7\67\2\2\u0394\u0396\5"+ - "*\26\2\u0395\u0394\3\2\2\2\u0395\u0396\3\2\2\2\u0396\u0397\3\2\2\2\u0397"+ - "\u0398\78\2\2\u0398\u00ad\3\2\2\2\u0399\u039a\5\u00b0Y\2\u039a\u00af\3"+ - "\2\2\2\u039b\u039c\7k\2\2\u039c\u00b1\3\2\2\2\u039d\u039e\t\t\2\2\u039e"+ - "\u00b3\3\2\2\2e\u00bc\u00c0\u00d0\u00d6\u00de\u00e5\u00f0\u0106\u010e"+ - "\u0113\u0116\u011a\u0123\u012c\u012f\u0136\u013d\u013f\u0146\u014b\u014f"+ - "\u0153\u0160\u0167\u016e\u0178\u017c\u0184\u0186\u0192\u0198\u019c\u01a0"+ - "\u01ab\u01b1\u01c0\u01c6\u01ca\u01ce\u01d5\u01dc\u01e2\u01e7\u01e9\u01ed"+ - "\u01f4\u01fb\u0204\u0210\u021a\u0226\u022a\u0233\u023a\u0250\u0255\u025a"+ - "\u025e\u026a\u0272\u0276\u027d\u0284\u028a\u0291\u0299\u02a0\u02a6\u02ac"+ - "\u02b2\u02b8\u02c1\u02c7\u02ce\u02dc\u02e5\u02e7\u02fe\u030c\u0313\u0329"+ - "\u032d\u0334\u0338\u0341\u0346\u034a\u0354\u0356\u035e\u0361\u0368\u036d"+ - "\u0371\u037f\u0382\u038a\u038e\u0395"; + "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\3\2\3\2\3\2\3\3\3\3\3\3\3\3"+ + "\3\3\5\3\u00bf\n\3\3\3\3\3\5\3\u00c3\n\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3"+ + "\5\3\5\3\5\3\5\3\6\3\6\3\6\5\6\u00d3\n\6\3\6\3\6\7\6\u00d7\n\6\f\6\16"+ + "\6\u00da\13\6\3\6\3\6\3\6\7\6\u00df\n\6\f\6\16\6\u00e2\13\6\3\7\3\7\3"+ + "\7\3\7\5\7\u00e8\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\t\u00f3\n\t"+ + "\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3"+ + "\r\3\r\3\r\3\r\5\r\u0109\n\r\3\r\3\r\3\r\3\r\7\r\u010f\n\r\f\r\16\r\u0112"+ + "\13\r\3\16\3\16\5\16\u0116\n\16\3\16\5\16\u0119\n\16\3\16\3\16\5\16\u011d"+ + "\n\16\3\17\3\17\3\20\3\20\3\21\3\21\3\21\3\21\3\21\5\21\u0128\n\21\3\21"+ + "\3\21\3\21\3\21\3\21\7\21\u012f\n\21\f\21\16\21\u0132\13\21\5\21\u0134"+ + "\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u013b\n\22\3\22\3\22\3\22\3\22\3\22"+ + "\5\22\u0142\n\22\5\22\u0144\n\22\3\23\3\23\3\23\3\23\3\23\5\23\u014b\n"+ + "\23\3\23\3\23\3\23\5\23\u0150\n\23\3\23\3\23\5\23\u0154\n\23\3\23\3\23"+ + "\5\23\u0158\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\7\25\u0163"+ + "\n\25\f\25\16\25\u0166\13\25\3\26\3\26\3\26\3\26\5\26\u016c\n\26\3\27"+ + "\3\27\3\27\7\27\u0171\n\27\f\27\16\27\u0174\13\27\3\30\3\30\3\30\3\30"+ + "\3\30\3\30\3\30\5\30\u017d\n\30\3\31\3\31\5\31\u0181\n\31\3\31\3\31\3"+ + "\31\3\31\3\31\3\31\7\31\u0189\n\31\f\31\16\31\u018c\13\31\3\31\3\31\3"+ + "\31\3\32\3\32\3\32\3\32\7\32\u0195\n\32\f\32\16\32\u0198\13\32\3\33\3"+ + "\33\3\33\5\33\u019d\n\33\3\33\3\33\5\33\u01a1\n\33\3\33\3\33\5\33\u01a5"+ + "\n\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\7\34\u01ae\n\34\f\34\16\34\u01b1"+ + "\13\34\3\35\3\35\3\35\5\35\u01b6\n\35\3\35\3\35\3\35\3\36\3\36\3\36\3"+ + "\37\3\37\3\37\3\37\3\37\7\37\u01c3\n\37\f\37\16\37\u01c6\13\37\3 \3 \3"+ + " \5 \u01cb\n \3 \3 \5 \u01cf\n \3 \3 \5 \u01d3\n \3!\3!\3!\3!\3!\5!\u01da"+ + "\n!\3!\3!\3!\7!\u01df\n!\f!\16!\u01e2\13!\3\"\3\"\3\"\5\"\u01e7\n\"\3"+ + "\"\3\"\3\"\5\"\u01ec\n\"\5\"\u01ee\n\"\3\"\3\"\5\"\u01f2\n\"\3#\3#\3#"+ + "\3$\3$\5$\u01f9\n$\3$\3$\3$\7$\u01fe\n$\f$\16$\u0201\13$\3$\3$\3$\3%\3"+ + "%\3%\5%\u0209\n%\3%\3%\3%\3&\3&\3&\3&\3&\6&\u0213\n&\r&\16&\u0214\3&\3"+ + "&\3&\3&\3\'\3\'\6\'\u021d\n\'\r\'\16\'\u021e\3\'\3\'\3\'\3(\3(\3(\3(\3"+ + "(\6(\u0229\n(\r(\16(\u022a\3(\3(\5(\u022f\n(\3(\3(\3(\3)\3)\3)\3)\5)\u0238"+ + "\n)\3)\3)\3)\7)\u023d\n)\f)\16)\u0240\13)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3"+ + "*\3*\3*\3+\3+\3+\3+\3+\6+\u0253\n+\r+\16+\u0254\3,\3,\3,\5,\u025a\n,\3"+ + ",\3,\3,\5,\u025f\n,\7,\u0261\n,\f,\16,\u0264\13,\3,\3,\3,\3,\3-\3-\3-"+ + "\7-\u026d\n-\f-\16-\u0270\13-\3.\3.\3.\7.\u0275\n.\f.\16.\u0278\13.\3"+ + "/\5/\u027b\n/\3/\3/\3\60\3\60\3\60\5\60\u0282\n\60\3\61\3\61\3\61\7\61"+ + "\u0287\n\61\f\61\16\61\u028a\13\61\3\62\3\62\3\62\5\62\u028f\n\62\3\63"+ + "\3\63\3\63\7\63\u0294\n\63\f\63\16\63\u0297\13\63\3\64\3\64\3\64\7\64"+ + "\u029c\n\64\f\64\16\64\u029f\13\64\3\65\3\65\3\65\3\65\5\65\u02a5\n\65"+ + "\3\66\3\66\3\66\3\66\5\66\u02ab\n\66\3\67\3\67\3\67\3\67\5\67\u02b1\n"+ + "\67\38\38\38\38\58\u02b7\n8\39\39\39\39\59\u02bd\n9\3:\3:\3:\3:\3:\7:"+ + "\u02c4\n:\f:\16:\u02c7\13:\3;\7;\u02ca\n;\f;\16;\u02cd\13;\3;\3;\3<\3"+ + "<\5<\u02d3\n<\3=\3=\3=\3=\3=\3=\3=\3>\3>\3>\7>\u02df\n>\f>\16>\u02e2\13"+ + ">\3?\3?\3?\3?\3?\3?\7?\u02ea\n?\f?\16?\u02ed\13?\3@\3@\3@\3@\3@\3@\3A"+ + "\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3C\5C\u0303\nC\3D\3D\3D\3D\3D\3D"+ + "\3D\3D\3D\3D\3D\3D\5D\u0311\nD\3E\3E\3E\3F\3F\5F\u0318\nF\3F\3F\3G\3G"+ + "\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3K\3K\3K\5K\u032e\nK\7K\u0330"+ + "\nK\fK\16K\u0333\13K\3K\3K\3L\3L\5L\u0339\nL\3M\3M\5M\u033d\nM\3N\3N\3"+ + "N\3N\3O\3O\3O\5O\u0346\nO\3O\3O\3O\5O\u034b\nO\3O\3O\5O\u034f\nO\3O\3"+ + "O\3P\3P\3P\3P\3P\3P\5P\u0359\nP\5P\u035b\nP\3Q\3Q\3Q\3Q\7Q\u0361\nQ\f"+ + "Q\16Q\u0364\13Q\5Q\u0366\nQ\3Q\3Q\3Q\3Q\3Q\5Q\u036d\nQ\3R\3R\3R\5R\u0372"+ + "\nR\3S\3S\5S\u0376\nS\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\7U\u0382\nU\fU\16"+ + "U\u0385\13U\5U\u0387\nU\3U\3U\3U\3U\3V\3V\5V\u038f\nV\3W\3W\5W\u0393\n"+ + "W\3W\3W\3W\3X\3X\5X\u039a\nX\3X\3X\3Y\3Y\3Z\3Z\3[\3[\3[\2\2\\\2\4\6\b"+ + "\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVX"+ + "Z\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e\u0090"+ + "\u0092\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6\u00a8"+ + "\u00aa\u00ac\u00ae\u00b0\u00b2\u00b4\2\13\3\2\t\n\3\2TU\4\2mmuu\3\2\r"+ + "\26\4\2\6\6%/\3\2\61\62\4\2$$\63\65\4\2\f\fll\4\2?jmm\2\u03ce\2\u00b6"+ + "\3\2\2\2\4\u00be\3\2\2\2\6\u00c4\3\2\2\2\b\u00c7\3\2\2\2\n\u00d8\3\2\2"+ + "\2\f\u00e7\3\2\2\2\16\u00e9\3\2\2\2\20\u00f2\3\2\2\2\22\u00f4\3\2\2\2"+ + "\24\u00f9\3\2\2\2\26\u00fd\3\2\2\2\30\u0103\3\2\2\2\32\u0118\3\2\2\2\34"+ + "\u011e\3\2\2\2\36\u0120\3\2\2\2 \u0122\3\2\2\2\"\u0135\3\2\2\2$\u0145"+ + "\3\2\2\2&\u0159\3\2\2\2(\u015f\3\2\2\2*\u0167\3\2\2\2,\u016d\3\2\2\2."+ + "\u017c\3\2\2\2\60\u0180\3\2\2\2\62\u0190\3\2\2\2\64\u0199\3\2\2\2\66\u01a9"+ + "\3\2\2\28\u01b2\3\2\2\2:\u01ba\3\2\2\2<\u01bd\3\2\2\2>\u01c7\3\2\2\2@"+ + "\u01d9\3\2\2\2B\u01e3\3\2\2\2D\u01f3\3\2\2\2F\u01f8\3\2\2\2H\u0205\3\2"+ + "\2\2J\u020d\3\2\2\2L\u021c\3\2\2\2N\u0223\3\2\2\2P\u0233\3\2\2\2R\u0244"+ + "\3\2\2\2T\u024d\3\2\2\2V\u0256\3\2\2\2X\u0269\3\2\2\2Z\u0271\3\2\2\2\\"+ + "\u027a\3\2\2\2^\u027e\3\2\2\2`\u0283\3\2\2\2b\u028b\3\2\2\2d\u0290\3\2"+ + "\2\2f\u0298\3\2\2\2h\u02a0\3\2\2\2j\u02a6\3\2\2\2l\u02ac\3\2\2\2n\u02b2"+ + "\3\2\2\2p\u02b8\3\2\2\2r\u02be\3\2\2\2t\u02cb\3\2\2\2v\u02d2\3\2\2\2x"+ + "\u02d4\3\2\2\2z\u02db\3\2\2\2|\u02e3\3\2\2\2~\u02ee\3\2\2\2\u0080\u02f4"+ + "\3\2\2\2\u0082\u02f7\3\2\2\2\u0084\u02fb\3\2\2\2\u0086\u0310\3\2\2\2\u0088"+ + "\u0312\3\2\2\2\u008a\u0315\3\2\2\2\u008c\u031b\3\2\2\2\u008e\u031d\3\2"+ + "\2\2\u0090\u0322\3\2\2\2\u0092\u0327\3\2\2\2\u0094\u032a\3\2\2\2\u0096"+ + "\u0338\3\2\2\2\u0098\u033c\3\2\2\2\u009a\u033e\3\2\2\2\u009c\u0342\3\2"+ + "\2\2\u009e\u035a\3\2\2\2\u00a0\u036c\3\2\2\2\u00a2\u0371\3\2\2\2\u00a4"+ + "\u0375\3\2\2\2\u00a6\u0377\3\2\2\2\u00a8\u037c\3\2\2\2\u00aa\u038c\3\2"+ + "\2\2\u00ac\u0392\3\2\2\2\u00ae\u0397\3\2\2\2\u00b0\u039d\3\2\2\2\u00b2"+ + "\u039f\3\2\2\2\u00b4\u03a1\3\2\2\2\u00b6\u00b7\5\4\3\2\u00b7\u00b8\7\2"+ + "\2\3\u00b8\3\3\2\2\2\u00b9\u00ba\7j\2\2\u00ba\u00bb\7i\2\2\u00bb\u00bc"+ + "\5\u00b2Z\2\u00bc\u00bd\7\3\2\2\u00bd\u00bf\3\2\2\2\u00be\u00b9\3\2\2"+ + "\2\u00be\u00bf\3\2\2\2\u00bf\u00c2\3\2\2\2\u00c0\u00c3\5\b\5\2\u00c1\u00c3"+ + "\5\6\4\2\u00c2\u00c0\3\2\2\2\u00c2\u00c1\3\2\2\2\u00c3\5\3\2\2\2\u00c4"+ + "\u00c5\5\n\6\2\u00c5\u00c6\5,\27\2\u00c6\7\3\2\2\2\u00c7\u00c8\7\4\2\2"+ + "\u00c8\u00c9\7\5\2\2\u00c9\u00ca\7u\2\2\u00ca\u00cb\7\6\2\2\u00cb\u00cc"+ + "\5\u00b0Y\2\u00cc\u00cd\7\3\2\2\u00cd\u00ce\5\n\6\2\u00ce\t\3\2\2\2\u00cf"+ + "\u00d3\5\f\7\2\u00d0\u00d3\5\16\b\2\u00d1\u00d3\5 \21\2\u00d2\u00cf\3"+ + "\2\2\2\u00d2\u00d0\3\2\2\2\u00d2\u00d1\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4"+ + "\u00d5\7\3\2\2\u00d5\u00d7\3\2\2\2\u00d6\u00d2\3\2\2\2\u00d7\u00da\3\2"+ + "\2\2\u00d8\u00d6\3\2\2\2\u00d8\u00d9\3\2\2\2\u00d9\u00e0\3\2\2\2\u00da"+ + "\u00d8\3\2\2\2\u00db\u00dc\5\20\t\2\u00dc\u00dd\7\3\2\2\u00dd\u00df\3"+ + "\2\2\2\u00de\u00db\3\2\2\2\u00df\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0"+ + "\u00e1\3\2\2\2\u00e1\13\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e8\5\22\n"+ + "\2\u00e4\u00e8\5\24\13\2\u00e5\u00e8\5\26\f\2\u00e6\u00e8\5\30\r\2\u00e7"+ + "\u00e3\3\2\2\2\u00e7\u00e4\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e7\u00e6\3\2"+ + "\2\2\u00e8\r\3\2\2\2\u00e9\u00ea\7\7\2\2\u00ea\u00eb\7\5\2\2\u00eb\u00ec"+ + "\7u\2\2\u00ec\u00ed\7\6\2\2\u00ed\u00ee\5\u00b0Y\2\u00ee\17\3\2\2\2\u00ef"+ + "\u00f3\5$\23\2\u00f0\u00f3\5\"\22\2\u00f1\u00f3\5&\24\2\u00f2\u00ef\3"+ + "\2\2\2\u00f2\u00f0\3\2\2\2\u00f2\u00f1\3\2\2\2\u00f3\21\3\2\2\2\u00f4"+ + "\u00f5\7\7\2\2\u00f5\u00f6\7Z\2\2\u00f6\u00f7\7S\2\2\u00f7\u00f8\5\u00b0"+ + "Y\2\u00f8\23\3\2\2\2\u00f9\u00fa\7\7\2\2\u00fa\u00fb\7\b\2\2\u00fb\u00fc"+ + "\t\2\2\2\u00fc\25\3\2\2\2\u00fd\u00fe\7\7\2\2\u00fe\u00ff\7Z\2\2\u00ff"+ + "\u0100\7D\2\2\u0100\u0101\7K\2\2\u0101\u0102\t\3\2\2\u0102\27\3\2\2\2"+ + "\u0103\u0108\7\7\2\2\u0104\u0105\7\13\2\2\u0105\u0109\5\32\16\2\u0106"+ + "\u0107\7Z\2\2\u0107\u0109\7\13\2\2\u0108\u0104\3\2\2\2\u0108\u0106\3\2"+ + "\2\2\u0109\u0110\3\2\2\2\u010a\u010b\5\36\20\2\u010b\u010c\7\6\2\2\u010c"+ + "\u010d\5\u00b2Z\2\u010d\u010f\3\2\2\2\u010e\u010a\3\2\2\2\u010f\u0112"+ + "\3\2\2\2\u0110\u010e\3\2\2\2\u0110\u0111\3\2\2\2\u0111\31\3\2\2\2\u0112"+ + "\u0110\3\2\2\2\u0113\u0116\7u\2\2\u0114\u0116\5\u00b4[\2\u0115\u0113\3"+ + "\2\2\2\u0115\u0114\3\2\2\2\u0116\u0117\3\2\2\2\u0117\u0119\7\f\2\2\u0118"+ + "\u0115\3\2\2\2\u0118\u0119\3\2\2\2\u0119\u011c\3\2\2\2\u011a\u011d\5\34"+ + "\17\2\u011b\u011d\5\u00b4[\2\u011c\u011a\3\2\2\2\u011c\u011b\3\2\2\2\u011d"+ + "\33\3\2\2\2\u011e\u011f\t\4\2\2\u011f\35\3\2\2\2\u0120\u0121\t\5\2\2\u0121"+ + "\37\3\2\2\2\u0122\u0123\7\27\2\2\u0123\u0127\7\4\2\2\u0124\u0125\7\5\2"+ + "\2\u0125\u0126\7u\2\2\u0126\u0128\7\6\2\2\u0127\u0124\3\2\2\2\u0127\u0128"+ + "\3\2\2\2\u0128\u0129\3\2\2\2\u0129\u0133\5\u00b0Y\2\u012a\u012b\7I\2\2"+ + "\u012b\u0130\5\u00b0Y\2\u012c\u012d\7\30\2\2\u012d\u012f\5\u00b0Y\2\u012e"+ + "\u012c\3\2\2\2\u012f\u0132\3\2\2\2\u0130\u012e\3\2\2\2\u0130\u0131\3\2"+ + "\2\2\u0131\u0134\3\2\2\2\u0132\u0130\3\2\2\2\u0133\u012a\3\2\2\2\u0133"+ + "\u0134\3\2\2\2\u0134!\3\2\2\2\u0135\u0136\7\7\2\2\u0136\u0137\7\31\2\2"+ + "\u0137\u013a\5\u0088E\2\u0138\u0139\7H\2\2\u0139\u013b\5\u009eP\2\u013a"+ + "\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u0143\3\2\2\2\u013c\u013d\7\32"+ + "\2\2\u013d\u0144\5.\30\2\u013e\u0141\7\33\2\2\u013f\u0140\7\32\2\2\u0140"+ + "\u0142\5.\30\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2\2\2\u0142\u0144\3\2"+ + "\2\2\u0143\u013c\3\2\2\2\u0143\u013e\3\2\2\2\u0144#\3\2\2\2\u0145\u0146"+ + "\7\7\2\2\u0146\u0147\7\34\2\2\u0147\u0148\5\32\16\2\u0148\u014a\7\35\2"+ + "\2\u0149\u014b\5(\25\2\u014a\u0149\3\2\2\2\u014a\u014b\3\2\2\2\u014b\u014c"+ + "\3\2\2\2\u014c\u014f\7\36\2\2\u014d\u014e\7H\2\2\u014e\u0150\5\u009eP"+ + "\2\u014f\u014d\3\2\2\2\u014f\u0150\3\2\2\2\u0150\u0157\3\2\2\2\u0151\u0153"+ + "\7\37\2\2\u0152\u0154\5,\27\2\u0153\u0152\3\2\2\2\u0153\u0154\3\2\2\2"+ + "\u0154\u0155\3\2\2\2\u0155\u0158\7 \2\2\u0156\u0158\7\33\2\2\u0157\u0151"+ + "\3\2\2\2\u0157\u0156\3\2\2\2\u0158%\3\2\2\2\u0159\u015a\7\7\2\2\u015a"+ + "\u015b\7!\2\2\u015b\u015c\5\32\16\2\u015c\u015d\7H\2\2\u015d\u015e\5."+ + "\30\2\u015e\'\3\2\2\2\u015f\u0164\5*\26\2\u0160\u0161\7\30\2\2\u0161\u0163"+ + "\5*\26\2\u0162\u0160\3\2\2\2\u0163\u0166\3\2\2\2\u0164\u0162\3\2\2\2\u0164"+ + "\u0165\3\2\2\2\u0165)\3\2\2\2\u0166\u0164\3\2\2\2\u0167\u0168\7\"\2\2"+ + "\u0168\u016b\5\32\16\2\u0169\u016a\7H\2\2\u016a\u016c\5\u009eP\2\u016b"+ + "\u0169\3\2\2\2\u016b\u016c\3\2\2\2\u016c+\3\2\2\2\u016d\u0172\5.\30\2"+ + "\u016e\u016f\7\30\2\2\u016f\u0171\5.\30\2\u0170\u016e\3\2\2\2\u0171\u0174"+ + "\3\2\2\2\u0172\u0170\3\2\2\2\u0172\u0173\3\2\2\2\u0173-\3\2\2\2\u0174"+ + "\u0172\3\2\2\2\u0175\u017d\5\60\31\2\u0176\u017d\5F$\2\u0177\u017d\5J"+ + "&\2\u0178\u017d\5N(\2\u0179\u017d\5R*\2\u017a\u017d\5T+\2\u017b\u017d"+ + "\5X-\2\u017c\u0175\3\2\2\2\u017c\u0176\3\2\2\2\u017c\u0177\3\2\2\2\u017c"+ + "\u0178\3\2\2\2\u017c\u0179\3\2\2\2\u017c\u017a\3\2\2\2\u017c\u017b\3\2"+ + "\2\2\u017d/\3\2\2\2\u017e\u0181\5\62\32\2\u017f\u0181\5\66\34\2\u0180"+ + "\u017e\3\2\2\2\u0180\u017f\3\2\2\2\u0181\u018a\3\2\2\2\u0182\u0189\5\62"+ + "\32\2\u0183\u0189\5:\36\2\u0184\u0189\5\66\34\2\u0185\u0189\5<\37\2\u0186"+ + "\u0189\5@!\2\u0187\u0189\5D#\2\u0188\u0182\3\2\2\2\u0188\u0183\3\2\2\2"+ + "\u0188\u0184\3\2\2\2\u0188\u0185\3\2\2\2\u0188\u0186\3\2\2\2\u0188\u0187"+ + "\3\2\2\2\u0189\u018c\3\2\2\2\u018a\u0188\3\2\2\2\u018a\u018b\3\2\2\2\u018b"+ + "\u018d\3\2\2\2\u018c\u018a\3\2\2\2\u018d\u018e\7E\2\2\u018e\u018f\5.\30"+ + "\2\u018f\61\3\2\2\2\u0190\u0191\7?\2\2\u0191\u0196\5\64\33\2\u0192\u0193"+ + "\7\30\2\2\u0193\u0195\5\64\33\2\u0194\u0192\3\2\2\2\u0195\u0198\3\2\2"+ + "\2\u0196\u0194\3\2\2\2\u0196\u0197\3\2\2\2\u0197\63\3\2\2\2\u0198\u0196"+ + "\3\2\2\2\u0199\u019c\5\u0088E\2\u019a\u019b\7H\2\2\u019b\u019d\5\u009e"+ + "P\2\u019c\u019a\3\2\2\2\u019c\u019d\3\2\2\2\u019d\u01a0\3\2\2\2\u019e"+ + "\u019f\7J\2\2\u019f\u01a1\7K\2\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2\2"+ + "\2\u01a1\u01a4\3\2\2\2\u01a2\u01a3\7I\2\2\u01a3\u01a5\5\u0088E\2\u01a4"+ + "\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a7\7G"+ + "\2\2\u01a7\u01a8\5.\30\2\u01a8\65\3\2\2\2\u01a9\u01aa\7@\2\2\u01aa\u01af"+ + "\58\35\2\u01ab\u01ac\7\30\2\2\u01ac\u01ae\58\35\2\u01ad\u01ab\3\2\2\2"+ + "\u01ae\u01b1\3\2\2\2\u01af\u01ad\3\2\2\2\u01af\u01b0\3\2\2\2\u01b0\67"+ + "\3\2\2\2\u01b1\u01af\3\2\2\2\u01b2\u01b5\5\u0088E\2\u01b3\u01b4\7H\2\2"+ + "\u01b4\u01b6\5\u009eP\2\u01b5\u01b3\3\2\2\2\u01b5\u01b6\3\2\2\2\u01b6"+ + "\u01b7\3\2\2\2\u01b7\u01b8\7\32\2\2\u01b8\u01b9\5.\30\2\u01b99\3\2\2\2"+ + "\u01ba\u01bb\7A\2\2\u01bb\u01bc\5.\30\2\u01bc;\3\2\2\2\u01bd\u01be\7B"+ + "\2\2\u01be\u01bf\7C\2\2\u01bf\u01c4\5> \2\u01c0\u01c1\7\30\2\2\u01c1\u01c3"+ + "\5> \2\u01c2\u01c0\3\2\2\2\u01c3\u01c6\3\2\2\2\u01c4\u01c2\3\2\2\2\u01c4"+ + "\u01c5\3\2\2\2\u01c5=\3\2\2\2\u01c6\u01c4\3\2\2\2\u01c7\u01ce\5\u0088"+ + "E\2\u01c8\u01c9\7H\2\2\u01c9\u01cb\5\u009eP\2\u01ca\u01c8\3\2\2\2\u01ca"+ + "\u01cb\3\2\2\2\u01cb\u01cc\3\2\2\2\u01cc\u01cd\7\32\2\2\u01cd\u01cf\5"+ + ".\30\2\u01ce\u01ca\3\2\2\2\u01ce\u01cf\3\2\2\2\u01cf\u01d2\3\2\2\2\u01d0"+ + "\u01d1\7S\2\2\u01d1\u01d3\5\u00b0Y\2\u01d2\u01d0\3\2\2\2\u01d2\u01d3\3"+ + "\2\2\2\u01d3?\3\2\2\2\u01d4\u01d5\7D\2\2\u01d5\u01da\7C\2\2\u01d6\u01d7"+ + "\7M\2\2\u01d7\u01d8\7D\2\2\u01d8\u01da\7C\2\2\u01d9\u01d4\3\2\2\2\u01d9"+ + "\u01d6\3\2\2\2\u01da\u01db\3\2\2\2\u01db\u01e0\5B\"\2\u01dc\u01dd\7\30"+ + "\2\2\u01dd\u01df\5B\"\2\u01de\u01dc\3\2\2\2\u01df\u01e2\3\2\2\2\u01e0"+ + "\u01de\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1A\3\2\2\2\u01e2\u01e0\3\2\2\2"+ + "\u01e3\u01e6\5.\30\2\u01e4\u01e7\7N\2\2\u01e5\u01e7\7O\2\2\u01e6\u01e4"+ + "\3\2\2\2\u01e6\u01e5\3\2\2\2\u01e6\u01e7\3\2\2\2\u01e7\u01ed\3\2\2\2\u01e8"+ + "\u01eb\7K\2\2\u01e9\u01ec\7T\2\2\u01ea\u01ec\7U\2\2\u01eb\u01e9\3\2\2"+ + "\2\u01eb\u01ea\3\2\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01e8\3\2\2\2\u01ed\u01ee"+ + "\3\2\2\2\u01ee\u01f1\3\2\2\2\u01ef\u01f0\7S\2\2\u01f0\u01f2\5\u00b0Y\2"+ + "\u01f1\u01ef\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2C\3\2\2\2\u01f3\u01f4\7"+ + "L\2\2\u01f4\u01f5\5\u0088E\2\u01f5E\3\2\2\2\u01f6\u01f9\7P\2\2\u01f7\u01f9"+ + "\7Q\2\2\u01f8\u01f6\3\2\2\2\u01f8\u01f7\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fa"+ + "\u01ff\5H%\2\u01fb\u01fc\7\30\2\2\u01fc\u01fe\5H%\2\u01fd\u01fb\3\2\2"+ + "\2\u01fe\u0201\3\2\2\2\u01ff\u01fd\3\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0202"+ + "\3\2\2\2\u0201\u01ff\3\2\2\2\u0202\u0203\7R\2\2\u0203\u0204\5.\30\2\u0204"+ + "G\3\2\2\2\u0205\u0208\5\u0088E\2\u0206\u0207\7H\2\2\u0207\u0209\5\u009e"+ + "P\2\u0208\u0206\3\2\2\2\u0208\u0209\3\2\2\2\u0209\u020a\3\2\2\2\u020a"+ + "\u020b\7G\2\2\u020b\u020c\5.\30\2\u020cI\3\2\2\2\u020d\u020e\7V\2\2\u020e"+ + "\u020f\7\35\2\2\u020f\u0210\5,\27\2\u0210\u0212\7\36\2\2\u0211\u0213\5"+ + "L\'\2\u0212\u0211\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0212\3\2\2\2\u0214"+ + "\u0215\3\2\2\2\u0215\u0216\3\2\2\2\u0216\u0217\7Z\2\2\u0217\u0218\7E\2"+ + "\2\u0218\u0219\5.\30\2\u0219K\3\2\2\2\u021a\u021b\7W\2\2\u021b\u021d\5"+ + ".\30\2\u021c\u021a\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u021c\3\2\2\2\u021e"+ + "\u021f\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0221\7E\2\2\u0221\u0222\5.\30"+ + "\2\u0222M\3\2\2\2\u0223\u0224\7]\2\2\u0224\u0225\7\35\2\2\u0225\u0226"+ + "\5,\27\2\u0226\u0228\7\36\2\2\u0227\u0229\5P)\2\u0228\u0227\3\2\2\2\u0229"+ + "\u022a\3\2\2\2\u022a\u0228\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u022c\3\2"+ + "\2\2\u022c\u022e\7Z\2\2\u022d\u022f\5\u0088E\2\u022e\u022d\3\2\2\2\u022e"+ + "\u022f\3\2\2\2\u022f\u0230\3\2\2\2\u0230\u0231\7E\2\2\u0231\u0232\5.\30"+ + "\2\u0232O\3\2\2\2\u0233\u0237\7W\2\2\u0234\u0235\5\u0088E\2\u0235\u0236"+ + "\7H\2\2\u0236\u0238\3\2\2\2\u0237\u0234\3\2\2\2\u0237\u0238\3\2\2\2\u0238"+ + "\u0239\3\2\2\2\u0239\u023e\5\u009eP\2\u023a\u023b\7#\2\2\u023b\u023d\5"+ + "\u009eP\2\u023c\u023a\3\2\2\2\u023d\u0240\3\2\2\2\u023e\u023c\3\2\2\2"+ + "\u023e\u023f\3\2\2\2\u023f\u0241\3\2\2\2\u0240\u023e\3\2\2\2\u0241\u0242"+ + "\7E\2\2\u0242\u0243\5.\30\2\u0243Q\3\2\2\2\u0244\u0245\7F\2\2\u0245\u0246"+ + "\7\35\2\2\u0246\u0247\5,\27\2\u0247\u0248\7\36\2\2\u0248\u0249\7[\2\2"+ + "\u0249\u024a\5.\30\2\u024a\u024b\7\\\2\2\u024b\u024c\5.\30\2\u024cS\3"+ + "\2\2\2\u024d\u024e\7X\2\2\u024e\u024f\7\37\2\2\u024f\u0250\5,\27\2\u0250"+ + "\u0252\7 \2\2\u0251\u0253\5V,\2\u0252\u0251\3\2\2\2\u0253\u0254\3\2\2"+ + "\2\u0254\u0252\3\2\2\2\u0254\u0255\3\2\2\2\u0255U\3\2\2\2\u0256\u0259"+ + "\7Y\2\2\u0257\u025a\7$\2\2\u0258\u025a\5\32\16\2\u0259\u0257\3\2\2\2\u0259"+ + "\u0258\3\2\2\2\u025a\u0262\3\2\2\2\u025b\u025e\7#\2\2\u025c\u025f\7$\2"+ + "\2\u025d\u025f\5\32\16\2\u025e\u025c\3\2\2\2\u025e\u025d\3\2\2\2\u025f"+ + "\u0261\3\2\2\2\u0260\u025b\3\2\2\2\u0261\u0264\3\2\2\2\u0262\u0260\3\2"+ + "\2\2\u0262\u0263\3\2\2\2\u0263\u0265\3\2\2\2\u0264\u0262\3\2\2\2\u0265"+ + "\u0266\7\37\2\2\u0266\u0267\5,\27\2\u0267\u0268\7 \2\2\u0268W\3\2\2\2"+ + "\u0269\u026e\5Z.\2\u026a\u026b\7^\2\2\u026b\u026d\5Z.\2\u026c\u026a\3"+ + "\2\2\2\u026d\u0270\3\2\2\2\u026e\u026c\3\2\2\2\u026e\u026f\3\2\2\2\u026f"+ + "Y\3\2\2\2\u0270\u026e\3\2\2\2\u0271\u0276\5\\/\2\u0272\u0273\7_\2\2\u0273"+ + "\u0275\5\\/\2\u0274\u0272\3\2\2\2\u0275\u0278\3\2\2\2\u0276\u0274\3\2"+ + "\2\2\u0276\u0277\3\2\2\2\u0277[\3\2\2\2\u0278\u0276\3\2\2\2\u0279\u027b"+ + "\7`\2\2\u027a\u0279\3\2\2\2\u027a\u027b\3\2\2\2\u027b\u027c\3\2\2\2\u027c"+ + "\u027d\5^\60\2\u027d]\3\2\2\2\u027e\u0281\5`\61\2\u027f\u0280\t\6\2\2"+ + "\u0280\u0282\5`\61\2\u0281\u027f\3\2\2\2\u0281\u0282\3\2\2\2\u0282_\3"+ + "\2\2\2\u0283\u0288\5b\62\2\u0284\u0285\7\60\2\2\u0285\u0287\5b\62\2\u0286"+ + "\u0284\3\2\2\2\u0287\u028a\3\2\2\2\u0288\u0286\3\2\2\2\u0288\u0289\3\2"+ + "\2\2\u0289a\3\2\2\2\u028a\u0288\3\2\2\2\u028b\u028e\5d\63\2\u028c\u028d"+ + "\7a\2\2\u028d\u028f\5d\63\2\u028e\u028c\3\2\2\2\u028e\u028f\3\2\2\2\u028f"+ + "c\3\2\2\2\u0290\u0295\5f\64\2\u0291\u0292\t\7\2\2\u0292\u0294\5f\64\2"+ + "\u0293\u0291\3\2\2\2\u0294\u0297\3\2\2\2\u0295\u0293\3\2\2\2\u0295\u0296"+ + "\3\2\2\2\u0296e\3\2\2\2\u0297\u0295\3\2\2\2\u0298\u029d\5h\65\2\u0299"+ + "\u029a\t\b\2\2\u029a\u029c\5h\65\2\u029b\u0299\3\2\2\2\u029c\u029f\3\2"+ + "\2\2\u029d\u029b\3\2\2\2\u029d\u029e\3\2\2\2\u029eg\3\2\2\2\u029f\u029d"+ + "\3\2\2\2\u02a0\u02a4\5j\66\2\u02a1\u02a2\7b\2\2\u02a2\u02a3\7c\2\2\u02a3"+ + "\u02a5\5\u009eP\2\u02a4\u02a1\3\2\2\2\u02a4\u02a5\3\2\2\2\u02a5i\3\2\2"+ + "\2\u02a6\u02aa\5l\67\2\u02a7\u02a8\7e\2\2\u02a8\u02a9\7d\2\2\u02a9\u02ab"+ + "\5\u009eP\2\u02aa\u02a7\3\2\2\2\u02aa\u02ab\3\2\2\2\u02abk\3\2\2\2\u02ac"+ + "\u02b0\5n8\2\u02ad\u02ae\7f\2\2\u02ae\u02af\7H\2\2\u02af\u02b1\5\u009e"+ + "P\2\u02b0\u02ad\3\2\2\2\u02b0\u02b1\3\2\2\2\u02b1m\3\2\2\2\u02b2\u02b6"+ + "\5p9\2\u02b3\u02b4\7h\2\2\u02b4\u02b5\7H\2\2\u02b5\u02b7\5\u00aaV\2\u02b6"+ + "\u02b3\3\2\2\2\u02b6\u02b7\3\2\2\2\u02b7o\3\2\2\2\u02b8\u02bc\5r:\2\u02b9"+ + "\u02ba\7g\2\2\u02ba\u02bb\7H\2\2\u02bb\u02bd\5\u00aaV\2\u02bc\u02b9\3"+ + "\2\2\2\u02bc\u02bd\3\2\2\2\u02bdq\3\2\2\2\u02be\u02c5\5t;\2\u02bf\u02c0"+ + "\7\6\2\2\u02c0\u02c1\7.\2\2\u02c1\u02c2\3\2\2\2\u02c2\u02c4\5\u0092J\2"+ + "\u02c3\u02bf\3\2\2\2\u02c4\u02c7\3\2\2\2\u02c5\u02c3\3\2\2\2\u02c5\u02c6"+ + "\3\2\2\2\u02c6s\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c8\u02ca\t\7\2\2\u02c9"+ + "\u02c8\3\2\2\2\u02ca\u02cd\3\2\2\2\u02cb\u02c9\3\2\2\2\u02cb\u02cc\3\2"+ + "\2\2\u02cc\u02ce\3\2\2\2\u02cd\u02cb\3\2\2\2\u02ce\u02cf\5v<\2\u02cfu"+ + "\3\2\2\2\u02d0\u02d3\5z>\2\u02d1\u02d3\5x=\2\u02d2\u02d0\3\2\2\2\u02d2"+ + "\u02d1\3\2\2\2\u02d3w\3\2\2\2\u02d4\u02d5\7\66\2\2\u02d5\u02d6\7!\2\2"+ + "\u02d6\u02d7\5\u009eP\2\u02d7\u02d8\7\37\2\2\u02d8\u02d9\5,\27\2\u02d9"+ + "\u02da\7 \2\2\u02day\3\2\2\2\u02db\u02e0\5|?\2\u02dc\u02dd\7\67\2\2\u02dd"+ + "\u02df\5|?\2\u02de\u02dc\3\2\2\2\u02df\u02e2\3\2\2\2\u02e0\u02de\3\2\2"+ + "\2\u02e0\u02e1\3\2\2\2\u02e1{\3\2\2\2\u02e2\u02e0\3\2\2\2\u02e3\u02eb"+ + "\5\u0086D\2\u02e4\u02ea\5~@\2\u02e5\u02ea\5\u0082B\2\u02e6\u02ea\5\u0084"+ + "C\2\u02e7\u02ea\5\u0080A\2\u02e8\u02ea\5\u0094K\2\u02e9\u02e4\3\2\2\2"+ + "\u02e9\u02e5\3\2\2\2\u02e9\u02e6\3\2\2\2\u02e9\u02e7\3\2\2\2\u02e9\u02e8"+ + "\3\2\2\2\u02ea\u02ed\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ec\3\2\2\2\u02ec"+ + "}\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ee\u02ef\78\2\2\u02ef\u02f0\78\2\2\u02f0"+ + "\u02f1\5,\27\2\u02f1\u02f2\79\2\2\u02f2\u02f3\79\2\2\u02f3\177\3\2\2\2"+ + "\u02f4\u02f5\78\2\2\u02f5\u02f6\79\2\2\u02f6\u0081\3\2\2\2\u02f7\u02f8"+ + "\78\2\2\u02f8\u02f9\5,\27\2\u02f9\u02fa\79\2\2\u02fa\u0083\3\2\2\2\u02fb"+ + "\u0302\7:\2\2\u02fc\u0303\5\u00b4[\2\u02fd\u0303\5\u00b2Z\2\u02fe\u0303"+ + "\7u\2\2\u02ff\u0303\5\u008aF\2\u0300\u0303\5\u0088E\2\u0301\u0303\5\u008c"+ + "G\2\u0302\u02fc\3\2\2\2\u0302\u02fd\3\2\2\2\u0302\u02fe\3\2\2\2\u0302"+ + "\u02ff\3\2\2\2\u0302\u0300\3\2\2\2\u0302\u0301\3\2\2\2\u0303\u0085\3\2"+ + "\2\2\u0304\u0311\7m\2\2\u0305\u0311\7n\2\2\u0306\u0311\5\u00b2Z\2\u0307"+ + "\u0311\5\u0088E\2\u0308\u0311\5\u008aF\2\u0309\u0311\5\u008cG\2\u030a"+ + "\u0311\5\u00a0Q\2\u030b\u0311\5\u0092J\2\u030c\u0311\5\u008eH\2\u030d"+ + "\u0311\5\u0090I\2\u030e\u0311\5\u00aeX\2\u030f\u0311\5\u0098M\2\u0310"+ + "\u0304\3\2\2\2\u0310\u0305\3\2\2\2\u0310\u0306\3\2\2\2\u0310\u0307\3\2"+ + "\2\2\u0310\u0308\3\2\2\2\u0310\u0309\3\2\2\2\u0310\u030a\3\2\2\2\u0310"+ + "\u030b\3\2\2\2\u0310\u030c\3\2\2\2\u0310\u030d\3\2\2\2\u0310\u030e\3\2"+ + "\2\2\u0310\u030f\3\2\2\2\u0311\u0087\3\2\2\2\u0312\u0313\7\"\2\2\u0313"+ + "\u0314\5\32\16\2\u0314\u0089\3\2\2\2\u0315\u0317\7\35\2\2\u0316\u0318"+ + "\5,\27\2\u0317\u0316\3\2\2\2\u0317\u0318\3\2\2\2\u0318\u0319\3\2\2\2\u0319"+ + "\u031a\7\36\2\2\u031a\u008b\3\2\2\2\u031b\u031c\7;\2\2\u031c\u008d\3\2"+ + "\2\2\u031d\u031e\7\t\2\2\u031e\u031f\7\37\2\2\u031f\u0320\5,\27\2\u0320"+ + "\u0321\7 \2\2\u0321\u008f\3\2\2\2\u0322\u0323\7\n\2\2\u0323\u0324\7\37"+ + "\2\2\u0324\u0325\5,\27\2\u0325\u0326\7 \2\2\u0326\u0091\3\2\2\2\u0327"+ + "\u0328\5\32\16\2\u0328\u0329\5\u0094K\2\u0329\u0093\3\2\2\2\u032a\u0331"+ + "\7\35\2\2\u032b\u032d\5\u0096L\2\u032c\u032e\7\30\2\2\u032d\u032c\3\2"+ + "\2\2\u032d\u032e\3\2\2\2\u032e\u0330\3\2\2\2\u032f\u032b\3\2\2\2\u0330"+ + "\u0333\3\2\2\2\u0331\u032f\3\2\2\2\u0331\u0332\3\2\2\2\u0332\u0334\3\2"+ + "\2\2\u0333\u0331\3\2\2\2\u0334\u0335\7\36\2\2\u0335\u0095\3\2\2\2\u0336"+ + "\u0339\5.\30\2\u0337\u0339\7l\2\2\u0338\u0336\3\2\2\2\u0338\u0337\3\2"+ + "\2\2\u0339\u0097\3\2\2\2\u033a\u033d\5\u009aN\2\u033b\u033d\5\u009cO\2"+ + "\u033c\u033a\3\2\2\2\u033c\u033b\3\2\2\2\u033d\u0099\3\2\2\2\u033e\u033f"+ + "\5\32\16\2\u033f\u0340\7<\2\2\u0340\u0341\7n\2\2\u0341\u009b\3\2\2\2\u0342"+ + "\u0343\7\34\2\2\u0343\u0345\7\35\2\2\u0344\u0346\5(\25\2\u0345\u0344\3"+ + "\2\2\2\u0345\u0346\3\2\2\2\u0346\u0347\3\2\2\2\u0347\u034a\7\36\2\2\u0348"+ + "\u0349\7H\2\2\u0349\u034b\5\u009eP\2\u034a\u0348\3\2\2\2\u034a\u034b\3"+ + "\2\2\2\u034b\u034c\3\2\2\2\u034c\u034e\7\37\2\2\u034d\u034f\5,\27\2\u034e"+ + "\u034d\3\2\2\2\u034e\u034f\3\2\2\2\u034f\u0350\3\2\2\2\u0350\u0351\7 "+ + "\2\2\u0351\u009d\3\2\2\2\u0352\u0353\7\35\2\2\u0353\u035b\7\36\2\2\u0354"+ + "\u0358\5\u00a2R\2\u0355\u0359\7l\2\2\u0356\u0359\7$\2\2\u0357\u0359\7"+ + "\61\2\2\u0358\u0355\3\2\2\2\u0358\u0356\3\2\2\2\u0358\u0357\3\2\2\2\u0358"+ + "\u0359\3\2\2\2\u0359\u035b\3\2\2\2\u035a\u0352\3\2\2\2\u035a\u0354\3\2"+ + "\2\2\u035b\u009f\3\2\2\2\u035c\u0365\7\37\2\2\u035d\u0362\5\u00acW\2\u035e"+ + "\u035f\7\30\2\2\u035f\u0361\5\u00acW\2\u0360\u035e\3\2\2\2\u0361\u0364"+ + "\3\2\2\2\u0362\u0360\3\2\2\2\u0362\u0363\3\2\2\2\u0363\u0366\3\2\2\2\u0364"+ + "\u0362\3\2\2\2\u0365\u035d\3\2\2\2\u0365\u0366\3\2\2\2\u0366\u0367\3\2"+ + "\2\2\u0367\u036d\7 \2\2\u0368\u0369\7=\2\2\u0369\u036a\5,\27\2\u036a\u036b"+ + "\7>\2\2\u036b\u036d\3\2\2\2\u036c\u035c\3\2\2\2\u036c\u0368\3\2\2\2\u036d"+ + "\u00a1\3\2\2\2\u036e\u0372\5\32\16\2\u036f\u0372\7m\2\2\u0370\u0372\5"+ + "\u00a4S\2\u0371\u036e\3\2\2\2\u0371\u036f\3\2\2\2\u0371\u0370\3\2\2\2"+ + "\u0372\u00a3\3\2\2\2\u0373\u0376\5\u00a6T\2\u0374\u0376\5\u00a8U\2\u0375"+ + "\u0373\3\2\2\2\u0375\u0374\3\2\2\2\u0376\u00a5\3\2\2\2\u0377\u0378\7\34"+ + "\2\2\u0378\u0379\7\35\2\2\u0379\u037a\7$\2\2\u037a\u037b\7\36\2\2\u037b"+ + "\u00a7\3\2\2\2\u037c\u037d\7\34\2\2\u037d\u0386\7\35\2\2\u037e\u0383\5"+ + "\u009eP\2\u037f\u0380\7\30\2\2\u0380\u0382\5\u009eP\2\u0381\u037f\3\2"+ + "\2\2\u0382\u0385\3\2\2\2\u0383\u0381\3\2\2\2\u0383\u0384\3\2\2\2\u0384"+ + "\u0387\3\2\2\2\u0385\u0383\3\2\2\2\u0386\u037e\3\2\2\2\u0386\u0387\3\2"+ + "\2\2\u0387\u0388\3\2\2\2\u0388\u0389\7\36\2\2\u0389\u038a\7H\2\2\u038a"+ + "\u038b\5\u009eP\2\u038b\u00a9\3\2\2\2\u038c\u038e\5\u00a2R\2\u038d\u038f"+ + "\7l\2\2\u038e\u038d\3\2\2\2\u038e\u038f\3\2\2\2\u038f\u00ab\3\2\2\2\u0390"+ + "\u0393\5.\30\2\u0391\u0393\7u\2\2\u0392\u0390\3\2\2\2\u0392\u0391\3\2"+ + "\2\2\u0393\u0394\3\2\2\2\u0394\u0395\t\t\2\2\u0395\u0396\5.\30\2\u0396"+ + "\u00ad\3\2\2\2\u0397\u0399\78\2\2\u0398\u039a\5,\27\2\u0399\u0398\3\2"+ + "\2\2\u0399\u039a\3\2\2\2\u039a\u039b\3\2\2\2\u039b\u039c\79\2\2\u039c"+ + "\u00af\3\2\2\2\u039d\u039e\5\u00b2Z\2\u039e\u00b1\3\2\2\2\u039f\u03a0"+ + "\7k\2\2\u03a0\u00b3\3\2\2\2\u03a1\u03a2\t\n\2\2\u03a2\u00b5\3\2\2\2e\u00be"+ + "\u00c2\u00d2\u00d8\u00e0\u00e7\u00f2\u0108\u0110\u0115\u0118\u011c\u0127"+ + "\u0130\u0133\u013a\u0141\u0143\u014a\u014f\u0153\u0157\u0164\u016b\u0172"+ + "\u017c\u0180\u0188\u018a\u0196\u019c\u01a0\u01a4\u01af\u01b5\u01c4\u01ca"+ + "\u01ce\u01d2\u01d9\u01e0\u01e6\u01eb\u01ed\u01f1\u01f8\u01ff\u0208\u0214"+ + "\u021e\u022a\u022e\u0237\u023e\u0254\u0259\u025e\u0262\u026e\u0276\u027a"+ + "\u0281\u0288\u028e\u0295\u029d\u02a4\u02aa\u02b0\u02b6\u02bc\u02c5\u02cb"+ + "\u02d2\u02e0\u02e9\u02eb\u0302\u0310\u0317\u032d\u0331\u0338\u033c\u0345"+ + "\u034a\u034e\u0358\u035a\u0362\u0365\u036c\u0371\u0375\u0383\u0386\u038e"+ + "\u0392\u0399"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/org/rumbledb/parser/JsoniqVisitor.java b/src/main/java/org/rumbledb/parser/JsoniqVisitor.java index 9fcfac0333..18c0597d98 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqVisitor.java @@ -91,6 +91,12 @@ public interface JsoniqVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitQname(JsoniqParser.QnameContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#nCNameOrKeyWord}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNCNameOrKeyWord(JsoniqParser.NCNameOrKeyWordContext ctx); /** * Visit a parse tree produced by {@link JsoniqParser#dfPropertyName}. * @param ctx the parse tree From f6dca01d731baf2e216a9494598d23a5d5ecff42 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 17:02:57 +0200 Subject: [PATCH 091/142] allow unordered keyword. --- .../java/org/rumbledb/context/BuiltinFunctionCatalogue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index cf34dbda09..5311155886 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -622,7 +622,7 @@ private static BuiltinFunction createBuiltinFunction( new Name( Name.FN_NS, "fn", - "unorder" + "unordered" ), "item*", "item*", From ed17929da0fc4ae441fec76778d87e22547562e6 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 17:07:56 +0200 Subject: [PATCH 092/142] fix imports. --- .../context/BuiltinFunctionCatalogue.java | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 44713d21e5..243bf0d1c9 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -107,31 +107,7 @@ import org.rumbledb.runtime.functions.sequences.value.DeepEqualFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.DistinctValuesFunctionIterator; import org.rumbledb.runtime.functions.sequences.value.IndexOfFunctionIterator; -import org.rumbledb.runtime.functions.strings.CodepointEqualFunctionIterator; -import org.rumbledb.runtime.functions.strings.CodepointsToStringFunctionIterator; -import org.rumbledb.runtime.functions.strings.ConcatFunctionIterator; -import org.rumbledb.runtime.functions.strings.ContainsFunctionIterator; -import org.rumbledb.runtime.functions.strings.DefaultCollationFunctionIterator; -import org.rumbledb.runtime.functions.strings.EncodeForURIFunctionIterator; -import org.rumbledb.runtime.functions.strings.EndsWithFunctionIterator; -import org.rumbledb.runtime.functions.strings.LowerCaseFunctionIterator; -import org.rumbledb.runtime.functions.strings.MatchesFunctionIterator; -import org.rumbledb.runtime.functions.strings.NormalizeSpaceFunctionIterator; -import org.rumbledb.runtime.functions.strings.NormalizeUnicodeFunctionIterator; -import org.rumbledb.runtime.functions.strings.ReplaceFunctionIterator; -import org.rumbledb.runtime.functions.strings.ResolveURIFunctionIterator; -import org.rumbledb.runtime.functions.strings.SerializeFunctionIterator; -import org.rumbledb.runtime.functions.strings.StartsWithFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringJoinFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringLengthFunctionIterator; -import org.rumbledb.runtime.functions.strings.StringToCodepointsFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringAfterFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringBeforeFunctionIterator; -import org.rumbledb.runtime.functions.strings.SubstringFunctionIterator; -import org.rumbledb.runtime.functions.strings.TokenizeFunctionIterator; -import org.rumbledb.runtime.functions.strings.TranslateFunctionIterator; -import org.rumbledb.runtime.functions.strings.UpperCaseFunctionIterator; +import org.rumbledb.runtime.functions.strings.*; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.SequenceType; From 58ad89649f1483856e464b7359786193db156e84 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 17:29:48 +0200 Subject: [PATCH 093/142] fix RuntimeTests. --- .../context/BuiltinFunctionCatalogue.java | 3 ++- .../functions/io/CollectionFunctionIterator.java | 11 ++++------- .../cardinality/ExactlyOneIterator.java | 16 ++++++++++++---- .../strings/StringJoinFunctionIterator.java | 6 ++---- .../Aggregate/AggregateMaxDF1.jq | 2 +- .../Aggregate/AggregateMinDF1.jq | 2 +- .../Cardinality/FunctionZeroOrOneDF1.jq | 2 +- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 5311155886..1722fc1b39 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -1300,7 +1300,8 @@ private static BuiltinFunction createBuiltinFunction( BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); /** - * function that returns a string created by concatenating the items in a sequence, with an optional defined separator between adjacent items. + * function that returns a string created by concatenating the items in a sequence, with an optional defined + * separator between adjacent items. */ static final BuiltinFunction string_join1 = createBuiltinFunction( new Name( diff --git a/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java index c485ae7b77..f39dafa2af 100644 --- a/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/io/CollectionFunctionIterator.java @@ -1,15 +1,11 @@ package org.rumbledb.runtime.functions.io; import org.apache.spark.sql.DataFrameReader; -import org.apache.spark.sql.Dataset; -import org.apache.spark.sql.Row; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.CannotRetrieveResourceException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.ObjectItem; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.DataFrameRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -24,16 +20,17 @@ public class CollectionFunctionIterator extends DataFrameRuntimeIterator { public CollectionFunctionIterator( List children, ExecutionMode executionMode, - ExceptionMetadata iteratorMetadata) { + ExceptionMetadata iteratorMetadata + ) { super(children, executionMode, iteratorMetadata); } - //TODO: implement collection function + // TODO: implement collection function @Override public JSoundDataFrame getDataFrame(DynamicContext context) { Item stringItem = this.children.get(0) - .materializeFirstItemOrNull(context); + .materializeFirstItemOrNull(context); String url = stringItem.getStringValue(); URI uri = FileSystemUtil.resolveURI(this.staticURI, url, getMetadata()); if (!FileSystemUtil.exists(uri, context.getRumbleRuntimeConfiguration(), getMetadata())) { diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java index 1bf28c2bb6..0536c7665a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java @@ -47,15 +47,23 @@ public ExactlyOneIterator( @Override public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { - Item value = this.children.get(0).materializeFirstItemOrNull(dynamicContext); - if (value == null) { + try { + Item value = this.children.get(0).materializeAtMostOneItemOrNull(dynamicContext); + if (value == null) { + throw new SequenceExceptionExactlyOne( + "fn:exactly-one() called with a sequence that doesn't contain exactly one item", + getMetadata() + ); + + } + return value; + } catch (MoreThanOneItemException e) { throw new SequenceExceptionExactlyOne( "fn:exactly-one() called with a sequence that doesn't contain exactly one item", getMetadata() ); - } - return value; + } @Override diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java index fffcc01ba1..376b5c49c0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java @@ -24,13 +24,11 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.functions.base.LocalFunctionCallIterator; import java.util.List; @@ -70,8 +68,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } JavaRDD strings = this.children.get(0).getRDD(context); StringBuilder stringBuilder = new StringBuilder(); - //Item finalJoinString = joinString; - //strings.map(item -> stringBuilder.append(constructor(stringBuilder, item, finalJoinString))); + // Item finalJoinString = joinString; + // strings.map(item -> stringBuilder.append(constructor(stringBuilder, item, finalJoinString))); for (Item item : strings.collect()) { if (!(item.isString())) { throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq index 454adda5e0..d4c7bc8bb7 100644 --- a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq +++ b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMaxDF1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(100)" :) +(:JIQS: ShouldRun; Output="100" :) let $x := annotate( for $i in 1 to 100 return {"foo":$i, "bar":($i+1)}, diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq index 8a84729080..0e34c284b2 100644 --- a/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq +++ b/src/test/resources/test_files/runtime/FunctionSequence/Aggregate/AggregateMinDF1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(1)" :) +(:JIQS: ShouldRun; Output="1" :) let $x := annotate( for $i in 1 to 100 return {"foo":$i, "bar":($i+1)}, diff --git a/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq index 85f97b449b..ae461211fb 100644 --- a/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq +++ b/src/test/resources/test_files/runtime/FunctionSequence/Cardinality/FunctionZeroOrOneDF1.jq @@ -1,3 +1,3 @@ -(:JIQS: ShouldRun; Output="(1)" :) +(:JIQS: ShouldRun; Output="1" :) zero-or-one(annotate(parallelize(1 to 1) ! { "foo" : $$ cast as int }, { "foo" : "double" }).foo) From 811faf9d8c1bd14c14c02df1a20922c24b8e413b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 20:17:52 +0200 Subject: [PATCH 094/142] dateTimeStamp Facet + adapt two tests. --- .../rumbledb/runtime/typing/CastIterator.java | 19 +++++++++++-------- .../rumbledb/types/BuiltinTypesCatalogue.java | 2 +- src/main/java/org/rumbledb/types/Facets.java | 6 ++++++ .../NamedFunctionRef-Error4.jq | 2 +- .../NamedFunctionRef-Error5.jq | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index e0a024b2f4..149905a093 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -296,15 +296,18 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } if (targetType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); - } - if (item.isDate()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); - } - if (item.isDateTime()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); + if (item.hasTimeZone()) { + if (item.isString()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); + } + if (item.isDate()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); + } + if (item.isDateTime()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); + } } + return null; } if (targetType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { if (item.isString()) { diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 89b2679f38..eb29c0b104 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -159,7 +159,7 @@ public class BuiltinTypesCatalogue { new Name(Name.XS_NS, "xs", "dateTimeStamp"), dateTimeItem, AtomicItemType.dateTimeItem, - new Facets(), + Facets.createTimezoneFacets(TimezoneFacet.REQUIRED), false, DataTypes.DateType ); diff --git a/src/main/java/org/rumbledb/types/Facets.java b/src/main/java/org/rumbledb/types/Facets.java index 29596689a8..d62fbba2b6 100644 --- a/src/main/java/org/rumbledb/types/Facets.java +++ b/src/main/java/org/rumbledb/types/Facets.java @@ -52,6 +52,12 @@ public static Facets createMaxFacets(Item max, boolean isInclusive) { return facets; } + public static Facets createTimezoneFacets(TimezoneFacet explicitTimezone) { + Facets facets = new Facets(); + facets.setExplicitTimezone(explicitTimezone); + return facets; + } + private Item minInclusive, maxInclusive; private Item minExclusive, maxExclusive; private Integer minLength, length, maxLength, totalDigits, fractionDigits; diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq index 5eeff54f61..0e63e3309e 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPDY0130"; :) asd#true (: using non-integer literals for arity :) diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq index ed7c8e767a..3863682d98 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPDY0130"; :) asd#.9 (: using non-integer literals for arity :) From 79a5c88ad2461984651ceee5421a9d0d5631375e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 19:17:03 +0000 Subject: [PATCH 095/142] Update ZeroOrOneIterator.java --- .../functions/sequences/cardinality/ZeroOrOneIterator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java index d122bd52de..5b894c39d0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java @@ -27,6 +27,7 @@ import org.rumbledb.exceptions.MoreThanOneItemException; import org.rumbledb.exceptions.SequenceExceptionZeroOrOne; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; From 25890d07e6fdd8ac574759002fc0632024f66555 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 13 Jul 2021 21:59:13 +0200 Subject: [PATCH 096/142] fix tests. --- .../java/org/rumbledb/items/DateTimeItem.java | 4 +++- .../rumbledb/runtime/typing/CastIterator.java | 18 ++++++++---------- .../NamedFunctionRef-Error4.jq | 2 +- .../NamedFunctionRef-Error5.jq | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/rumbledb/items/DateTimeItem.java b/src/main/java/org/rumbledb/items/DateTimeItem.java index 8fd0dfa70b..513150c3ca 100644 --- a/src/main/java/org/rumbledb/items/DateTimeItem.java +++ b/src/main/java/org/rumbledb/items/DateTimeItem.java @@ -42,10 +42,12 @@ public class DateTimeItem implements Item { + "))"; private static final String dateTimeLexicalRep = dateFrag + "T" + timeFrag + "(" + timezoneFrag + ")?"; + private static final String dateTimeStampLexicalRep = dateFrag + "T" + timeFrag + timezoneFrag; private static final String dateLexicalRep = "(" + dateFrag + "(" + timezoneFrag + ")?)"; private static final String timeLexicalRep = "(" + timeFrag + "(" + timezoneFrag + ")?)"; private static final Pattern dateTimePattern = Pattern.compile(dateTimeLexicalRep); + private static final Pattern dateTimeStampPattern = Pattern.compile(dateTimeStampLexicalRep); private static final Pattern datePattern = Pattern.compile(dateLexicalRep); private static final Pattern timePattern = Pattern.compile(timeLexicalRep); @@ -173,7 +175,7 @@ static DateTimeFormatter getDateTimeFormatter(ItemType dateTimeType) { static boolean checkInvalidDateTimeFormat(String dateTime, ItemType dateTimeType) { if (dateTimeType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { - return dateTimePattern.matcher(dateTime).matches(); + return dateTimeStampPattern.matcher(dateTime).matches(); } if (dateTimeType.equals(BuiltinTypesCatalogue.dateTimeItem)) { return dateTimePattern.matcher(dateTime).matches(); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 149905a093..ff3bdf87e2 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -296,16 +296,14 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } if (targetType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { - if (item.hasTimeZone()) { - if (item.isString()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); - } - if (item.isDate()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); - } - if (item.isDateTime()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); - } + if (item.isString()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); + } + if (item.isDate()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); + } + if (item.isDateTime()) { + return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); } return null; } diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq index 0e63e3309e..5eeff54f61 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldNotParse; ErrorCode="XPDY0130"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) asd#true (: using non-integer literals for arity :) diff --git a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq index 3863682d98..ed7c8e767a 100644 --- a/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq +++ b/src/test/resources/test_files/runtime/FunctionUserDefinedDynamic/NamedFunctionRef-Error5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldNotParse; ErrorCode="XPDY0130"; :) +(:JIQS: ShouldNotParse; ErrorCode="XPST0003"; :) asd#.9 (: using non-integer literals for arity :) From b14758199d11da86540ba605d45440f3eba5b1c3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 14 Jul 2021 07:43:31 +0200 Subject: [PATCH 097/142] string-join rdd not better than local. --- .../strings/StringJoinFunctionIterator.java | 32 ++----------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java index 376b5c49c0..5a392acfde 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java @@ -50,27 +50,10 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (this.children.size() > 1) { joinString = this.children.get(1).materializeFirstItemOrNull(context); } - if (!this.children.get(0).isRDDOrDataFrame()) { - List strings = this.children.get(0).materialize(context); + List strings = this.children.get(0).materialize(context); - - StringBuilder stringBuilder = new StringBuilder(); - for (Item item : strings) { - if (!(item.isString())) { - throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); - } - if (!stringBuilder.toString().isEmpty()) { - stringBuilder.append(joinString.getStringValue()); - } - stringBuilder.append(item.getStringValue()); - } - return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); - } - JavaRDD strings = this.children.get(0).getRDD(context); StringBuilder stringBuilder = new StringBuilder(); - // Item finalJoinString = joinString; - // strings.map(item -> stringBuilder.append(constructor(stringBuilder, item, finalJoinString))); - for (Item item : strings.collect()) { + for (Item item : strings) { if (!(item.isString())) { throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); } @@ -79,18 +62,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } stringBuilder.append(item.getStringValue()); } + return ItemFactory.getInstance().createStringItem(stringBuilder.toString()); } - private String constructor(StringBuilder stringBuilder, Item item, Item joinString) { - if (!(item.isString())) { - throw new UnexpectedTypeException("String item expected", this.children.get(0).getMetadata()); - } - if (!stringBuilder.toString().isEmpty()) { - return joinString.getStringValue().concat(item.getStringValue()); - } - return item.getStringValue(); - } - } From 00ff45cd21401da60eaae210925afa0c08c87a75 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 16 Jul 2021 16:15:03 +0200 Subject: [PATCH 098/142] serialize -0 and fix rounding issues. --- .../java/org/rumbledb/items/DoubleItem.java | 12 ++-- .../java/org/rumbledb/items/FloatItem.java | 8 +-- .../java/org/rumbledb/items/ItemFactory.java | 16 +++++ .../java/org/rumbledb/items/StringItem.java | 3 + .../numerics/CeilingFunctionIterator.java | 18 +++-- .../numerics/FloorFunctionIterator.java | 16 ++++- .../numerics/RoundFunctionIterator.java | 44 +++++++++--- .../RoundHalfToEvenFunctionIterator.java | 20 ++++-- .../rumbledb/runtime/typing/CastIterator.java | 72 ++++++++++++++----- 9 files changed, 163 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/rumbledb/items/DoubleItem.java b/src/main/java/org/rumbledb/items/DoubleItem.java index aa512344ba..49f05857da 100644 --- a/src/main/java/org/rumbledb/items/DoubleItem.java +++ b/src/main/java/org/rumbledb/items/DoubleItem.java @@ -38,7 +38,7 @@ public class DoubleItem implements Item { private static final long serialVersionUID = 1L; - private double value; + private Double value; public DoubleItem() { super(); @@ -70,7 +70,7 @@ public double getDoubleValue() { @Override public String getStringValue() { - return String.valueOf(this.value); + return this.serialize(); } @Override @@ -85,7 +85,7 @@ public double castToDoubleValue() { @Override public float castToFloatValue() { - return (float) this.value; + return this.value.floatValue(); } public BigDecimal castToDecimalValue() { @@ -119,12 +119,12 @@ public String serialize() { if (Double.isInfinite(this.value) && this.value < 0) { return "-INF"; } - if (Double.compare(this.value, 0d) == 0) { - return "0"; - } if (Double.compare(this.value, -0d) == 0) { return "-0"; } + if (Double.compare(this.value, 0d) == 0) { + return "0"; + } double abs = Math.abs(this.value); if (abs >= 0.000001 && abs <= 1000000) { return this.castToDecimalValue().stripTrailingZeros().toPlainString(); diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index d80732c6e1..48e1bc99ad 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -74,7 +74,7 @@ public boolean getEffectiveBooleanValue() { @Override public String getStringValue() { - return String.valueOf(this.value); + return this.serialize(); } @Override @@ -118,12 +118,12 @@ public String serialize() { if (Float.isInfinite(this.value) && this.value < 0) { return "-INF"; } - if (Float.compare(this.value, 0f) == 0) { - return "0"; - } if (Float.compare(this.value, -0f) == 0) { return "-0"; } + if (Float.compare(this.value, 0f) == 0) { + return "0"; + } double abs = Math.abs(this.value); // Mantissa from less or equal than 1.0E-7 if (abs >= 0.000001 && abs < 1000000) { diff --git a/src/main/java/org/rumbledb/items/ItemFactory.java b/src/main/java/org/rumbledb/items/ItemFactory.java index fd210d95b0..602b166d1a 100644 --- a/src/main/java/org/rumbledb/items/ItemFactory.java +++ b/src/main/java/org/rumbledb/items/ItemFactory.java @@ -4,6 +4,7 @@ import org.joda.time.Period; import org.rumbledb.api.Item; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.ItemType; import java.math.BigDecimal; @@ -21,6 +22,9 @@ public class ItemFactory { private Item positiveInfinityDoubleItem; private Item negativeInfinityDoubleItem; private Item NaNDoubleItem; + private Item positiveInfinityFloatItem; + private Item negativeInfinityFloatItem; + private Item NaNFloatItem; public static ItemFactory getInstance() { if (instance == null) { @@ -32,6 +36,9 @@ public static ItemFactory getInstance() { instance.positiveInfinityDoubleItem = new DoubleItem(Double.POSITIVE_INFINITY); instance.negativeInfinityDoubleItem = new DoubleItem(Double.NEGATIVE_INFINITY); instance.NaNDoubleItem = new DoubleItem(Double.NaN); + instance.positiveInfinityFloatItem = new FloatItem(Float.POSITIVE_INFINITY); + instance.negativeInfinityFloatItem = new FloatItem(Float.NEGATIVE_INFINITY); + instance.NaNFloatItem = new FloatItem(Float.NaN); } return instance; } @@ -94,6 +101,15 @@ public Item createDoubleItem(double d) { } public Item createFloatItem(float d) { + if (d == Float.POSITIVE_INFINITY) { + return this.positiveInfinityFloatItem; + } + if (d == Float.NEGATIVE_INFINITY) { + return this.negativeInfinityFloatItem; + } + if (d == Float.NaN) { + return this.NaNFloatItem; + } return new FloatItem(d); } diff --git a/src/main/java/org/rumbledb/items/StringItem.java b/src/main/java/org/rumbledb/items/StringItem.java index 0b9f2180d6..4e1953d1ee 100644 --- a/src/main/java/org/rumbledb/items/StringItem.java +++ b/src/main/java/org/rumbledb/items/StringItem.java @@ -97,6 +97,9 @@ public float castToFloatValue() { if (trimmedValue.equals("NaN")) { return Float.NaN; } + if (trimmedValue.startsWith("-") && Float.parseFloat(this.getValue()) == -0f) { + return -0f; + } return Float.parseFloat(this.getValue()); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java index 58ec68618f..03b0b575c0 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java @@ -52,6 +52,13 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } + if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + return value; + } + if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + return value; + } + if (value.isInt()) { return ItemFactory.getInstance().createIntItem(value.getIntValue()); } @@ -63,15 +70,18 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createDecimalItem(bd); } if (value.isFloat()) { - BigDecimal bd = new BigDecimal(value.getFloatValue()); - bd = bd.setScale(0, RoundingMode.CEILING); - return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + return ItemFactory.getInstance() + .createFloatItem( + (float) Math.ceil( + value.getFloatValue() + ) + ); } if (value.isDouble()) { return ItemFactory.getInstance() .createDoubleItem( Math.ceil( - value.castToDoubleValue() + value.getDoubleValue() ) ); } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index 44fcddacbb..c829ee7b58 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -54,6 +54,13 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } + if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + return value; + } + if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + return value; + } + if (value.isInt()) { return ItemFactory.getInstance().createIntItem(value.getIntValue()); } @@ -65,9 +72,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createDecimalItem(bd); } if (value.isFloat()) { - BigDecimal bd = new BigDecimal(value.getFloatValue()); - bd = bd.setScale(0, RoundingMode.FLOOR); - return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + return ItemFactory.getInstance() + .createFloatItem( + (float) Math.floor( + value.getFloatValue() + ) + ); } if (value.isDouble()) { return ItemFactory.getInstance() 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 78c60deb98..d05e808461 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java @@ -26,6 +26,7 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.DoubleItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -54,13 +55,13 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { if (value == null) { return null; } - if (value.isDouble() && Double.isNaN(value.getDoubleValue())) { + if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { return value; } - if (value.isDouble() && Double.isInfinite(value.getDoubleValue())) { + if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { return value; } - if (value.isDouble() && value.getDoubleValue() == 0d) { + if ((value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0))) { return value; } int precision; @@ -83,16 +84,36 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { return ItemFactory.getInstance().createIntegerItem(bd.toBigInteger()); } if (value.isDecimal()) { - BigDecimal bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_UP); + double sign = getSign(value.getDecimalValue().doubleValue()); + BigDecimal bd; + if (sign ==1) { + bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_UP); + } else { + bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_DOWN); + } return ItemFactory.getInstance().createDecimalItem(bd); } if (value.isDouble()) { - BigDecimal bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_UP); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + double sign = getSign(value.getDoubleValue()); + BigDecimal bd; + if (sign ==1) { + bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_UP); + } else { + bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_DOWN); + } + + return ItemFactory.getInstance().createDoubleItem(sign * Math.abs(bd.doubleValue())); } if (value.isFloat()) { - BigDecimal bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_UP); - return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + + double sign = getSign(value.getFloatValue()); + BigDecimal bd; + if (sign ==1) { + bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_UP); + } else { + bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_DOWN); + } + return ItemFactory.getInstance().createFloatItem((float) sign * Math.abs(bd.floatValue())); } throw new UnexpectedTypeException("Unexpected value in round(): " + value.getDynamicType(), getMetadata()); @@ -101,6 +122,13 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { } } + private double getSign(double doubleValue) { + double sign = 0; + if (doubleValue > 0) sign = 1; + if (doubleValue < 0) sign = -1; + return sign; + } + @Override public NativeClauseContext generateNativeQuery(NativeClauseContext nativeClauseContext) { NativeClauseContext value = this.children.get(0).generateNativeQuery(nativeClauseContext); diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index f63d79b019..ca04e424d6 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -31,6 +31,7 @@ import org.rumbledb.runtime.RuntimeIterator; import java.math.BigDecimal; +import java.math.BigInteger; import java.math.RoundingMode; import java.util.List; @@ -53,13 +54,13 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - if (value.isDouble() && Double.isNaN(value.getDoubleValue())) { + if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { return value; } - if (value.isDouble() && Double.isInfinite(value.getDoubleValue())) { + if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { return value; } - if (value.isDouble() && value.getDoubleValue() == 0d) { + if ((value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0))) { return value; } @@ -87,12 +88,14 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createDecimalItem(bd); } if (value.isDouble()) { + double sign = getSign(value.getDoubleValue()); BigDecimal bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createDoubleItem(bd.doubleValue()); + return ItemFactory.getInstance().createDoubleItem(sign * Math.abs(bd.doubleValue())); } if (value.isFloat()) { + double sign = getSign(value.getFloatValue()); BigDecimal bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_EVEN); - return ItemFactory.getInstance().createFloatItem(bd.floatValue()); + return ItemFactory.getInstance().createFloatItem((float) sign * Math.abs(bd.floatValue())); } throw new UnexpectedTypeException( "Unexpected value in round-half-to-even(): " + value.getDynamicType(), @@ -106,5 +109,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } + private double getSign(double doubleValue) { + double sign = 0; + if (doubleValue > 0) sign = 1; + if (doubleValue < 0) sign = -1; + return sign; + } + } diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index ff3bdf87e2..5e884b13c7 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -12,6 +12,7 @@ import org.rumbledb.exceptions.UnknownCastTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; +import org.rumbledb.items.IntItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -146,7 +147,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isFloat()) { return ItemFactory.getInstance().createBooleanItem(item.getFloatValue() != 0); } - return null; } if (targetType.equals(BuiltinTypesCatalogue.doubleItem)) { @@ -159,7 +159,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); } - return null; } if (targetType.equals(BuiltinTypesCatalogue.floatItem)) { if (item.isString()) { @@ -171,7 +170,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createFloatItem(item.castToFloatValue()); } - return null; } if (targetType.equals(BuiltinTypesCatalogue.decimalItem)) { @@ -185,33 +183,33 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad if (item.isNumeric()) { return ItemFactory.getInstance().createDecimalItem(item.castToDecimalValue()); } - return null; } - if (targetType.equals(BuiltinTypesCatalogue.integerItem)) { if (item.isString()) { - return ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()); + return checkFacetsInteger(ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), targetType, false); } if (item.isBoolean()) { return ItemFactory.getInstance() .createIntegerItem(item.getBooleanValue() ? BigInteger.ONE : BigInteger.ZERO); } if (item.isNumeric()) { - return ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()); + return checkFacetsInteger(ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), targetType, false); } - return null; } if (targetType.equals(BuiltinTypesCatalogue.intItem)) { if (item.isString()) { - return ItemFactory.getInstance().createIntItem(item.castToIntValue()); + return checkFacetsInt(ItemFactory.getInstance().createIntItem(item.castToIntValue()), targetType, false); } if (item.isBoolean()) { return ItemFactory.getInstance() .createIntItem(item.getBooleanValue() ? 1 : 0); } if (item.isNumeric()) { - return ItemFactory.getInstance().createIntItem(item.castToIntValue()); + Item checkedItem = checkFacetsInteger(item, targetType, false); + if (checkedItem != null) { + return ItemFactory.getInstance().createIntItem(checkedItem.castToIntValue()); + } } return null; } @@ -246,14 +244,14 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return null; } if (item.isInt()) { - return checkFacetsInt(item, targetType); + return checkFacetsInt(item, targetType, true); } Item intItem = castItemToType(item, BuiltinTypesCatalogue.intItem, metadata); if (intItem == null) { return null; } - return checkFacetsInt(intItem, targetType); + return checkFacetsInt(intItem, targetType, true); } if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { @@ -261,14 +259,14 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return null; } if (item.isInteger()) { - return checkFacetsInteger(item, targetType); + return checkFacetsInteger(item, targetType, true); } Item integerItem = castItemToType(item, BuiltinTypesCatalogue.integerItem, metadata); if (integerItem == null) { return null; } - return checkFacetsInteger(integerItem, targetType); + return checkFacetsInteger(integerItem, targetType, true); } if (targetType.equals(BuiltinTypesCatalogue.dateItem)) { @@ -396,7 +394,49 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } } - public static Item checkFacetsInt(Item item, ItemType targetType) { + public static Item checkFacetsInt(Item item, ItemType targetType, boolean annotated) { + if ( + (targetType.getMinInclusiveFacet() != null + && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntValue() > targetType.getMaxInclusiveFacet().getIntValue()) + || (targetType.getMinExclusiveFacet() != null + && item.getIntValue() <= targetType.getMinExclusiveFacet().getIntValue()) + || (targetType.getMaxExclusiveFacet() != null + && item.getIntValue() <= targetType.getMaxExclusiveFacet().getIntValue()) + ) { + return null; + } + if (annotated) { + return ItemFactory.getInstance().createAnnotatedItem(item, targetType); + } + return item; + } + + public static Item checkFacetsInteger(Item item, ItemType targetType, boolean annotated) { + if ( + (targetType.getMinInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMaxInclusiveFacet().getIntegerValue()) == 1) + || (targetType.getMinExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) + || (targetType.getMaxExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) + ) { + return null; + } + + if (annotated) { + return ItemFactory.getInstance().createAnnotatedItem(item, targetType); + } + return item; + + } + + public static Item checkAnnotatedFacetsInt(Item item, ItemType targetType) { if ( (targetType.getMinInclusiveFacet() != null && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) @@ -413,7 +453,7 @@ public static Item checkFacetsInt(Item item, ItemType targetType) { return ItemFactory.getInstance().createAnnotatedItem(item, targetType); } - public static Item checkFacetsInteger(Item item, ItemType targetType) { + public static Item checkAnnotatedFacetsInteger(Item item, ItemType targetType) { if ( (targetType.getMinInclusiveFacet() != null && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) From 30ad1e202c8e216d2a6f74d6b98066786aff5b7e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 13:17:35 +0200 Subject: [PATCH 099/142] Fix comparison with NaN --- .../org/rumbledb/items/ItemComparator.java | 14 +++++++++++ .../aggregate/MaxFunctionIterator.java | 22 ++++++++++++++---- .../aggregate/MinFunctionIterator.java | 23 +++++++++++++++---- .../runtime/misc/ComparisonIterator.java | 16 +++++++++++++ 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/rumbledb/items/ItemComparator.java b/src/main/java/org/rumbledb/items/ItemComparator.java index 28553b6110..b3d6cb021c 100644 --- a/src/main/java/org/rumbledb/items/ItemComparator.java +++ b/src/main/java/org/rumbledb/items/ItemComparator.java @@ -35,11 +35,17 @@ public class ItemComparator implements Comparator, Serializable { private static final long serialVersionUID = 1L; private RumbleException exception; + private boolean compareMin = false; public ItemComparator(RumbleException exception) { this.exception = exception; } + public ItemComparator(boolean compareMin, RumbleException exception) { + this.compareMin = compareMin; + this.exception = exception; + } + /** * Comparator used for sequence aggregate functions and their RDD evaluations * It compares 2 atomic items (non-null) @@ -48,6 +54,14 @@ public ItemComparator(RumbleException exception) { * @return -1 if v1 < v2; 0 if v1 == v2; 1 if v1 > v2; */ public int compare(Item v1, Item v2) { + if (this.compareMin) { + if ((v1.isDouble() && Double.isNaN(v1.getDoubleValue())) || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) { + return -1; + } + if ((v2.isDouble() && Double.isNaN(v2.getDoubleValue())) || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) { + return 1; + } + } try { long comparison = ComparisonIterator.compareItems( v1, diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index d8feb43ed9..4d5a9a2808 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -30,6 +30,7 @@ import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -60,6 +61,7 @@ public MaxFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { ItemComparator comparator = new ItemComparator( + false, new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types", getMetadata() @@ -80,7 +82,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } try { - return Collections.max(results, comparator); + return itemTypePromotion(Collections.max(results, comparator)); } catch (RumbleException e) { RumbleException ex = new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types.", @@ -105,16 +107,15 @@ public Item materializeFirstItemOrNull(DynamicContext context) { ), df.getItemType() ); - return maxDF.getExactlyOneItem(); + return itemTypePromotion(maxDF.getExactlyOneItem()); } JavaRDD rdd = this.iterator.getRDD(context); if (rdd.isEmpty()) { return null; } - this.result = rdd.max(comparator); - return this.result; + return itemTypePromotion(this.result); } @@ -129,4 +130,17 @@ public Map getVariableDependencies() { return super.getVariableDependencies(); } } + + private Item itemTypePromotion(Item item) { + if (item.isAnyURI()) { + return ItemFactory.getInstance().createStringItem(item.getStringValue()); + } + if (item.isFloat()) { + return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + } + if (item.isDecimal()) { + return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + } + return item; + } } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index b88f80cc9c..694e34b3c7 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -30,6 +30,7 @@ import org.rumbledb.exceptions.RumbleException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -60,6 +61,7 @@ public MinFunctionIterator( @Override public Item materializeFirstItemOrNull(DynamicContext context) { ItemComparator comparator = new ItemComparator( + true, new InvalidArgumentTypeException( "Min expression input error. Input has to be non-null atomics of matching types", getMetadata() @@ -80,7 +82,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } try { - return Collections.min(results, comparator); + return itemTypePromotion(Collections.min(results, comparator)); } catch (RumbleException e) { RumbleException ex = new InvalidArgumentTypeException( "Min expression input error. Input has to be non-null atomics of matching types.", @@ -105,16 +107,15 @@ public Item materializeFirstItemOrNull(DynamicContext context) { ), df.getItemType() ); - return minDF.getExactlyOneItem(); + return itemTypePromotion(minDF.getExactlyOneItem()); } JavaRDD rdd = this.iterator.getRDD(context); if (rdd.isEmpty()) { return null; } - this.result = rdd.min(comparator); - return this.result; + return itemTypePromotion(this.result); } @@ -130,4 +131,18 @@ public Map getVariableDependencies() { return super.getVariableDependencies(); } } + + private Item itemTypePromotion(Item item) { + if (item.isAnyURI()) { + return ItemFactory.getInstance().createStringItem(item.getStringValue()); + } + if (item.isFloat()) { + return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + } + if (item.isDecimal()) { + return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + } + return item; + } + } diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 2a66f1cfb2..a50f319133 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -198,6 +198,16 @@ private Item valueComparison(Item left, Item right) { .getInstance() .createBooleanItem(false); } + if (left.isFloat() && Float.isNaN(left.getFloatValue())) { + return ItemFactory + .getInstance() + .createBooleanItem(false); + } + if (right.isFloat() && Float.isNaN(right.getFloatValue())) { + return ItemFactory + .getInstance() + .createBooleanItem(false); + } return comparisonResultToBooleanItem( (int) comparison, this.comparisonOperator, @@ -220,6 +230,12 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } + if ((left.isDouble() && Double.isNaN(left.getDoubleValue())) || (left.isFloat() && Float.isNaN(left.getFloatValue()))) { + return 1; + } + if ((right.isDouble() && Double.isNaN(right.getDoubleValue())) || (right.isFloat() && Float.isNaN(right.getFloatValue()))) { + return -1; + } if ( left.isInt() && right.isInt() From 33ee01cfa26df238f774ef79b461af27c246c7a3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 14:34:46 +0200 Subject: [PATCH 100/142] spotless. --- .../java/org/rumbledb/items/ItemFactory.java | 1 - .../numerics/CeilingFunctionIterator.java | 20 ++++++++----- .../numerics/FloorFunctionIterator.java | 20 ++++++++----- .../numerics/RoundFunctionIterator.java | 28 +++++++++++++------ .../RoundHalfToEvenFunctionIterator.java | 22 +++++++++++---- .../strings/StringJoinFunctionIterator.java | 1 - 6 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/rumbledb/items/ItemFactory.java b/src/main/java/org/rumbledb/items/ItemFactory.java index 602b166d1a..e4be0edbe1 100644 --- a/src/main/java/org/rumbledb/items/ItemFactory.java +++ b/src/main/java/org/rumbledb/items/ItemFactory.java @@ -4,7 +4,6 @@ import org.joda.time.Period; import org.rumbledb.api.Item; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.ItemType; import java.math.BigDecimal; diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java index 03b0b575c0..2a0335c7e7 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/CeilingFunctionIterator.java @@ -52,10 +52,16 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isNaN(value.getDoubleValue())) + || (value.isFloat() && Float.isNaN(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isInfinite(value.getDoubleValue())) + || (value.isFloat() && Float.isInfinite(value.getFloatValue())) + ) { return value; } @@ -71,11 +77,11 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } if (value.isFloat()) { return ItemFactory.getInstance() - .createFloatItem( - (float) Math.ceil( - value.getFloatValue() - ) - ); + .createFloatItem( + (float) Math.ceil( + value.getFloatValue() + ) + ); } if (value.isDouble()) { return ItemFactory.getInstance() diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java index c829ee7b58..6c4398bdf1 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/FloorFunctionIterator.java @@ -54,10 +54,16 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isNaN(value.getDoubleValue())) + || (value.isFloat() && Float.isNaN(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isInfinite(value.getDoubleValue())) + || (value.isFloat() && Float.isInfinite(value.getFloatValue())) + ) { return value; } @@ -73,11 +79,11 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } if (value.isFloat()) { return ItemFactory.getInstance() - .createFloatItem( - (float) Math.floor( - value.getFloatValue() - ) - ); + .createFloatItem( + (float) Math.floor( + value.getFloatValue() + ) + ); } if (value.isDouble()) { return ItemFactory.getInstance() 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 d05e808461..3d9c8a3547 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundFunctionIterator.java @@ -26,7 +26,6 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.exceptions.UnexpectedTypeException; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.DoubleItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -55,13 +54,22 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { if (value == null) { return null; } - if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isNaN(value.getDoubleValue())) + || (value.isFloat() && Float.isNaN(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isInfinite(value.getDoubleValue())) + || (value.isFloat() && Float.isInfinite(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0))) { + if ( + (value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 + || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0)) + ) { return value; } int precision; @@ -86,7 +94,7 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { if (value.isDecimal()) { double sign = getSign(value.getDecimalValue().doubleValue()); BigDecimal bd; - if (sign ==1) { + if (sign == 1) { bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_UP); } else { bd = value.getDecimalValue().setScale(precision, RoundingMode.HALF_DOWN); @@ -96,7 +104,7 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { if (value.isDouble()) { double sign = getSign(value.getDoubleValue()); BigDecimal bd; - if (sign ==1) { + if (sign == 1) { bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_UP); } else { bd = new BigDecimal(value.getDoubleValue()).setScale(precision, RoundingMode.HALF_DOWN); @@ -108,7 +116,7 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { double sign = getSign(value.getFloatValue()); BigDecimal bd; - if (sign ==1) { + if (sign == 1) { bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_UP); } else { bd = new BigDecimal(value.getFloatValue()).setScale(precision, RoundingMode.HALF_DOWN); @@ -124,8 +132,10 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { private double getSign(double doubleValue) { double sign = 0; - if (doubleValue > 0) sign = 1; - if (doubleValue < 0) sign = -1; + if (doubleValue > 0) + sign = 1; + if (doubleValue < 0) + sign = -1; return sign; } diff --git a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java index ca04e424d6..b37a192844 100644 --- a/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/numerics/RoundHalfToEvenFunctionIterator.java @@ -31,7 +31,6 @@ import org.rumbledb.runtime.RuntimeIterator; import java.math.BigDecimal; -import java.math.BigInteger; import java.math.RoundingMode; import java.util.List; @@ -54,13 +53,22 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (value == null) { return null; } - if ((value.isDouble() && Double.isNaN(value.getDoubleValue())) || (value.isFloat() && Float.isNaN(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isNaN(value.getDoubleValue())) + || (value.isFloat() && Float.isNaN(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.isInfinite(value.getDoubleValue())) || (value.isFloat() && Float.isInfinite(value.getFloatValue()))) { + if ( + (value.isDouble() && Double.isInfinite(value.getDoubleValue())) + || (value.isFloat() && Float.isInfinite(value.getFloatValue())) + ) { return value; } - if ((value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0))) { + if ( + (value.isDouble() && Double.compare(value.getDoubleValue(), -0d) == 0 + || (value.isFloat() && Float.compare(value.getFloatValue(), -0f) == 0)) + ) { return value; } @@ -111,8 +119,10 @@ public Item materializeFirstItemOrNull(DynamicContext context) { private double getSign(double doubleValue) { double sign = 0; - if (doubleValue > 0) sign = 1; - if (doubleValue < 0) sign = -1; + if (doubleValue > 0) + sign = 1; + if (doubleValue < 0) + sign = -1; return sign; } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java index 5a392acfde..08ca254a63 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java @@ -20,7 +20,6 @@ package org.rumbledb.runtime.functions.strings; -import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; From e3ae8e49689673f1b58a72f5db3b27959e8c969f Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 14:35:50 +0200 Subject: [PATCH 101/142] fix cast decimal to int. --- .../rumbledb/runtime/typing/CastIterator.java | 59 ++++++++++++------- .../test_files/runtime/CastAnnotated.jq | 6 +- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 5e884b13c7..3f9e3178c3 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -12,7 +12,7 @@ import org.rumbledb.exceptions.UnknownCastTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; -import org.rumbledb.items.IntItem; +import org.rumbledb.items.IntegerItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -186,26 +186,41 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } if (targetType.equals(BuiltinTypesCatalogue.integerItem)) { if (item.isString()) { - return checkFacetsInteger(ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), targetType, false); + return checkFacetsInteger( + ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), + targetType, + false + ); } if (item.isBoolean()) { return ItemFactory.getInstance() .createIntegerItem(item.getBooleanValue() ? BigInteger.ONE : BigInteger.ZERO); } if (item.isNumeric()) { - return checkFacetsInteger(ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), targetType, false); + return checkFacetsInteger( + ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), + targetType, + false + ); } } if (targetType.equals(BuiltinTypesCatalogue.intItem)) { if (item.isString()) { - return checkFacetsInt(ItemFactory.getInstance().createIntItem(item.castToIntValue()), targetType, false); + return checkFacetsInt( + ItemFactory.getInstance().createIntItem(item.castToIntValue()), + targetType, + false + ); } if (item.isBoolean()) { return ItemFactory.getInstance() .createIntItem(item.getBooleanValue() ? 1 : 0); } if (item.isNumeric()) { + if (item.isDecimal()) { + item = new IntegerItem(item.castToIntegerValue()); + } Item checkedItem = checkFacetsInteger(item, targetType, false); if (checkedItem != null) { return ItemFactory.getInstance().createIntItem(checkedItem.castToIntValue()); @@ -396,14 +411,14 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad public static Item checkFacetsInt(Item item, ItemType targetType, boolean annotated) { if ( - (targetType.getMinInclusiveFacet() != null - && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) - || (targetType.getMaxInclusiveFacet() != null - && item.getIntValue() > targetType.getMaxInclusiveFacet().getIntValue()) - || (targetType.getMinExclusiveFacet() != null - && item.getIntValue() <= targetType.getMinExclusiveFacet().getIntValue()) - || (targetType.getMaxExclusiveFacet() != null - && item.getIntValue() <= targetType.getMaxExclusiveFacet().getIntValue()) + (targetType.getMinInclusiveFacet() != null + && item.getIntValue() < targetType.getMinInclusiveFacet().getIntValue()) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntValue() > targetType.getMaxInclusiveFacet().getIntValue()) + || (targetType.getMinExclusiveFacet() != null + && item.getIntValue() <= targetType.getMinExclusiveFacet().getIntValue()) + || (targetType.getMaxExclusiveFacet() != null + && item.getIntValue() <= targetType.getMaxExclusiveFacet().getIntValue()) ) { return null; } @@ -415,16 +430,16 @@ public static Item checkFacetsInt(Item item, ItemType targetType, boolean annota public static Item checkFacetsInteger(Item item, ItemType targetType, boolean annotated) { if ( - (targetType.getMinInclusiveFacet() != null - && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) - || (targetType.getMaxInclusiveFacet() != null - && item.getIntegerValue().compareTo(targetType.getMaxInclusiveFacet().getIntegerValue()) == 1) - || (targetType.getMinExclusiveFacet() != null - && - item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) - || (targetType.getMaxExclusiveFacet() != null - && - item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) + (targetType.getMinInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMinInclusiveFacet().getIntegerValue()) == -1) + || (targetType.getMaxInclusiveFacet() != null + && item.getIntegerValue().compareTo(targetType.getMaxInclusiveFacet().getIntegerValue()) == 1) + || (targetType.getMinExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMinExclusiveFacet().getIntegerValue()) <= 0) + || (targetType.getMaxExclusiveFacet() != null + && + item.getIntegerValue().compareTo(targetType.getMaxExclusiveFacet().getIntegerValue()) >= 0) ) { return null; } diff --git a/src/test/resources/test_files/runtime/CastAnnotated.jq b/src/test/resources/test_files/runtime/CastAnnotated.jq index 32a782474b..fc4a5ea05a 100644 --- a/src/test/resources/test_files/runtime/CastAnnotated.jq +++ b/src/test/resources/test_files/runtime/CastAnnotated.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(2, 10, -32, -21, 127, 3456, 0, -2, 1000)" :) +(:JIQS: ShouldRun; Output="(2, 10, -32, -21, 127, 3456, 0, -2, 1000, 14)" :) xs:positiveInteger("2"), xs:positiveInteger(10), xs:long(-32), @@ -7,4 +7,6 @@ xs:byte(127), xs:unsignedShort(3456), unsignedInt(0), xs:negativeInteger(-2.8), -xs:short(1000.99) +xs:short(1000.99), +xs:positiveInteger(14.2) + From eaaaf6c24c1ac80006154f64e875154dd8dca4c8 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 14:36:06 +0200 Subject: [PATCH 102/142] fix wrong expected output round. --- .../test_files/runtime/FunctionNumerics/FunctionRound1.jq | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq index c9ee9082b7..0cc2c49bb6 100644 --- a/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq +++ b/src/test/resources/test_files/runtime/FunctionNumerics/FunctionRound1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="(3, 2, -3, 1.13, 8500, 3.14, NaN, INF, -INF, 0, -0)" :) +(:JIQS: ShouldRun; Output="(3, 2, -2, 1.13, 8500, 3.14, NaN, INF, -INF, 0, -0)" :) fn:round(2.5), round(2.4999), round(-2.5), From f30467fca8f8d44ecc751447d7f7c8bd805dd6b9 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 15:03:20 +0200 Subject: [PATCH 103/142] spotless. --- .../org/rumbledb/items/ItemComparator.java | 10 ++++++++-- .../strings/StringJoinFunctionIterator.java | 1 - .../runtime/misc/ComparisonIterator.java | 18 ++++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/rumbledb/items/ItemComparator.java b/src/main/java/org/rumbledb/items/ItemComparator.java index b3d6cb021c..a4b6cfba39 100644 --- a/src/main/java/org/rumbledb/items/ItemComparator.java +++ b/src/main/java/org/rumbledb/items/ItemComparator.java @@ -55,10 +55,16 @@ public ItemComparator(boolean compareMin, RumbleException exception) { */ public int compare(Item v1, Item v2) { if (this.compareMin) { - if ((v1.isDouble() && Double.isNaN(v1.getDoubleValue())) || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) { + if ( + (v1.isDouble() && Double.isNaN(v1.getDoubleValue())) + || (v1.isFloat() && Float.isNaN(v1.getFloatValue())) + ) { return -1; } - if ((v2.isDouble() && Double.isNaN(v2.getDoubleValue())) || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) { + if ( + (v2.isDouble() && Double.isNaN(v2.getDoubleValue())) + || (v2.isFloat() && Float.isNaN(v2.getFloatValue())) + ) { return 1; } } diff --git a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java index 5a392acfde..08ca254a63 100644 --- a/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/strings/StringJoinFunctionIterator.java @@ -20,7 +20,6 @@ package org.rumbledb.runtime.functions.strings; -import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index a50f319133..20f7c46ba5 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -200,13 +200,13 @@ private Item valueComparison(Item left, Item right) { } if (left.isFloat() && Float.isNaN(left.getFloatValue())) { return ItemFactory - .getInstance() - .createBooleanItem(false); + .getInstance() + .createBooleanItem(false); } if (right.isFloat() && Float.isNaN(right.getFloatValue())) { return ItemFactory - .getInstance() - .createBooleanItem(false); + .getInstance() + .createBooleanItem(false); } return comparisonResultToBooleanItem( (int) comparison, @@ -230,10 +230,16 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } - if ((left.isDouble() && Double.isNaN(left.getDoubleValue())) || (left.isFloat() && Float.isNaN(left.getFloatValue()))) { + if ( + (left.isDouble() && Double.isNaN(left.getDoubleValue())) + || (left.isFloat() && Float.isNaN(left.getFloatValue())) + ) { return 1; } - if ((right.isDouble() && Double.isNaN(right.getDoubleValue())) || (right.isFloat() && Float.isNaN(right.getFloatValue()))) { + if ( + (right.isDouble() && Double.isNaN(right.getDoubleValue())) + || (right.isFloat() && Float.isNaN(right.getFloatValue())) + ) { return -1; } if ( From 074adf620b6b01714161fd5ba81109f28da7f6f7 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 15:06:37 +0200 Subject: [PATCH 104/142] fix float precision MLPipeline tests. --- .../resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq index 62d29dfd5d..e7c8ed4b91 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.019540421813566, 37.019540421813566 ], "probability" : [ 8.367926795070004E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856415582, -37.84452856415582 ], "probability" : [ 1, 3.667161819676691E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.2860939487717079, 1.1822492465709793 ], "rawPrediction" : [ -18.53660987378621, 18.53660987378621 ], "probability" : [ 8.905383257302129E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) let $vector-assembler := get-transformer("VectorAssembler") let $training-data := ( {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq index 4466476be8..0043895037 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.019540421813645, 37.019540421813645 ], "probability" : [ 8.36792679506935E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856415555, -37.84452856415555 ], "probability" : [ 1, 3.6671618196776806E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.2860939487717079, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873786368, 18.536609873786368 ], "probability" : [ 8.905383257300736E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) let $training-data := ( {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq index 3204b05df9..22ec9c789a 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838128 ], "rawPrediction" : [ -37.01954042181356, 37.01954042181356 ], "probability" : [ 8.367926795070064E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197546 ], "rawPrediction" : [ 37.84452856415591, -37.84452856415591 ], "probability" : [ 1, 3.667161819676378E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873786183, 18.536609873786183 ], "probability" : [ 8.905383257302382E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) declare type local:mytype as { "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq index 520c307381..488ef60dd5 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983225814, 43.28021983225814 ], "probability" : [ 1.598230268069814E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563755981074, -27.129563755981074 ], "probability" : [ 0.9999999999983489, 1.6511258027506401E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.544453548692445, 41.544453548692445 ], "probability" : [ 9.067197386481577E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq index 297bb024ea..0a767a5f03 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021951991732, 43.28021951991732 ], "probability" : [ 1.5982307672624502E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129564163157283, -27.129564163157283 ], "probability" : [ 0.9999999999983489, 1.651125130451632E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.544453088801276, 41.544453088801276 ], "probability" : [ 9.067201556406539E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq index f2bbe8ed97..f8ee0a25ef 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.2802198436369, 43.2802198436369 ], "probability" : [ 1.5982302498839368E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563760791896, -27.129563760791896 ], "probability" : [ 0.9999999999983489, 1.6511257948073681E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445356013767, 41.54445356013767 ], "probability" : [ 9.067197282705476E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $pipeline := get-estimator("Pipeline", { From d9377ff8c07655d09ab75556b7d18c7d50ff705d Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 15:06:37 +0200 Subject: [PATCH 105/142] Revert "fix float precision MLPipeline tests." This reverts commit 074adf620b6b01714161fd5ba81109f28da7f6f7. --- .../resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq | 2 +- .../resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq index e7c8ed4b91..62d29dfd5d 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.019540421813566, 37.019540421813566 ], "probability" : [ 8.367926795070004E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856415582, -37.84452856415582 ], "probability" : [ 1, 3.667161819676691E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.2860939487717079, 1.1822492465709793 ], "rawPrediction" : [ -18.53660987378621, 18.53660987378621 ], "probability" : [ 8.905383257302129E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) let $vector-assembler := get-transformer("VectorAssembler") let $training-data := ( {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq index 0043895037..4466476be8 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.019540421813645, 37.019540421813645 ], "probability" : [ 8.36792679506935E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856415555, -37.84452856415555 ], "probability" : [ 1, 3.6671618196776806E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.2860939487717079, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873786368, 18.536609873786368 ], "probability" : [ 8.905383257300736E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) let $training-data := ( {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq index 22ec9c789a..3204b05df9 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838128 ], "rawPrediction" : [ -37.01954042181356, 37.01954042181356 ], "probability" : [ 8.367926795070064E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197546 ], "rawPrediction" : [ 37.84452856415591, -37.84452856415591 ], "probability" : [ 1, 3.667161819676378E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873786183, 18.536609873786183 ], "probability" : [ 8.905383257302382E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) declare type local:mytype as { "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq index 488ef60dd5..520c307381 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983225814, 43.28021983225814 ], "probability" : [ 1.598230268069814E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563755981074, -27.129563755981074 ], "probability" : [ 0.9999999999983489, 1.6511258027506401E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.544453548692445, 41.544453548692445 ], "probability" : [ 9.067197386481577E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq index 0a767a5f03..297bb024ea 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021951991732, 43.28021951991732 ], "probability" : [ 1.5982307672624502E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129564163157283, -27.129564163157283 ], "probability" : [ 0.9999999999983489, 1.651125130451632E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.544453088801276, 41.544453088801276 ], "probability" : [ 9.067201556406539E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq index f8ee0a25ef..f2bbe8ed97 100644 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq @@ -1,4 +1,4 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.2802198436369, 43.2802198436369 ], "probability" : [ 1.5982302498839368E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563760791896, -27.129563760791896 ], "probability" : [ 0.9999999999983489, 1.6511257948073681E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445356013767, 41.54445356013767 ], "probability" : [ 9.067197282705476E-19, 1 ], "prediction" : 1 })" :) +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; let $pipeline := get-estimator("Pipeline", { From aa7cb814c0043bec57647ac682867dfb5b116e77 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sun, 18 Jul 2021 22:44:44 +0200 Subject: [PATCH 106/142] revert MLPipeline changes. Improve float mantissa handling. --- src/main/java/org/rumbledb/items/FloatItem.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index 48e1bc99ad..d439bfd7ce 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -125,19 +125,19 @@ public String serialize() { return "0"; } double abs = Math.abs(this.value); - // Mantissa from less or equal than 1.0E-7 + // Convert to decimal between 10E-7 to 10E6 if (abs >= 0.000001 && abs < 1000000) { return new BigDecimal(this.value).toString(); } - // Mantissa already from 1.0E6, then let Float.toString take care of mantissa from 1.0E7 - if (abs >= 1000000 && abs < 10000000) { - return new DecimalFormat("0.0#######E0").format(this.value); - // return String.format("%.4E", this.castToDecimalValue().stripTrailingZeros().toPlainString()); + // Force mantissa between 10E6 and 10E7 + if (abs < 100000000) { + String str = Float.toString(this.value*10); + char reducedChar = (char) ((int) str.charAt(str.length()-1) - 1); + StringBuilder sb = new StringBuilder(str.substring(0, str.length()-1)).append(reducedChar); + return sb.toString(); } - // If less than 0.000001 must use mantissa, so from 0.0000001 = 1.0E-7 - // If more or = than 1.0E6 - // When use float.toString or not return Float.toString(this.value); + } @Override From 757b81ff1059d8d52bbc8a2068a6d852b830f340 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 15:43:22 +0200 Subject: [PATCH 107/142] Annotated support in DFs. Type test. --- .../rumbledb/items/parsing/ItemParser.java | 12 +- .../rumbledb/types/BuiltinTypesCatalogue.java | 18 +-- .../runtime-native-flwor/udt/type6.jq | 104 ++++++++++++++++++ 3 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 src/test/resources/test_files/runtime-native-flwor/udt/type6.jq diff --git a/src/main/java/org/rumbledb/items/parsing/ItemParser.java b/src/main/java/org/rumbledb/items/parsing/ItemParser.java index da40ea6a7d..449ae75bc7 100644 --- a/src/main/java/org/rumbledb/items/parsing/ItemParser.java +++ b/src/main/java/org/rumbledb/items/parsing/ItemParser.java @@ -21,6 +21,7 @@ package org.rumbledb.items.parsing; import org.apache.commons.codec.binary.Hex; +import org.apache.parquet.format.IntType; import org.apache.spark.ml.linalg.DenseVector; import org.apache.spark.ml.linalg.SparseVector; import org.apache.spark.ml.linalg.Vector; @@ -350,7 +351,7 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.dateItem)) { return DataTypes.DateType; } - if (itemType.equals(BuiltinTypesCatalogue.dateTimeItem)) { + if (itemType.equals(BuiltinTypesCatalogue.dateTimeItem) || itemType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { return DataTypes.TimestampType; } if (itemType.equals(BuiltinTypesCatalogue.hexBinaryItem)) { @@ -359,6 +360,15 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.objectItem)) { return vectorType; } + if (itemType.equals(BuiltinTypesCatalogue.positiveIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonNegativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.negativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonPositiveIntegerItem)) { + return DataTypes.IntegerType; + } + if (itemType.equals(BuiltinTypesCatalogue.unsignedByteItem) || itemType.equals(BuiltinTypesCatalogue.unsignedLongItem) || itemType.equals(BuiltinTypesCatalogue.unsignedShortItem) || itemType.equals(BuiltinTypesCatalogue.unsignedIntItem)) { + return DataTypes.IntegerType; + } + if (itemType.equals(BuiltinTypesCatalogue.intItem) || itemType.equals(BuiltinTypesCatalogue.byteItem) || itemType.equals(BuiltinTypesCatalogue.shortItem)) { + return DataTypes.IntegerType; + } throw new IllegalArgumentException( "Unexpected item type found: '" + itemType + "' in namespace " + itemType.getName().getNamespace() + "." ); diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 5010ab94d5..675a6495c5 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -348,7 +348,7 @@ public class BuiltinTypesCatalogue { DataTypes.ShortType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "byte"), intItem, AtomicItemType.decimalItem, @@ -357,7 +357,7 @@ public class BuiltinTypesCatalogue { DataTypes.ByteType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType nonNegativeIntegerItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType nonNegativeIntegerItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "nonNegativeInteger"), integerItem, AtomicItemType.decimalItem, @@ -369,7 +369,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType nonPositiveIntegerItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType nonPositiveIntegerItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "nonPositiveInteger"), integerItem, AtomicItemType.decimalItem, @@ -381,7 +381,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType negativeIntegerItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType negativeIntegerItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "negativeInteger"), nonPositiveIntegerItem, AtomicItemType.decimalItem, @@ -393,7 +393,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType positiveIntegerItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType positiveIntegerItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "positiveInteger"), nonNegativeIntegerItem, AtomicItemType.decimalItem, @@ -405,7 +405,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedInt"), integerItem, AtomicItemType.decimalItem, @@ -418,7 +418,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedLong"), integerItem, AtomicItemType.decimalItem, @@ -431,7 +431,7 @@ public class BuiltinTypesCatalogue { DataTypes.LongType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedShort"), integerItem, AtomicItemType.decimalItem, @@ -440,7 +440,7 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( + public static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedByte"), integerItem, AtomicItemType.decimalItem, diff --git a/src/test/resources/test_files/runtime-native-flwor/udt/type6.jq b/src/test/resources/test_files/runtime-native-flwor/udt/type6.jq new file mode 100644 index 0000000000..b44bd4956d --- /dev/null +++ b/src/test/resources/test_files/runtime-native-flwor/udt/type6.jq @@ -0,0 +1,104 @@ +(:JIQS: ShouldRun; Output="({ "foo" : 1 }, { "foo" : 300 }, { }, true, true, true, true, true, true, Success, Success, Success, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, { }, Success, Success, 1000000, { "foo" : [ 2 ] }, { "foo" : [ 3, 4 ] }, Success, Success)" :) +declare type local:x as { "foo" : "positiveInteger" }; +declare type local:y as { "foo" : [ "byte" ] }; +declare type local:z as { "foo" : [ "nonPositiveInteger" ] }; +declare type local:w as { "foo" : "unsignedByte", "bar" : "unsignedLong" }; +validate type local:x* { + { "foo" : 1 }, + { "foo" : 300 }, + { } +}, +validate type local:x* { + { "foo" : 2 }, + { "foo" : 3 }, + { } +} instance of local:x+, +(validate type local:x* { + { "foo" : 2 }, + { "foo" : 3 }, + { } +}).foo instance of positiveInteger+, +(validate type local:y+ { parallelize(( + { "foo" : [ -128 ] }, + { "foo" : [ 11, 127 ] }, + { "foo" : [ ] }, + { } +))}).foo[] instance of byte+, +(validate type local:y+ { + { "foo" : [ -128 ] }, + { "foo" : [ 3, 127 ] }, + { "foo" : [ ] }, + { } +}).foo instance of array*, +(validate type local:z+ { + { "foo" : [ -1000008 ] }, + { "foo" : [ -10, -1 ] }, + { "foo" : [ ] }, + { } +}).foo[] instance of nonPositiveInteger+, +(validate type local:w* { + { "foo" : 2, "bar" : 3 } + } +).bar instance of unsignedLong+, +try { + validate type local:x* { + { "foo" : "string" } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:z* { + { "foo" : 1 } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:x* { + [ "foo" ] + } +} catch XQDY0027 { + "Success" +}, +validate type local:y* { + { "foo" : [ 2 ] }, + { "foo" : [ 3, 4 ] }, + { } +}, +try { + validate type local:y* { + { "foo" : 2 } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:y* { + { "foo" : { "bar" : "foo" } } + } +} catch XQDY0027 { + "Success" +}, +(validate type local:w* { + { "foo" : -2, "bar": -123456789 }, + { "foo" : 129, "bar": 1000000 } +}).bar[2], +validate type local:z* { + { "foo" : [ 2 ] }, + { "foo" : [ 3, 4 ] } +}, +try { + validate type local:z* { + { "foo" : { "bar" : "foo" } } + } +} catch XQDY0027 { + "Success" +}, +try { + validate type local:w* { + { "foo" : [ "foo" ], "bar": 12345 } + } +} catch XQDY0027 { + "Success" +} From 42a778aa5da29e8358970a8c6337b0aded224672 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 19:47:40 +0200 Subject: [PATCH 108/142] Throw error if compare invalid types, even if contain NaN. --- src/main/java/org/rumbledb/items/ItemComparator.java | 12 ++++++------ .../rumbledb/runtime/misc/ComparisonIterator.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/rumbledb/items/ItemComparator.java b/src/main/java/org/rumbledb/items/ItemComparator.java index a4b6cfba39..ea991f9359 100644 --- a/src/main/java/org/rumbledb/items/ItemComparator.java +++ b/src/main/java/org/rumbledb/items/ItemComparator.java @@ -55,15 +55,15 @@ public ItemComparator(boolean compareMin, RumbleException exception) { */ public int compare(Item v1, Item v2) { if (this.compareMin) { - if ( - (v1.isDouble() && Double.isNaN(v1.getDoubleValue())) - || (v1.isFloat() && Float.isNaN(v1.getFloatValue())) + if (v2.isNumeric() && + ((v1.isDouble() && Double.isNaN(v1.getDoubleValue())) + || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) ) { return -1; } - if ( - (v2.isDouble() && Double.isNaN(v2.getDoubleValue())) - || (v2.isFloat() && Float.isNaN(v2.getFloatValue())) + if (v1.isNumeric() && + ((v2.isDouble() && Double.isNaN(v2.getDoubleValue())) + || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) ) { return 1; } diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 20f7c46ba5..7269b9cfef 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -230,15 +230,15 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } - if ( - (left.isDouble() && Double.isNaN(left.getDoubleValue())) - || (left.isFloat() && Float.isNaN(left.getFloatValue())) + if (right.isNumeric() && + ((left.isDouble() && Double.isNaN(left.getDoubleValue())) + || (left.isFloat() && Float.isNaN(left.getFloatValue()))) ) { return 1; } - if ( - (right.isDouble() && Double.isNaN(right.getDoubleValue())) - || (right.isFloat() && Float.isNaN(right.getFloatValue())) + if (left.isNumeric() && + ((right.isDouble() && Double.isNaN(right.getDoubleValue())) + || (right.isFloat() && Float.isNaN(right.getFloatValue()))) ) { return -1; } From b001506a9250066088a31b6220277098a0d9f8b0 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 20:19:26 +0200 Subject: [PATCH 109/142] fix deep-equal annotated items. spotless. --- .../org/rumbledb/items/AnnotatedItem.java | 17 ++++++++++++ .../org/rumbledb/items/ItemComparator.java | 12 ++++++--- .../rumbledb/items/parsing/ItemParser.java | 26 +++++++++++++++---- .../value/DeepEqualFunctionIterator.java | 1 - .../runtime/misc/ComparisonIterator.java | 12 ++++++--- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/rumbledb/items/AnnotatedItem.java b/src/main/java/org/rumbledb/items/AnnotatedItem.java index 058a4d3691..d5ce1f8082 100644 --- a/src/main/java/org/rumbledb/items/AnnotatedItem.java +++ b/src/main/java/org/rumbledb/items/AnnotatedItem.java @@ -10,9 +10,12 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; +import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.ItemType; @@ -37,6 +40,20 @@ public AnnotatedItem(Item itemToAnnotate, ItemType type) { this.type = type; } + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof AnnotatedItem) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + @Override public void write(Kryo kryo, Output output) { this.itemToAnnotate.write(kryo, output); diff --git a/src/main/java/org/rumbledb/items/ItemComparator.java b/src/main/java/org/rumbledb/items/ItemComparator.java index ea991f9359..1f134e576d 100644 --- a/src/main/java/org/rumbledb/items/ItemComparator.java +++ b/src/main/java/org/rumbledb/items/ItemComparator.java @@ -55,15 +55,19 @@ public ItemComparator(boolean compareMin, RumbleException exception) { */ public int compare(Item v1, Item v2) { if (this.compareMin) { - if (v2.isNumeric() && + if ( + v2.isNumeric() + && ((v1.isDouble() && Double.isNaN(v1.getDoubleValue())) - || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) + || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) ) { return -1; } - if (v1.isNumeric() && + if ( + v1.isNumeric() + && ((v2.isDouble() && Double.isNaN(v2.getDoubleValue())) - || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) + || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) ) { return 1; } diff --git a/src/main/java/org/rumbledb/items/parsing/ItemParser.java b/src/main/java/org/rumbledb/items/parsing/ItemParser.java index 449ae75bc7..a8c9d8187b 100644 --- a/src/main/java/org/rumbledb/items/parsing/ItemParser.java +++ b/src/main/java/org/rumbledb/items/parsing/ItemParser.java @@ -21,7 +21,6 @@ package org.rumbledb.items.parsing; import org.apache.commons.codec.binary.Hex; -import org.apache.parquet.format.IntType; import org.apache.spark.ml.linalg.DenseVector; import org.apache.spark.ml.linalg.SparseVector; import org.apache.spark.ml.linalg.Vector; @@ -351,7 +350,10 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.dateItem)) { return DataTypes.DateType; } - if (itemType.equals(BuiltinTypesCatalogue.dateTimeItem) || itemType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.dateTimeItem) + || itemType.equals(BuiltinTypesCatalogue.dateTimeStampItem) + ) { return DataTypes.TimestampType; } if (itemType.equals(BuiltinTypesCatalogue.hexBinaryItem)) { @@ -360,13 +362,27 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.objectItem)) { return vectorType; } - if (itemType.equals(BuiltinTypesCatalogue.positiveIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonNegativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.negativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonPositiveIntegerItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.positiveIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.nonNegativeIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.negativeIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.nonPositiveIntegerItem) + ) { return DataTypes.IntegerType; } - if (itemType.equals(BuiltinTypesCatalogue.unsignedByteItem) || itemType.equals(BuiltinTypesCatalogue.unsignedLongItem) || itemType.equals(BuiltinTypesCatalogue.unsignedShortItem) || itemType.equals(BuiltinTypesCatalogue.unsignedIntItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.unsignedByteItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedLongItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedShortItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedIntItem) + ) { return DataTypes.IntegerType; } - if (itemType.equals(BuiltinTypesCatalogue.intItem) || itemType.equals(BuiltinTypesCatalogue.byteItem) || itemType.equals(BuiltinTypesCatalogue.shortItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.intItem) + || itemType.equals(BuiltinTypesCatalogue.byteItem) + || itemType.equals(BuiltinTypesCatalogue.shortItem) + ) { return DataTypes.IntegerType; } throw new IllegalArgumentException( diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 7c7b18b729..0b22c8734a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -96,7 +96,6 @@ public boolean checkDeepEqual(List items1, List items2) { for (int i = 0; i < items1.size(); i++) { Item item1 = items1.get(i); Item item2 = items2.get(i); - if (!item1.equals(item2)) { return false; } diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 7269b9cfef..886a312b5a 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -230,15 +230,19 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } - if (right.isNumeric() && + if ( + right.isNumeric() + && ((left.isDouble() && Double.isNaN(left.getDoubleValue())) - || (left.isFloat() && Float.isNaN(left.getFloatValue()))) + || (left.isFloat() && Float.isNaN(left.getFloatValue()))) ) { return 1; } - if (left.isNumeric() && + if ( + left.isNumeric() + && ((right.isDouble() && Double.isNaN(right.getDoubleValue())) - || (right.isFloat() && Float.isNaN(right.getFloatValue()))) + || (right.isFloat() && Float.isNaN(right.getFloatValue()))) ) { return -1; } From 0cd6662acad5c8561194bc10c4f08c327df81b46 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 23:43:37 +0200 Subject: [PATCH 110/142] True False functions. --- .../context/BuiltinFunctionCatalogue.java | 22 ++++++++ src/main/java/org/rumbledb/parser/Jsoniq.g4 | 6 +++ .../booleans/FalseFunctionIterator.java | 50 +++++++++++++++++++ .../booleans/TrueFunctionIterator.java | 30 +++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/functions/booleans/FalseFunctionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/functions/booleans/TrueFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index b7e73269ff..55a660728b 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -11,7 +11,9 @@ import org.rumbledb.runtime.functions.arrays.ArrayMembersFunctionIterator; import org.rumbledb.runtime.functions.arrays.ArraySizeFunctionIterator; import org.rumbledb.runtime.functions.booleans.BooleanFunctionIterator; +import org.rumbledb.runtime.functions.booleans.FalseFunctionIterator; import org.rumbledb.runtime.functions.booleans.NotFunctionIterator; +import org.rumbledb.runtime.functions.booleans.TrueFunctionIterator; import org.rumbledb.runtime.functions.context.LastFunctionIterator; import org.rumbledb.runtime.functions.context.PositionFunctionIterator; import org.rumbledb.runtime.functions.datetime.CurrentDateFunctionIterator; @@ -535,6 +537,24 @@ private static BuiltinFunction createBuiltinFunction( NotFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns true. + */ + static final BuiltinFunction true_function = createBuiltinFunction( + new Name(Name.FN_NS, "fn", "true"), + "boolean", + TrueFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); + /** + * function that returns false. + */ + static final BuiltinFunction false_function = createBuiltinFunction( + new Name(Name.FN_NS, "fn", "false"), + "boolean", + FalseFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the minimum of a sequence @@ -2511,6 +2531,8 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(count.getIdentifier(), count); builtinFunctions.put(boolean_function.getIdentifier(), boolean_function); builtinFunctions.put(not_function.getIdentifier(), not_function); + builtinFunctions.put(true_function.getIdentifier(), true_function); + builtinFunctions.put(false_function.getIdentifier(), false_function); builtinFunctions.put(min1.getIdentifier(), min1); builtinFunctions.put(min2.getIdentifier(), min2); diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index b336d4a6bf..4e69dd965e 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -297,6 +297,8 @@ keyWords : Kjsoniq | Kcount | Kreturn | Kunordered + | Ktrue + | Kfalse ; ///////////////////////// literals @@ -391,6 +393,10 @@ Kjsoniq : 'jsoniq'; Kunordered : 'unordered'; +Ktrue : 'true'; + +Kfalse : 'false'; + STRING : '"' (ESC | ~ ["\\])* '"'; fragment ESC : '\\' (["\\/bfnrt] | UNICODE); diff --git a/src/main/java/org/rumbledb/runtime/functions/booleans/FalseFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/booleans/FalseFunctionIterator.java new file mode 100644 index 0000000000..4ca6cab487 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/booleans/FalseFunctionIterator.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.runtime.functions.booleans; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class FalseFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public FalseFunctionIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createBooleanItem(false); + } + +} diff --git a/src/main/java/org/rumbledb/runtime/functions/booleans/TrueFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/booleans/TrueFunctionIterator.java new file mode 100644 index 0000000000..fdc48f24cc --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/booleans/TrueFunctionIterator.java @@ -0,0 +1,30 @@ +package org.rumbledb.runtime.functions.booleans; + +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class TrueFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + + public TrueFunctionIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + return ItemFactory.getInstance().createBooleanItem(true); + } + +} From 6cd0b645a41b677ba40a5c3820aa6162943a809e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 23:43:55 +0200 Subject: [PATCH 111/142] Forbid 0000 gyear. --- src/main/java/org/rumbledb/items/gYearItem.java | 3 +++ src/main/java/org/rumbledb/items/gYearMonthItem.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/org/rumbledb/items/gYearItem.java b/src/main/java/org/rumbledb/items/gYearItem.java index 8eea5b5664..4232dfbf38 100644 --- a/src/main/java/org/rumbledb/items/gYearItem.java +++ b/src/main/java/org/rumbledb/items/gYearItem.java @@ -137,6 +137,9 @@ public void read(Kryo kryo, Input input) { } private static boolean checkInvalidGYearFormat(String gYear, ItemType gYearType) { + if (gYear.startsWith("0000") || gYear.startsWith("-0000")) { + return false; + } if (gYearType.equals(BuiltinTypesCatalogue.gYearItem)) { return gYearPattern.matcher(gYear).matches(); } diff --git a/src/main/java/org/rumbledb/items/gYearMonthItem.java b/src/main/java/org/rumbledb/items/gYearMonthItem.java index 2448c29c83..3e4e502d71 100644 --- a/src/main/java/org/rumbledb/items/gYearMonthItem.java +++ b/src/main/java/org/rumbledb/items/gYearMonthItem.java @@ -145,6 +145,9 @@ public void read(Kryo kryo, Input input) { } private static boolean checkInvalidGYearMonthFormat(String gYearMonth, ItemType gYearMonthType) { + if (gYearMonth.startsWith("0000") || gYearMonth.startsWith("-0000")) { + return false; + } if (gYearMonthType.equals(BuiltinTypesCatalogue.gYearMonthItem)) { return gYearMonthPattern.matcher(gYearMonth).matches(); } From 563b91b13bce77706a181ae530bb80fc807761da Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 19 Jul 2021 23:44:55 +0200 Subject: [PATCH 112/142] NaN deep-equal. --- .../value/DeepEqualFunctionIterator.java | 9 ++++++++ .../runtime/misc/ComparisonIterator.java | 15 ++++++++----- .../rumbledb/runtime/typing/CastIterator.java | 22 ++++++++++++++----- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 0b22c8734a..a0861156d8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -96,6 +96,15 @@ public boolean checkDeepEqual(List items1, List items2) { for (int i = 0; i < items1.size(); i++) { Item item1 = items1.get(i); Item item2 = items2.get(i); + // Specific to deep-equal but does not apply to eq operator + if ( + ((item1.isFloat() && Float.isNaN(item1.getFloatValue())) + || (item1.isDouble() && Double.isNaN(item1.getDoubleValue()))) + && ((item2.isFloat() && Float.isNaN(item2.getFloatValue())) + || (item2.isDouble() && Double.isNaN(item2.getDoubleValue()))) + ) { + return true; + } if (!item1.equals(item2)) { return false; } diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 886a312b5a..d45c1273b0 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -269,11 +269,6 @@ public static long compareItems( double r = right.getDoubleValue(); return processDouble(l, r); } - if (right.isDouble() && left.isNumeric()) { - double l = left.castToDoubleValue(); - double r = right.getDoubleValue(); - return processDouble(l, r); - } if (left.isFloat() && right.isNumeric()) { float l = left.getFloatValue(); float r = 0; @@ -284,6 +279,16 @@ public static long compareItems( } return processFloat(l, r); } + if (left.isNumeric() && right.isFloat()) { + float l = 0; + float r = right.getFloatValue(); + if (left.isFloat()) { + l = left.getFloatValue(); + } else { + l = left.castToFloatValue(); + } + return processFloat(l, r); + } if (left.isInteger() && right.isInteger()) { BigInteger l = left.getIntegerValue(); BigInteger r = right.getIntegerValue(); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index ff3bdf87e2..22f786fc51 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -5,11 +5,7 @@ import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.MoreThanOneItemException; -import org.rumbledb.exceptions.UnexpectedTypeException; -import org.rumbledb.exceptions.UnknownCastTypeException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; @@ -25,6 +21,7 @@ import java.util.Collections; + public class CastIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private final RuntimeIterator child; @@ -173,6 +170,16 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return null; } + if ( + (item.isFloat() && (Float.isNaN(item.getFloatValue()) || Float.isInfinite(item.getFloatValue()))) + || (item.isDouble() + && (Double.isNaN(item.getDoubleValue()) || Double.isInfinite(item.getDoubleValue()))) + ) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); + } if (targetType.equals(BuiltinTypesCatalogue.decimalItem)) { if (item.isString()) { @@ -391,6 +398,11 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return null; + } catch (InvalidLexicalValueException i) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); } catch (Exception e) { return null; } From 9b055803f5d8cf602800f0f6168c64e3a3442ab3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 20 Jul 2021 19:43:06 +0200 Subject: [PATCH 113/142] Deep-equal Annotated --- .../org/rumbledb/items/AnnotatedItem.java | 17 ++++++++++++ .../org/rumbledb/items/ItemComparator.java | 12 ++++++--- .../rumbledb/items/parsing/ItemParser.java | 26 +++++++++++++++---- .../runtime/misc/ComparisonIterator.java | 12 ++++++--- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/rumbledb/items/AnnotatedItem.java b/src/main/java/org/rumbledb/items/AnnotatedItem.java index 058a4d3691..d5ce1f8082 100644 --- a/src/main/java/org/rumbledb/items/AnnotatedItem.java +++ b/src/main/java/org/rumbledb/items/AnnotatedItem.java @@ -10,9 +10,12 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.FunctionIdentifier; import org.rumbledb.context.Name; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.comparison.ComparisonExpression; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.flwor.NativeClauseContext; +import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.ItemType; @@ -37,6 +40,20 @@ public AnnotatedItem(Item itemToAnnotate, ItemType type) { this.type = type; } + @Override + public boolean equals(Object otherItem) { + if (otherItem instanceof AnnotatedItem) { + long c = ComparisonIterator.compareItems( + this, + (Item) otherItem, + ComparisonExpression.ComparisonOperator.VC_EQ, + ExceptionMetadata.EMPTY_METADATA + ); + return c == 0; + } + return false; + } + @Override public void write(Kryo kryo, Output output) { this.itemToAnnotate.write(kryo, output); diff --git a/src/main/java/org/rumbledb/items/ItemComparator.java b/src/main/java/org/rumbledb/items/ItemComparator.java index ea991f9359..1f134e576d 100644 --- a/src/main/java/org/rumbledb/items/ItemComparator.java +++ b/src/main/java/org/rumbledb/items/ItemComparator.java @@ -55,15 +55,19 @@ public ItemComparator(boolean compareMin, RumbleException exception) { */ public int compare(Item v1, Item v2) { if (this.compareMin) { - if (v2.isNumeric() && + if ( + v2.isNumeric() + && ((v1.isDouble() && Double.isNaN(v1.getDoubleValue())) - || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) + || (v1.isFloat() && Float.isNaN(v1.getFloatValue()))) ) { return -1; } - if (v1.isNumeric() && + if ( + v1.isNumeric() + && ((v2.isDouble() && Double.isNaN(v2.getDoubleValue())) - || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) + || (v2.isFloat() && Float.isNaN(v2.getFloatValue()))) ) { return 1; } diff --git a/src/main/java/org/rumbledb/items/parsing/ItemParser.java b/src/main/java/org/rumbledb/items/parsing/ItemParser.java index 449ae75bc7..a8c9d8187b 100644 --- a/src/main/java/org/rumbledb/items/parsing/ItemParser.java +++ b/src/main/java/org/rumbledb/items/parsing/ItemParser.java @@ -21,7 +21,6 @@ package org.rumbledb.items.parsing; import org.apache.commons.codec.binary.Hex; -import org.apache.parquet.format.IntType; import org.apache.spark.ml.linalg.DenseVector; import org.apache.spark.ml.linalg.SparseVector; import org.apache.spark.ml.linalg.Vector; @@ -351,7 +350,10 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.dateItem)) { return DataTypes.DateType; } - if (itemType.equals(BuiltinTypesCatalogue.dateTimeItem) || itemType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.dateTimeItem) + || itemType.equals(BuiltinTypesCatalogue.dateTimeStampItem) + ) { return DataTypes.TimestampType; } if (itemType.equals(BuiltinTypesCatalogue.hexBinaryItem)) { @@ -360,13 +362,27 @@ public static DataType getDataFrameDataTypeFromItemType(ItemType itemType) { if (itemType.equals(BuiltinTypesCatalogue.objectItem)) { return vectorType; } - if (itemType.equals(BuiltinTypesCatalogue.positiveIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonNegativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.negativeIntegerItem) || itemType.equals(BuiltinTypesCatalogue.nonPositiveIntegerItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.positiveIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.nonNegativeIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.negativeIntegerItem) + || itemType.equals(BuiltinTypesCatalogue.nonPositiveIntegerItem) + ) { return DataTypes.IntegerType; } - if (itemType.equals(BuiltinTypesCatalogue.unsignedByteItem) || itemType.equals(BuiltinTypesCatalogue.unsignedLongItem) || itemType.equals(BuiltinTypesCatalogue.unsignedShortItem) || itemType.equals(BuiltinTypesCatalogue.unsignedIntItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.unsignedByteItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedLongItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedShortItem) + || itemType.equals(BuiltinTypesCatalogue.unsignedIntItem) + ) { return DataTypes.IntegerType; } - if (itemType.equals(BuiltinTypesCatalogue.intItem) || itemType.equals(BuiltinTypesCatalogue.byteItem) || itemType.equals(BuiltinTypesCatalogue.shortItem)) { + if ( + itemType.equals(BuiltinTypesCatalogue.intItem) + || itemType.equals(BuiltinTypesCatalogue.byteItem) + || itemType.equals(BuiltinTypesCatalogue.shortItem) + ) { return DataTypes.IntegerType; } throw new IllegalArgumentException( diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 7269b9cfef..886a312b5a 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -230,15 +230,19 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } - if (right.isNumeric() && + if ( + right.isNumeric() + && ((left.isDouble() && Double.isNaN(left.getDoubleValue())) - || (left.isFloat() && Float.isNaN(left.getFloatValue()))) + || (left.isFloat() && Float.isNaN(left.getFloatValue()))) ) { return 1; } - if (left.isNumeric() && + if ( + left.isNumeric() + && ((right.isDouble() && Double.isNaN(right.getDoubleValue())) - || (right.isFloat() && Float.isNaN(right.getFloatValue()))) + || (right.isFloat() && Float.isNaN(right.getFloatValue()))) ) { return -1; } From 7e58da171c006f1e89703d0ddf2d761f3f8f77bd Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 20 Jul 2021 20:09:21 +0200 Subject: [PATCH 114/142] DeepEq NaN, compare with NaN or INF. --- .../value/DeepEqualFunctionIterator.java | 9 ++++++++ .../runtime/misc/ComparisonIterator.java | 10 +++++++++ .../rumbledb/runtime/typing/CastIterator.java | 22 ++++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 7c7b18b729..42b4caca11 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -96,6 +96,15 @@ public boolean checkDeepEqual(List items1, List items2) { for (int i = 0; i < items1.size(); i++) { Item item1 = items1.get(i); Item item2 = items2.get(i); + // Specific to deep-equal but does not apply to eq operator + if ( + ((item1.isFloat() && Float.isNaN(item1.getFloatValue())) + || (item1.isDouble() && Double.isNaN(item1.getDoubleValue()))) + && ((item2.isFloat() && Float.isNaN(item2.getFloatValue())) + || (item2.isDouble() && Double.isNaN(item2.getDoubleValue()))) + ) { + return true; + } if (!item1.equals(item2)) { return false; diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 886a312b5a..5b1c6fcda2 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -284,6 +284,16 @@ public static long compareItems( } return processFloat(l, r); } + if (left.isNumeric() && right.isFloat()) { + float l = 0; + float r = right.getFloatValue(); + if (left.isFloat()) { + l = left.getFloatValue(); + } else { + l = left.castToFloatValue(); + } + return processFloat(l, r); + } if (left.isInteger() && right.isInteger()) { BigInteger l = left.getIntegerValue(); BigInteger r = right.getIntegerValue(); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index ff3bdf87e2..b893e71bc8 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -5,11 +5,7 @@ import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.MoreThanOneItemException; -import org.rumbledb.exceptions.UnexpectedTypeException; -import org.rumbledb.exceptions.UnknownCastTypeException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; @@ -174,6 +170,17 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return null; } + if ( + (item.isFloat() && (Float.isNaN(item.getFloatValue()) || Float.isInfinite(item.getFloatValue()))) + || (item.isDouble() + && (Double.isNaN(item.getDoubleValue()) || Double.isInfinite(item.getDoubleValue()))) + ) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); + } + if (targetType.equals(BuiltinTypesCatalogue.decimalItem)) { if (item.isString()) { return ItemFactory.getInstance().createDecimalItem(item.castToDecimalValue()); @@ -391,6 +398,11 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return null; + } catch (InvalidLexicalValueException i) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); } catch (Exception e) { return null; } From 7d36b60d3d93a3cf3a5b5f25a6f10c4d994ade6e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 20 Jul 2021 21:11:40 +0200 Subject: [PATCH 115/142] deactivate MLPipeline tests --- .../RumbleML/{MLPipeline1.jq => MLPipeline1.jq.deactivated} | 0 .../RumbleML/{MLPipeline2.jq => MLPipeline2.jq.deactivated} | 0 .../RumbleML/{MLPipeline3.jq => MLPipeline3.jq.deactivated} | 0 .../RumbleML/{MLPipeline4.jq => MLPipeline4.jq.deactivated} | 0 .../RumbleML/{MLPipeline5.jq => MLPipeline5.jq.deactivated} | 0 .../RumbleML/{MLPipeline6.jq => MLPipeline6.jq.deactivated} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline1.jq => MLPipeline1.jq.deactivated} (100%) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline2.jq => MLPipeline2.jq.deactivated} (100%) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline3.jq => MLPipeline3.jq.deactivated} (100%) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline4.jq => MLPipeline4.jq.deactivated} (100%) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline5.jq => MLPipeline5.jq.deactivated} (100%) rename src/test/resources/test_files/runtime-spark/RumbleML/{MLPipeline6.jq => MLPipeline6.jq.deactivated} (100%) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated similarity index 100% rename from src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq rename to src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated From 2c0c89e9b446922e2c1f68e4c0a2b236d2df0804 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 22 Jul 2021 15:30:38 +0200 Subject: [PATCH 116/142] modify check facets int to fix annotate. --- .../java/org/rumbledb/runtime/typing/CastIterator.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 3f9e3178c3..661f8510bb 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -218,10 +218,11 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad .createIntItem(item.getBooleanValue() ? 1 : 0); } if (item.isNumeric()) { - if (item.isDecimal()) { - item = new IntegerItem(item.castToIntegerValue()); - } - Item checkedItem = checkFacetsInteger(item, targetType, false); + Item checkedItem = checkFacetsInteger( + ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), + targetType, + false + ); if (checkedItem != null) { return ItemFactory.getInstance().createIntItem(checkedItem.castToIntValue()); } From 34a59ce497dbd31606c99c1ef81c06d7e23cb37b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 22 Jul 2021 15:31:55 +0200 Subject: [PATCH 117/142] spotless. --- src/main/java/org/rumbledb/items/FloatItem.java | 7 +++---- .../java/org/rumbledb/runtime/typing/CastIterator.java | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/rumbledb/items/FloatItem.java b/src/main/java/org/rumbledb/items/FloatItem.java index d439bfd7ce..7b9d78bbb7 100644 --- a/src/main/java/org/rumbledb/items/FloatItem.java +++ b/src/main/java/org/rumbledb/items/FloatItem.java @@ -34,7 +34,6 @@ import org.rumbledb.types.ItemType; import java.math.BigDecimal; import java.math.BigInteger; -import java.text.DecimalFormat; public class FloatItem implements Item { @@ -131,9 +130,9 @@ public String serialize() { } // Force mantissa between 10E6 and 10E7 if (abs < 100000000) { - String str = Float.toString(this.value*10); - char reducedChar = (char) ((int) str.charAt(str.length()-1) - 1); - StringBuilder sb = new StringBuilder(str.substring(0, str.length()-1)).append(reducedChar); + String str = Float.toString(this.value * 10); + char reducedChar = (char) ((int) str.charAt(str.length() - 1) - 1); + StringBuilder sb = new StringBuilder(str.substring(0, str.length() - 1)).append(reducedChar); return sb.toString(); } return Float.toString(this.value); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 661f8510bb..c77edff794 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -12,7 +12,6 @@ import org.rumbledb.exceptions.UnknownCastTypeException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; -import org.rumbledb.items.IntegerItem; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -219,9 +218,9 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } if (item.isNumeric()) { Item checkedItem = checkFacetsInteger( - ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), - targetType, - false + ItemFactory.getInstance().createIntegerItem(item.castToIntegerValue()), + targetType, + false ); if (checkedItem != null) { return ItemFactory.getInstance().createIntItem(checkedItem.castToIntValue()); From abdd02e22328b731055914d8ff3763f39d21e208 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 22 Jul 2021 18:44:33 +0200 Subject: [PATCH 118/142] spotless. --- .../sequences/value/DeepEqualFunctionIterator.java | 8 ++++---- .../java/org/rumbledb/runtime/typing/CastIterator.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 42b4caca11..e7f9a4f6e4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -98,10 +98,10 @@ public boolean checkDeepEqual(List items1, List items2) { Item item2 = items2.get(i); // Specific to deep-equal but does not apply to eq operator if ( - ((item1.isFloat() && Float.isNaN(item1.getFloatValue())) - || (item1.isDouble() && Double.isNaN(item1.getDoubleValue()))) - && ((item2.isFloat() && Float.isNaN(item2.getFloatValue())) - || (item2.isDouble() && Double.isNaN(item2.getDoubleValue()))) + ((item1.isFloat() && Float.isNaN(item1.getFloatValue())) + || (item1.isDouble() && Double.isNaN(item1.getDoubleValue()))) + && ((item2.isFloat() && Float.isNaN(item2.getFloatValue())) + || (item2.isDouble() && Double.isNaN(item2.getDoubleValue()))) ) { return true; } diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index b893e71bc8..f54feeb17a 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -171,9 +171,9 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } if ( - (item.isFloat() && (Float.isNaN(item.getFloatValue()) || Float.isInfinite(item.getFloatValue()))) - || (item.isDouble() - && (Double.isNaN(item.getDoubleValue()) || Double.isInfinite(item.getDoubleValue()))) + (item.isFloat() && (Float.isNaN(item.getFloatValue()) || Float.isInfinite(item.getFloatValue()))) + || (item.isDouble() + && (Double.isNaN(item.getDoubleValue()) || Double.isInfinite(item.getDoubleValue()))) ) { throw new InvalidLexicalValueException( "NaN or INF cannot be cast to another type than Float or Double", From d1c95de95d476a4ffc8cc08574f7ff8267a3cab8 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 20 Jul 2021 20:09:21 +0200 Subject: [PATCH 119/142] DeepEq NaN, compare with NaN or INF. --- .../value/DeepEqualFunctionIterator.java | 9 ++++++++ .../runtime/misc/ComparisonIterator.java | 10 +++++++++ .../rumbledb/runtime/typing/CastIterator.java | 22 ++++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java index 7c7b18b729..e7f9a4f6e4 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/value/DeepEqualFunctionIterator.java @@ -96,6 +96,15 @@ public boolean checkDeepEqual(List items1, List items2) { for (int i = 0; i < items1.size(); i++) { Item item1 = items1.get(i); Item item2 = items2.get(i); + // Specific to deep-equal but does not apply to eq operator + if ( + ((item1.isFloat() && Float.isNaN(item1.getFloatValue())) + || (item1.isDouble() && Double.isNaN(item1.getDoubleValue()))) + && ((item2.isFloat() && Float.isNaN(item2.getFloatValue())) + || (item2.isDouble() && Double.isNaN(item2.getDoubleValue()))) + ) { + return true; + } if (!item1.equals(item2)) { return false; diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 886a312b5a..5b1c6fcda2 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -284,6 +284,16 @@ public static long compareItems( } return processFloat(l, r); } + if (left.isNumeric() && right.isFloat()) { + float l = 0; + float r = right.getFloatValue(); + if (left.isFloat()) { + l = left.getFloatValue(); + } else { + l = left.castToFloatValue(); + } + return processFloat(l, r); + } if (left.isInteger() && right.isInteger()) { BigInteger l = left.getIntegerValue(); BigInteger r = right.getIntegerValue(); diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index ff3bdf87e2..f54feeb17a 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -5,11 +5,7 @@ import org.apache.commons.lang.StringUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; -import org.rumbledb.exceptions.CastException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.MoreThanOneItemException; -import org.rumbledb.exceptions.UnexpectedTypeException; -import org.rumbledb.exceptions.UnknownCastTypeException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.DurationItem; import org.rumbledb.items.ItemFactory; @@ -174,6 +170,17 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return null; } + if ( + (item.isFloat() && (Float.isNaN(item.getFloatValue()) || Float.isInfinite(item.getFloatValue()))) + || (item.isDouble() + && (Double.isNaN(item.getDoubleValue()) || Double.isInfinite(item.getDoubleValue()))) + ) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); + } + if (targetType.equals(BuiltinTypesCatalogue.decimalItem)) { if (item.isString()) { return ItemFactory.getInstance().createDecimalItem(item.castToDecimalValue()); @@ -391,6 +398,11 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return null; + } catch (InvalidLexicalValueException i) { + throw new InvalidLexicalValueException( + "NaN or INF cannot be cast to another type than Float or Double", + metadata + ); } catch (Exception e) { return null; } From 5cd8b945b3417f8a51af5ec797c1c6e9c23721ed Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 23 Jul 2021 18:14:09 +0200 Subject: [PATCH 120/142] update compare float. --- .../org/rumbledb/runtime/misc/ComparisonIterator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 5b1c6fcda2..7682db8cb5 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -264,16 +264,17 @@ public static long compareItems( } return processDouble(l, r); } - if (right.isDouble() && left.isNumeric()) { + if (left.isNumeric() && right.isDouble()) { double l = left.castToDoubleValue(); double r = right.getDoubleValue(); return processDouble(l, r); } - if (right.isDouble() && left.isNumeric()) { + if (left.isNumeric() && right.isDouble()) { double l = left.castToDoubleValue(); double r = right.getDoubleValue(); return processDouble(l, r); } + if (left.isFloat() && right.isNumeric()) { float l = left.getFloatValue(); float r = 0; @@ -415,6 +416,9 @@ private static int processFloat( float l, float r ) { + // Check equality to have -0 to be equal 0 + if (l == r) + return 0; return Float.compare(l, r); } From dae4a5b25937e3af8cd5280969b9e882821b331b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 24 Jul 2021 00:10:42 +0200 Subject: [PATCH 121/142] min to volcano style. --- .../aggregate/MinFunctionIterator.java | 93 ++++++++++++++++--- 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 694e34b3c7..6789206b02 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -24,20 +24,19 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; -import org.rumbledb.exceptions.DefaultCollationException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.RumbleException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import sparksoniq.spark.SparkSessionManager; +import org.rumbledb.expressions.comparison.ComparisonExpression.ComparisonOperator; +import org.rumbledb.runtime.misc.ComparisonIterator; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -48,6 +47,10 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private RuntimeIterator iterator; private Item result; + private Item nextResult; + private Item minResult; + private ItemComparator comparator; + public MinFunctionIterator( List arguments, @@ -56,17 +59,18 @@ public MinFunctionIterator( ) { super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); - } - - @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - ItemComparator comparator = new ItemComparator( + this.comparator = new ItemComparator( true, new InvalidArgumentTypeException( "Min expression input error. Input has to be non-null atomics of matching types", getMetadata() ) ); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + if (this.children.size() == 2) { String collation = this.children.get(1).materializeFirstItemOrNull(context).getStringValue(); if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { @@ -82,7 +86,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } try { - return itemTypePromotion(Collections.min(results, comparator)); + System.out.println("before open context"); + open(context); + System.out.println("before next"); + return next(); + //return itemTypePromotion(Collections.min(results, comparator)); + } catch (RumbleException e) { RumbleException ex = new InvalidArgumentTypeException( "Min expression input error. Input has to be non-null atomics of matching types.", @@ -114,10 +123,70 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (rdd.isEmpty()) { return null; } - this.result = rdd.min(comparator); + this.result = rdd.min(comparator); // this return itemTypePromotion(this.result); + } + + @Override + public void open(DynamicContext dynamicContext) { + this.iterator.open(dynamicContext); + System.out.println("next it "); + this.minResult = this.iterator.next(); + System.out.println("setNextRes"); + setNextResult(); + } + @Override + public Item next() { + //Item result = this.nextResult; + //setNextResult(); + System.out.println("NEXT"); + System.out.println(this.minResult); + System.out.println(this.nextResult); + return this.minResult; + //throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "min function", getMetadata()); + } + + private void setNextResult() { + this.nextResult = null; + while (this.iterator.hasNext()) { + System.out.println("init candidate"); + Item candidateItem = this.iterator.next(); + System.out.println("candidate is "); + System.out.println(candidateItem.getIntValue()); + long c = ComparisonIterator.compareItems(candidateItem, this.minResult, ComparisonOperator.GC_LT, getMetadata()); + System.out.println("c"); + System.out.println(c); + if (c < 0) { + this.minResult = candidateItem; + this.nextResult = this.minResult; + } + } + System.out.println("out loop"); + if (this.nextResult == null) { + this.hasNext = false; + this.iterator.close(); + } else { + this.hasNext = true; + } + next(); + } + + @Override + public void reset(DynamicContext dynamicContext) { + this.iterator.reset(dynamicContext); + setNextResult(); + } + + @Override + public boolean hasNext() { + return this.hasNext; + } + + @Override + public void close() { + this.iterator.close(); } public Map getVariableDependencies() { From 394743d692417efabe6bf80f06e00a8c1df6c1ca Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Sat, 24 Jul 2021 14:18:14 +0200 Subject: [PATCH 122/142] fix types hierarchy. min still has issues if called in context. --- .../aggregate/MinFunctionIterator.java | 161 ++++++++---------- .../rumbledb/types/BuiltinTypesCatalogue.java | 26 +-- 2 files changed, 83 insertions(+), 104 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 6789206b02..926c594ec5 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -20,23 +20,18 @@ package org.rumbledb.runtime.functions.sequences.aggregate; -import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; -import org.rumbledb.items.ItemFactory; -import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; -import org.rumbledb.runtime.misc.ComparisonIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; -import sparksoniq.spark.SparkSessionManager; -import org.rumbledb.expressions.comparison.ComparisonExpression.ComparisonOperator; -import org.rumbledb.runtime.misc.ComparisonIterator; - +import org.rumbledb.runtime.typing.CastIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -46,9 +41,8 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private RuntimeIterator iterator; - private Item result; private Item nextResult; - private Item minResult; + private ItemType returnType; private ItemComparator comparator; @@ -78,99 +72,81 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } - if (!this.iterator.isRDDOrDataFrame()) { - - List results = this.iterator.materialize(context); - if (results.size() == 0) { - return null; - } - - try { - System.out.println("before open context"); - open(context); - System.out.println("before next"); - return next(); - //return itemTypePromotion(Collections.min(results, comparator)); - - } catch (RumbleException e) { - RumbleException ex = new InvalidArgumentTypeException( - "Min expression input error. Input has to be non-null atomics of matching types.", - getMetadata() - ); - ex.initCause(e); - throw ex; - } - } - - if (this.iterator.isDataFrame()) { - JSoundDataFrame df = this.iterator.getDataFrame(context); - if (df.isEmptySequence()) { - return null; - } - df.createOrReplaceTempView("input"); - JSoundDataFrame minDF = df.evaluateSQL( - String.format( - "SELECT MIN(`%s`) as `%s` FROM input", - SparkSessionManager.atomicJSONiqItemColumnName, - SparkSessionManager.atomicJSONiqItemColumnName - ), - df.getItemType() + // if (!this.iterator.isRDDOrDataFrame()) { + try { + return this.nextResult; + } catch (RumbleException e) { + RumbleException ex = new InvalidArgumentTypeException( + "Min expression input error. Input has to be non-null atomics of matching types.", + getMetadata() ); - return itemTypePromotion(minDF.getExactlyOneItem()); + ex.initCause(e); + throw ex; } - - JavaRDD rdd = this.iterator.getRDD(context); - if (rdd.isEmpty()) { - return null; - } - this.result = rdd.min(comparator); // this - return itemTypePromotion(this.result); - + // } + /* + * if (this.iterator.isDataFrame()) { + * JSoundDataFrame df = this.iterator.getDataFrame(context); + * if (df.isEmptySequence()) { + * return null; + * } + * df.createOrReplaceTempView("input"); + * JSoundDataFrame minDF = df.evaluateSQL( + * String.format( + * "SELECT MIN(`%s`) as `%s` FROM input", + * SparkSessionManager.atomicJSONiqItemColumnName, + * SparkSessionManager.atomicJSONiqItemColumnName + * ), + * df.getItemType() + * ); + * return itemTypePromotion(minDF.getExactlyOneItem()); + * } + * + * JavaRDD rdd = this.iterator.getRDD(context); + * if (rdd.isEmpty()) { + * return null; + * } + * this.result = rdd.min(comparator); // this + * return itemTypePromotion(this.result); + */ } + @Override public void open(DynamicContext dynamicContext) { + super.open(dynamicContext); this.iterator.open(dynamicContext); - System.out.println("next it "); - this.minResult = this.iterator.next(); - System.out.println("setNextRes"); + this.hasNext = this.iterator.hasNext(); + if (!this.hasNext) { + return; + } + this.nextResult = this.iterator.next(); + this.returnType = this.nextResult.getDynamicType(); setNextResult(); } @Override public Item next() { - //Item result = this.nextResult; - //setNextResult(); - System.out.println("NEXT"); - System.out.println(this.minResult); - System.out.println(this.nextResult); - return this.minResult; - //throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "min function", getMetadata()); + if (this.nextResult == null) { + return null; + } + if (this.hasNext) { + this.hasNext = false; + return CastIterator.castItemToType(this.nextResult, this.returnType, getMetadata()); + } + throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "min function", getMetadata()); } private void setNextResult() { - this.nextResult = null; while (this.iterator.hasNext()) { - System.out.println("init candidate"); Item candidateItem = this.iterator.next(); - System.out.println("candidate is "); - System.out.println(candidateItem.getIntValue()); - long c = ComparisonIterator.compareItems(candidateItem, this.minResult, ComparisonOperator.GC_LT, getMetadata()); - System.out.println("c"); - System.out.println(c); + promoteType(candidateItem); + int c = this.comparator.compare(candidateItem, this.nextResult); if (c < 0) { - this.minResult = candidateItem; - this.nextResult = this.minResult; + this.nextResult = candidateItem; } } - System.out.println("out loop"); - if (this.nextResult == null) { - this.hasNext = false; - this.iterator.close(); - } else { - this.hasNext = true; - } - next(); + this.iterator.close(); } @Override @@ -201,17 +177,20 @@ public Map getVariableDependencies() { } } - private Item itemTypePromotion(Item item) { - if (item.isAnyURI()) { - return ItemFactory.getInstance().createStringItem(item.getStringValue()); + + + private void promoteType(Item candidateItem) { + if (this.returnType != BuiltinTypesCatalogue.doubleItem && candidateItem.isFloat()) { + this.returnType = BuiltinTypesCatalogue.floatItem; } - if (item.isFloat()) { - return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + if (candidateItem.isDouble()) { + this.returnType = BuiltinTypesCatalogue.doubleItem; } - if (item.isDecimal()) { - return ItemFactory.getInstance().createDoubleItem(item.castToDoubleValue()); + if (candidateItem.isString()) { + this.returnType = BuiltinTypesCatalogue.stringItem; } - return item; } + + } diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index 675a6495c5..12dc387e57 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -350,7 +350,7 @@ public class BuiltinTypesCatalogue { public static final DerivedAtomicItemType byteItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "byte"), - intItem, + shortItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets(new IntItem(-128), new IntItem(127), true), false, @@ -405,35 +405,35 @@ public class BuiltinTypesCatalogue { DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); - public static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedInt"), - integerItem, + public static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedLong"), + nonNegativeIntegerItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets( new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("4294967295")), + new IntegerItem(new BigInteger("18446744073709551615")), true ), false, - DataTypes.IntegerType // TODO : how to support arbitrary-sized integer + DataTypes.LongType // TODO : how to support arbitrary-sized integer ); - public static final DerivedAtomicItemType unsignedLongItem = new DerivedAtomicItemType( - new Name(Name.XS_NS, "xs", "unsignedLong"), - integerItem, + public static final DerivedAtomicItemType unsignedIntItem = new DerivedAtomicItemType( + new Name(Name.XS_NS, "xs", "unsignedInt"), + unsignedLongItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets( new IntegerItem(new BigInteger("0")), - new IntegerItem(new BigInteger("18446744073709551615")), + new IntegerItem(new BigInteger("4294967295")), true ), false, - DataTypes.LongType // TODO : how to support arbitrary-sized integer + DataTypes.IntegerType // TODO : how to support arbitrary-sized integer ); public static final DerivedAtomicItemType unsignedShortItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedShort"), - integerItem, + unsignedIntItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets(new IntItem(0), new IntItem(65535), true), false, @@ -442,7 +442,7 @@ public class BuiltinTypesCatalogue { public static final DerivedAtomicItemType unsignedByteItem = new DerivedAtomicItemType( new Name(Name.XS_NS, "xs", "unsignedByte"), - integerItem, + unsignedShortItem, AtomicItemType.decimalItem, Facets.createMinMaxFacets(new IntItem(0), new IntItem(255), true), false, From b6400486788d46cbf43846d92610d0997f53775e Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 26 Jul 2021 14:35:20 +0200 Subject: [PATCH 123/142] update min, works for numeric types. --- .../aggregate/MinFunctionIterator.java | 322 ++++++++++++------ 1 file changed, 215 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 926c594ec5..b9c0a2617a 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -20,18 +20,24 @@ package org.rumbledb.runtime.functions.sequences.aggregate; +import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import org.rumbledb.runtime.typing.CastIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.ItemType; +import sparksoniq.spark.SparkSessionManager; + +import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -41,9 +47,14 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private RuntimeIterator iterator; - private Item nextResult; + private double currentMinDouble; + private float currentMinFloat; + private BigDecimal currentMinDecimal; + private long currentMinLong; + private Item currentMin; + private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long private ItemType returnType; - private ItemComparator comparator; + private Item result; public MinFunctionIterator( @@ -53,18 +64,10 @@ public MinFunctionIterator( ) { super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); - this.comparator = new ItemComparator( - true, - new InvalidArgumentTypeException( - "Min expression input error. Input has to be non-null atomics of matching types", - getMetadata() - ) - ); } @Override public Item materializeFirstItemOrNull(DynamicContext context) { - if (this.children.size() == 2) { String collation = this.children.get(1).materializeFirstItemOrNull(context).getStringValue(); if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { @@ -72,97 +75,218 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } - // if (!this.iterator.isRDDOrDataFrame()) { - try { - return this.nextResult; - } catch (RumbleException e) { - RumbleException ex = new InvalidArgumentTypeException( - "Min expression input error. Input has to be non-null atomics of matching types.", - getMetadata() - ); - ex.initCause(e); - throw ex; - } - // } - /* - * if (this.iterator.isDataFrame()) { - * JSoundDataFrame df = this.iterator.getDataFrame(context); - * if (df.isEmptySequence()) { - * return null; - * } - * df.createOrReplaceTempView("input"); - * JSoundDataFrame minDF = df.evaluateSQL( - * String.format( - * "SELECT MIN(`%s`) as `%s` FROM input", - * SparkSessionManager.atomicJSONiqItemColumnName, - * SparkSessionManager.atomicJSONiqItemColumnName - * ), - * df.getItemType() - * ); - * return itemTypePromotion(minDF.getExactlyOneItem()); - * } - * - * JavaRDD rdd = this.iterator.getRDD(context); - * if (rdd.isEmpty()) { - * return null; - * } - * this.result = rdd.min(comparator); // this - * return itemTypePromotion(this.result); - */ - } + if (!this.iterator.isRDDOrDataFrame()) { + this.iterator.open(context); + while (this.iterator.hasNext()) { + Item candidateItem = this.iterator.next(); + ItemType candidateType = candidateItem.getDynamicType(); - @Override - public void open(DynamicContext dynamicContext) { - super.open(dynamicContext); - this.iterator.open(dynamicContext); - this.hasNext = this.iterator.hasNext(); - if (!this.hasNext) { - return; - } - this.nextResult = this.iterator.next(); - this.returnType = this.nextResult.getDynamicType(); - setNextResult(); - } + // Manage all types and make sure comparison are correct + switch (this.activeType) { + case 0: + // initialization, take whatever first type + if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { + this.activeType = 1; + this.currentMinLong = candidateItem.castToDecimalValue().longValue(); + } else if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.decimalItem)) { + this.activeType = 2; + this.currentMinDecimal = candidateItem.castToDecimalValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.floatItem)) { + this.activeType = 3; + this.currentMinFloat = candidateItem.castToFloatValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.doubleItem)) { + this.activeType = 4; + this.currentMinDouble = candidateItem.castToDoubleValue(); + } else { + throw new OurBadException("Inconsistent state in state iteration"); + } + this.returnType = candidateType; + break; + case 1: + // long + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare float with " + candidateItem.getDynamicType(), + getMetadata() + ); + } + if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { + long candidateItemLong = candidateItem.castToDecimalValue().longValue(); + if (candidateItemLong < this.currentMinLong) { + this.currentMinLong = candidateItemLong; + this.returnType = candidateType; + } + } + if (candidateItem.isDecimal()) { + this.activeType = 1; + this.currentMinDecimal = new BigDecimal(this.currentMinLong); + BigDecimal candidateItemDecimal = candidateItem.getDecimalValue(); + if (candidateItemDecimal.compareTo(this.currentMinDecimal) < 0) { + this.currentMinDecimal = candidateItemDecimal; + this.returnType = candidateType; + } + } else if (candidateItem.isFloat()) { + this.activeType = 3; + this.returnType = BuiltinTypesCatalogue.floatItem; + this.currentMinFloat = this.currentMinLong; + float candidateItemFloat = candidateItem.getFloatValue(); + if (Float.isNaN(candidateItemFloat)) { + this.currentMinFloat = Float.NaN; + } else if (candidateItemFloat < this.currentMinFloat) { + this.currentMinFloat = candidateItemFloat; + } + } else if (candidateItem.isDouble()) { + this.activeType = 4; + this.returnType = BuiltinTypesCatalogue.doubleItem; + this.currentMinDouble = this.currentMinLong; + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble)) { + this.currentMinDouble = Double.NaN; + } else if (candidateItemDouble < this.currentMinDouble) { + this.currentMinDouble = candidateItemDouble; + } + } + break; + case 2: + // decimal + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare float with " + candidateItem.getDynamicType(), + getMetadata() + ); + } + if (candidateItem.isFloat()) { + this.activeType = 3; + this.returnType = BuiltinTypesCatalogue.floatItem; + this.currentMinFloat = this.currentMinDecimal.floatValue(); + float candidateItemFloat = candidateItem.getFloatValue(); + if (Float.isNaN(candidateItemFloat)) { + this.currentMinFloat = Float.NaN; + } else if (candidateItemFloat < this.currentMinFloat) { + this.currentMinFloat = candidateItemFloat; + } + } else if (candidateItem.isDouble()) { + this.activeType = 4; + this.currentMinDouble = this.currentMinFloat; + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble)) { + this.currentMinDouble = Double.NaN; + } else if (candidateItemDouble < this.currentMinDouble) { + this.currentMinDouble = candidateItemDouble; + } + } else { + BigDecimal candidateItemDecimal = candidateItem.castToDecimalValue(); + if (candidateItemDecimal.compareTo(this.currentMinDecimal) < 0) { + this.currentMinDecimal = candidateItemDecimal; + this.returnType = candidateType; + } + } + + break; + case 3: + System.out.println("case 3"); + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare float with " + candidateItem.getDynamicType(), + getMetadata() + ); + } + if (candidateItem.isDouble()) { + this.activeType = 4; + this.currentMinDouble = this.currentMinFloat; + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble) || candidateItemDouble < this.currentMinDouble) { + this.currentMinDouble = candidateItemDouble; + } + } else { + if (!Float.isNaN(this.currentMinFloat)) { + float candidateItemFloat = candidateItem.castToFloatValue(); + if (candidateItemFloat < this.currentMinFloat) { + this.currentMinFloat = candidateItemFloat; + } + } + } + + break; + case 4: + System.out.println("case 4"); + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare double with " + candidateItem.getDynamicType(), + getMetadata() + ); + } + if (!Double.isNaN(this.currentMinDouble)) { + double candidateItemDouble = candidateItem.castToDoubleValue(); + if (candidateItemDouble < this.currentMinDouble) { + this.currentMinDouble = candidateItemDouble; + } + } + break; + default: + throw new OurBadException("Inconsistent state in state iteration"); + } + + } + + this.iterator.close(); + + Item itemResult = null; + switch (this.activeType) { + case 0: + return null; + case 1: + itemResult = ItemFactory.getInstance().createLongItem(this.currentMinLong); + break; + case 2: + itemResult = ItemFactory.getInstance().createDecimalItem(this.currentMinDecimal); + break; + case 3: + itemResult = ItemFactory.getInstance().createFloatItem(this.currentMinFloat); + break; + case 4: + itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMinDouble); + break; + default: + throw new OurBadException("Inconsistent state in state iteration"); + } + return CastIterator.castItemToType(itemResult, this.returnType, getMetadata()); - @Override - public Item next() { - if (this.nextResult == null) { - return null; - } - if (this.hasNext) { - this.hasNext = false; - return CastIterator.castItemToType(this.nextResult, this.returnType, getMetadata()); } - throw new IteratorFlowException(FLOW_EXCEPTION_MESSAGE + "min function", getMetadata()); - } - private void setNextResult() { - while (this.iterator.hasNext()) { - Item candidateItem = this.iterator.next(); - promoteType(candidateItem); - int c = this.comparator.compare(candidateItem, this.nextResult); - if (c < 0) { - this.nextResult = candidateItem; + if (this.iterator.isDataFrame()) { + JSoundDataFrame df = this.iterator.getDataFrame(context); + if (df.isEmptySequence()) { + return null; } + df.createOrReplaceTempView("input"); + JSoundDataFrame minDF = df.evaluateSQL( + String.format( + "SELECT MIN(`%s`) as `%s` FROM input", + SparkSessionManager.atomicJSONiqItemColumnName, + SparkSessionManager.atomicJSONiqItemColumnName + ), + df.getItemType() + ); + return minDF.getExactlyOneItem(); } - this.iterator.close(); - } - @Override - public void reset(DynamicContext dynamicContext) { - this.iterator.reset(dynamicContext); - setNextResult(); - } + JavaRDD rdd = this.iterator.getRDD(context); + if (rdd.isEmpty()) { + return null; + } - @Override - public boolean hasNext() { - return this.hasNext; - } + ItemComparator comparator = new ItemComparator( + true, + new InvalidArgumentTypeException( + "Min expression input error. Input has to be non-null atomics of matching types", + getMetadata() + ) + ); - @Override - public void close() { - this.iterator.close(); + this.result = rdd.min(comparator); + return this.result; } public Map getVariableDependencies() { @@ -177,20 +301,4 @@ public Map getVariableDependencies() { } } - - - private void promoteType(Item candidateItem) { - if (this.returnType != BuiltinTypesCatalogue.doubleItem && candidateItem.isFloat()) { - this.returnType = BuiltinTypesCatalogue.floatItem; - } - if (candidateItem.isDouble()) { - this.returnType = BuiltinTypesCatalogue.doubleItem; - } - if (candidateItem.isString()) { - this.returnType = BuiltinTypesCatalogue.stringItem; - } - } - - - } From 7691e6761e05b1166bcc1c65d7e23e7871ded4d9 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Mon, 26 Jul 2021 18:33:19 +0200 Subject: [PATCH 124/142] pass test suite min function, except 2. fn-min-10 fn-min-19 --- .../aggregate/MinFunctionIterator.java | 111 ++++++++++++++---- 1 file changed, 91 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index b9c0a2617a..03bb8a92ec 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -52,9 +52,11 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private BigDecimal currentMinDecimal; private long currentMinLong; private Item currentMin; - private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long + private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long, 5 = anyURI, 6 = + // String, 7 = other types (date types) private ItemType returnType; private Item result; + private ItemComparator comparator; public MinFunctionIterator( @@ -64,6 +66,13 @@ public MinFunctionIterator( ) { super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); + this.comparator = new ItemComparator( + true, + new InvalidArgumentTypeException( + "Min expression input error. Input has to be non-null atomics of matching types", + getMetadata() + ) + ); } @Override @@ -98,8 +107,24 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } else if (candidateType.equals(BuiltinTypesCatalogue.doubleItem)) { this.activeType = 4; this.currentMinDouble = candidateItem.castToDoubleValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.anyURIItem)) { + this.activeType = 5; + this.currentMin = candidateItem; + } else if (candidateType.equals(BuiltinTypesCatalogue.stringItem)) { + this.activeType = 6; + this.currentMin = candidateItem; + } else if ( + candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem) + || candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem) + || candidateType.equals(BuiltinTypesCatalogue.dateTimeItem) + || candidateType.equals(BuiltinTypesCatalogue.dateItem) + ) { + this.activeType = 7; + this.currentMin = candidateItem; } else { - throw new OurBadException("Inconsistent state in state iteration"); + this.activeType = 9; + this.currentMin = candidateItem; + // throw new OurBadException("Inconsistent state in state iteration"); } this.returnType = candidateType; break; @@ -107,7 +132,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { // long if (!candidateItem.isNumeric()) { throw new InvalidArgumentTypeException( - "Cannot compare float with " + candidateItem.getDynamicType(), + "Cannot compare " + this.returnType + " with " + candidateType, getMetadata() ); } @@ -152,7 +177,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { // decimal if (!candidateItem.isNumeric()) { throw new InvalidArgumentTypeException( - "Cannot compare float with " + candidateItem.getDynamicType(), + "Cannot compare decimal with " + candidateType, getMetadata() ); } @@ -168,7 +193,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } else if (candidateItem.isDouble()) { this.activeType = 4; - this.currentMinDouble = this.currentMinFloat; + this.returnType = BuiltinTypesCatalogue.doubleItem; + this.currentMinDouble = this.currentMinDecimal.doubleValue(); double candidateItemDouble = candidateItem.getDoubleValue(); if (Double.isNaN(candidateItemDouble)) { this.currentMinDouble = Double.NaN; @@ -185,15 +211,15 @@ public Item materializeFirstItemOrNull(DynamicContext context) { break; case 3: - System.out.println("case 3"); if (!candidateItem.isNumeric()) { throw new InvalidArgumentTypeException( - "Cannot compare float with " + candidateItem.getDynamicType(), + "Cannot compare float with " + candidateType, getMetadata() ); } if (candidateItem.isDouble()) { this.activeType = 4; + this.returnType = BuiltinTypesCatalogue.doubleItem; this.currentMinDouble = this.currentMinFloat; double candidateItemDouble = candidateItem.getDoubleValue(); if (Double.isNaN(candidateItemDouble) || candidateItemDouble < this.currentMinDouble) { @@ -210,10 +236,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { break; case 4: - System.out.println("case 4"); if (!candidateItem.isNumeric()) { throw new InvalidArgumentTypeException( - "Cannot compare double with " + candidateItem.getDynamicType(), + "Cannot compare double with " + candidateType, getMetadata() ); } @@ -224,6 +249,55 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } } break; + case 5: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare anyURI with " + candidateType, + getMetadata() + ); + } + if (candidateItem.isString()) { + this.activeType = 6; + this.returnType = BuiltinTypesCatalogue.stringItem; + } + if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMin = candidateItem; + } + break; + case 6: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare string with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMin = candidateItem; + this.returnType = candidateType; + } + break; + case 7: + if (!candidateType.equals(this.returnType)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMin = candidateItem; + } + break; + case 9: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMin = candidateItem; + } + break; default: throw new OurBadException("Inconsistent state in state iteration"); } @@ -232,7 +306,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.iterator.close(); - Item itemResult = null; + Item itemResult; switch (this.activeType) { case 0: return null; @@ -248,6 +322,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { case 4: itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMinDouble); break; + case 5: + case 6: + case 7: + case 9: + itemResult = this.currentMin; + break; default: throw new OurBadException("Inconsistent state in state iteration"); } @@ -276,16 +356,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (rdd.isEmpty()) { return null; } - - ItemComparator comparator = new ItemComparator( - true, - new InvalidArgumentTypeException( - "Min expression input error. Input has to be non-null atomics of matching types", - getMetadata() - ) - ); - - this.result = rdd.min(comparator); + this.result = rdd.min(this.comparator); return this.result; } From f501179c146a72bec14b83d26bca3a99fc408e6b Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 27 Jul 2021 09:34:41 +0200 Subject: [PATCH 125/142] Update max similarly. spotless. --- .../aggregate/MaxFunctionIterator.java | 295 ++++++++++++++++-- .../aggregate/MinFunctionIterator.java | 6 + 2 files changed, 277 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index 4d5a9a2808..80ed2ffd53 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -24,10 +24,7 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; -import org.rumbledb.exceptions.DefaultCollationException; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.InvalidArgumentTypeException; -import org.rumbledb.exceptions.RumbleException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemComparator; import org.rumbledb.items.ItemFactory; @@ -35,9 +32,12 @@ import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; +import org.rumbledb.runtime.typing.CastIterator; +import org.rumbledb.types.BuiltinTypesCatalogue; +import org.rumbledb.types.ItemType; import sparksoniq.spark.SparkSessionManager; -import java.util.Collections; +import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -47,7 +47,16 @@ public class MaxFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private RuntimeIterator iterator; + private double currentMaxDouble; + private float currentMaxFloat; + private BigDecimal currentMaxDecimal; + private long currentMaxLong; + private Item currentMax; + private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long, 5 = anyURI, 6 = + // String, 7 = other types (date types) + private ItemType returnType; private Item result; + private ItemComparator comparator; public MaxFunctionIterator( List arguments, @@ -56,17 +65,17 @@ public MaxFunctionIterator( ) { super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); - } - - @Override - public Item materializeFirstItemOrNull(DynamicContext context) { - ItemComparator comparator = new ItemComparator( + this.comparator = new ItemComparator( false, new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types", getMetadata() ) ); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { if (this.children.size() == 2) { String collation = this.children.get(1).materializeFirstItemOrNull(context).getStringValue(); if (!collation.equals("http://www.w3.org/2005/xpath-functions/collation/codepoint")) { @@ -75,22 +84,260 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } if (!this.iterator.isRDDOrDataFrame()) { + this.iterator.open(context); + while (this.iterator.hasNext()) { + Item candidateItem = this.iterator.next(); + + ItemType candidateType = candidateItem.getDynamicType(); + + // Manage all types and make sure comparison are correct + switch (this.activeType) { + case 0: + // initialization, take whatever first type + if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { + this.activeType = 1; + this.currentMaxLong = candidateItem.castToDecimalValue().longValue(); + } else if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.decimalItem)) { + this.activeType = 2; + this.currentMaxDecimal = candidateItem.castToDecimalValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.floatItem)) { + this.activeType = 3; + this.currentMaxFloat = candidateItem.castToFloatValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.doubleItem)) { + this.activeType = 4; + this.currentMaxDouble = candidateItem.castToDoubleValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.anyURIItem)) { + this.activeType = 5; + this.currentMax = candidateItem; + } else if (candidateType.equals(BuiltinTypesCatalogue.stringItem)) { + this.activeType = 6; + this.currentMax = candidateItem; + } else if ( + candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem) + || candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem) + || candidateType.equals(BuiltinTypesCatalogue.dateTimeItem) + || candidateType.equals(BuiltinTypesCatalogue.dateItem) + ) { + this.activeType = 7; + this.currentMax = candidateItem; + } else { + if (candidateType.equals(BuiltinTypesCatalogue.durationItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + this.activeType = 9; + this.currentMax = candidateItem; + // throw new OurBadException("Inconsistent state in state iteration"); + } + this.returnType = candidateType; + break; + case 1: + // long + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { + long candidateItemLong = candidateItem.castToDecimalValue().longValue(); + if (candidateItemLong > this.currentMaxLong) { + this.currentMaxLong = candidateItemLong; + this.returnType = candidateType; + } + } + if (candidateItem.isDecimal()) { + this.activeType = 1; + this.currentMaxDecimal = new BigDecimal(this.currentMaxLong); + BigDecimal candidateItemDecimal = candidateItem.getDecimalValue(); + if (candidateItemDecimal.compareTo(this.currentMaxDecimal) > 0) { + this.currentMaxDecimal = candidateItemDecimal; + this.returnType = candidateType; + } + } else if (candidateItem.isFloat()) { + this.activeType = 3; + this.returnType = BuiltinTypesCatalogue.floatItem; + this.currentMaxFloat = this.currentMaxLong; + float candidateItemFloat = candidateItem.getFloatValue(); + if (Float.isNaN(candidateItemFloat)) { + this.currentMaxFloat = Float.NaN; + } else if (candidateItemFloat > this.currentMaxFloat) { + this.currentMaxFloat = candidateItemFloat; + } + } else if (candidateItem.isDouble()) { + this.activeType = 4; + this.returnType = BuiltinTypesCatalogue.doubleItem; + this.currentMaxDouble = this.currentMaxLong; + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble)) { + this.currentMaxDouble = Double.NaN; + } else if (candidateItemDouble > this.currentMaxDouble) { + this.currentMaxDouble = candidateItemDouble; + } + } + break; + case 2: + // decimal + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare decimal with " + candidateType, + getMetadata() + ); + } + if (candidateItem.isFloat()) { + this.activeType = 3; + this.returnType = BuiltinTypesCatalogue.floatItem; + this.currentMaxFloat = this.currentMaxDecimal.floatValue(); + float candidateItemFloat = candidateItem.getFloatValue(); + if (Float.isNaN(candidateItemFloat)) { + this.currentMaxFloat = Float.NaN; + } else if (candidateItemFloat > this.currentMaxFloat) { + this.currentMaxFloat = candidateItemFloat; + } + } else if (candidateItem.isDouble()) { + this.activeType = 4; + this.returnType = BuiltinTypesCatalogue.doubleItem; + this.currentMaxDouble = this.currentMaxDecimal.doubleValue(); + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble)) { + this.currentMaxDouble = Double.NaN; + } else if (candidateItemDouble > this.currentMaxDouble) { + this.currentMaxDouble = candidateItemDouble; + } + } else { + BigDecimal candidateItemDecimal = candidateItem.castToDecimalValue(); + if (candidateItemDecimal.compareTo(this.currentMaxDecimal) > 0) { + this.currentMaxDecimal = candidateItemDecimal; + this.returnType = candidateType; + } + } + + break; + case 3: + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare float with " + candidateType, + getMetadata() + ); + } + if (candidateItem.isDouble()) { + this.activeType = 4; + this.returnType = BuiltinTypesCatalogue.doubleItem; + this.currentMaxDouble = this.currentMaxFloat; + double candidateItemDouble = candidateItem.getDoubleValue(); + if (Double.isNaN(candidateItemDouble) || candidateItemDouble > this.currentMaxDouble) { + this.currentMaxDouble = candidateItemDouble; + } + } else { + if (!Float.isNaN(this.currentMaxFloat)) { + float candidateItemFloat = candidateItem.castToFloatValue(); + if (candidateItemFloat > this.currentMaxFloat) { + this.currentMaxFloat = candidateItemFloat; + } + } + } + + break; + case 4: + if (!candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare double with " + candidateType, + getMetadata() + ); + } + if (!Double.isNaN(this.currentMaxDouble)) { + double candidateItemDouble = candidateItem.castToDoubleValue(); + if (candidateItemDouble > this.currentMaxDouble) { + this.currentMaxDouble = candidateItemDouble; + } + } + break; + case 5: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare anyURI with " + candidateType, + getMetadata() + ); + } + if (candidateItem.isString()) { + this.activeType = 6; + this.returnType = BuiltinTypesCatalogue.stringItem; + } + if (this.comparator.compare(candidateItem, this.currentMax) > 0) { + this.currentMax = candidateItem; + } + break; + case 6: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare string with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMax) > 0) { + this.currentMax = candidateItem; + this.returnType = candidateType; + } + break; + case 7: + if (!candidateType.equals(this.returnType)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMax) > 0) { + this.currentMax = candidateItem; + } + break; + case 9: + if (candidateItem.isNumeric()) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (this.comparator.compare(candidateItem, this.currentMax) > 0) { + this.currentMax = candidateItem; + } + break; + default: + throw new OurBadException("Inconsistent state in state iteration"); + } - List results = this.iterator.materialize(context); - if (results.size() == 0) { - return null; } - try { - return itemTypePromotion(Collections.max(results, comparator)); - } catch (RumbleException e) { - RumbleException ex = new InvalidArgumentTypeException( - "Max expression input error. Input has to be non-null atomics of matching types.", - getMetadata() - ); - ex.initCause(e); - throw ex; + this.iterator.close(); + + Item itemResult; + switch (this.activeType) { + case 0: + return null; + case 1: + itemResult = ItemFactory.getInstance().createLongItem(this.currentMaxLong); + break; + case 2: + itemResult = ItemFactory.getInstance().createDecimalItem(this.currentMaxDecimal); + break; + case 3: + itemResult = ItemFactory.getInstance().createFloatItem(this.currentMaxFloat); + break; + case 4: + itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMaxDouble); + break; + case 5: + case 6: + case 7: + case 9: + itemResult = this.currentMax; + break; + default: + throw new OurBadException("Inconsistent state in state iteration"); } + return CastIterator.castItemToType(itemResult, this.returnType, getMetadata()); + } if (this.iterator.isDataFrame()) { @@ -114,8 +361,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (rdd.isEmpty()) { return null; } - this.result = rdd.max(comparator); - return itemTypePromotion(this.result); + this.result = rdd.max(this.comparator); + return this.result; } diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 03bb8a92ec..0aa73e0152 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -122,6 +122,12 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.activeType = 7; this.currentMin = candidateItem; } else { + if (candidateType.equals(BuiltinTypesCatalogue.durationItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } this.activeType = 9; this.currentMin = candidateItem; // throw new OurBadException("Inconsistent state in state iteration"); From 1b863c48fdc81c9f83ec615a025dc50c2d7861c4 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 27 Jul 2021 10:34:52 +0200 Subject: [PATCH 126/142] null handling. --- .../functions/sequences/aggregate/MaxFunctionIterator.java | 5 +++-- .../functions/sequences/aggregate/MinFunctionIterator.java | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index 80ed2ffd53..b6b633a202 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -87,9 +87,10 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.iterator.open(context); while (this.iterator.hasNext()) { Item candidateItem = this.iterator.next(); - + if (candidateItem.isNull()) { + continue; + } ItemType candidateType = candidateItem.getDynamicType(); - // Manage all types and make sure comparison are correct switch (this.activeType) { case 0: diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 0aa73e0152..97c1a5fb20 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -88,7 +88,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.iterator.open(context); while (this.iterator.hasNext()) { Item candidateItem = this.iterator.next(); - + if (candidateItem.isNull()) { + continue; + } ItemType candidateType = candidateItem.getDynamicType(); // Manage all types and make sure comparison are correct From d4766d2c5109d23b165200c0d471748475715971 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 27 Jul 2021 15:19:43 +0200 Subject: [PATCH 127/142] handle null for min. --- .../functions/sequences/aggregate/MinFunctionIterator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 97c1a5fb20..65b0723f5e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -89,7 +89,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { while (this.iterator.hasNext()) { Item candidateItem = this.iterator.next(); if (candidateItem.isNull()) { - continue; + return null; } ItemType candidateType = candidateItem.getDynamicType(); From c69d04ef62c14d1891430efa0d96282244e43f77 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Tue, 27 Jul 2021 15:19:43 +0200 Subject: [PATCH 128/142] handle null for min. --- .../functions/sequences/aggregate/MinFunctionIterator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 97c1a5fb20..6ee948732e 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -89,7 +89,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { while (this.iterator.hasNext()) { Item candidateItem = this.iterator.next(); if (candidateItem.isNull()) { - continue; + return ItemFactory.getInstance().createNullItem(); } ItemType candidateType = candidateItem.getDynamicType(); @@ -317,7 +317,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { Item itemResult; switch (this.activeType) { case 0: - return null; + return ItemFactory.getInstance().createNullItem(); case 1: itemResult = ItemFactory.getInstance().createLongItem(this.currentMinLong); break; From 73cec55b1366064df4bd67f111cf0abfc65ba393 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Wed, 28 Jul 2021 14:40:43 +0200 Subject: [PATCH 129/142] meeting update min --- .../functions/sequences/aggregate/MinFunctionIterator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 3b77ccc44a..9c8bedce92 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -259,7 +259,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } break; case 5: - if (candidateItem.isNumeric()) { + if (!candidateItem.isString() || !candidateItem.isAnyURI()) { throw new InvalidArgumentTypeException( "Cannot compare anyURI with " + candidateType, getMetadata() @@ -274,7 +274,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } break; case 6: - if (candidateItem.isNumeric()) { + if (!candidateItem.isString() && !candidateItem.isAnyURI()) { throw new InvalidArgumentTypeException( "Cannot compare string with " + candidateType, getMetadata() From 17d14c71cc9211d1ddaf8f0f88292df32c1071bd Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 29 Jul 2021 00:02:39 +0200 Subject: [PATCH 130/142] add all comparable types min. --- .../aggregate/MinFunctionIterator.java | 141 ++++++++++++++---- 1 file changed, 112 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index 9c8bedce92..a89388eda5 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -21,6 +21,9 @@ package org.rumbledb.runtime.functions.sequences.aggregate; import org.apache.spark.api.java.JavaRDD; +import org.joda.time.DateTime; +import org.joda.time.Instant; +import org.joda.time.Period; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; @@ -38,6 +41,8 @@ import sparksoniq.spark.SparkSessionManager; import java.math.BigDecimal; +import java.net.URI; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -51,6 +56,14 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private float currentMinFloat; private BigDecimal currentMinDecimal; private long currentMinLong; + private Item currentMinURI; + private String currentMinString; + private boolean currentMinBoolean; + private Date currentMinDate; + private DateTime currentMinDateTime; + private Period currentMinDayTimeDuration; + private Period currentMinYearMonthDuration; + private DateTime currentMinTime; private Item currentMin; private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long, 5 = anyURI, 6 = // String, 7 = other types (date types) @@ -88,6 +101,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.iterator.open(context); Item candidateItem = null; ItemType candidateType = null; + Instant now = null; while (this.iterator.hasNext()) { candidateItem = this.iterator.next(); if (candidateItem.isNull()) { @@ -112,28 +126,31 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.currentMinDouble = candidateItem.castToDoubleValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.anyURIItem)) { this.activeType = 5; - this.currentMin = candidateItem; + this.currentMinURI = candidateItem; } else if (candidateType.equals(BuiltinTypesCatalogue.stringItem)) { this.activeType = 6; - this.currentMin = candidateItem; - } else if ( - candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem) - || candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem) - || candidateType.equals(BuiltinTypesCatalogue.dateTimeItem) - || candidateType.equals(BuiltinTypesCatalogue.dateItem) - ) { + this.currentMinString = candidateItem.getStringValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.booleanItem)) { this.activeType = 7; - this.currentMin = candidateItem; - } else { - if (candidateType.equals(BuiltinTypesCatalogue.durationItem)) { - throw new InvalidArgumentTypeException( - "Cannot compare " + this.returnType + " with " + candidateType, - getMetadata() - ); - } + this.currentMinBoolean = candidateItem.getBooleanValue(); + } + else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { + this.activeType = 8; + this.currentMinDate = candidateItem.getDateTimeValue().toDate(); + } else if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.dateTimeItem)) { this.activeType = 9; - this.currentMin = candidateItem; - // throw new OurBadException("Inconsistent state in state iteration"); + this.currentMinDateTime = candidateItem.getDateTimeValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem)) { + this.activeType = 10; + this.currentMinDayTimeDuration = candidateItem.getDurationValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { + this.activeType = 11; + this.currentMinYearMonthDuration = candidateItem.getDurationValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.timeItem)) { + this.activeType = 12; + this.currentMinTime = candidateItem.getDateTimeValue(); + } else { + throw new OurBadException("Inconsistent state in state iteration"); } this.returnType = candidateType; break; @@ -268,9 +285,11 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (candidateItem.isString()) { this.activeType = 6; this.returnType = BuiltinTypesCatalogue.stringItem; - } - if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMin = candidateItem; + if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMinString = this.currentMinURI.getStringValue(); + } + } else if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + this.currentMinURI = candidateItem; } break; case 6: @@ -281,30 +300,76 @@ public Item materializeFirstItemOrNull(DynamicContext context) { ); } if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMin = candidateItem; + this.currentMinString = candidateItem.getStringValue(); this.returnType = candidateType; } break; case 7: - if (!candidateType.equals(this.returnType)) { + if (!candidateType.equals(BuiltinTypesCatalogue.booleanItem)) { throw new InvalidArgumentTypeException( "Cannot compare " + this.returnType + " with " + candidateType, getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMin = candidateItem; + if (Boolean.compare(candidateItem.getBooleanValue(), this.currentMinBoolean) < 0) { + this.currentMinBoolean = candidateItem.getBooleanValue(); + } + break; + case 8: + if (!candidateType.equals(BuiltinTypesCatalogue.dateItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateItem.getDateTimeValue().toDate().compareTo(this.currentMinDate) < 0) { + this.currentMinDate = candidateItem.getDateTimeValue().toDate(); } break; case 9: - if (candidateItem.isNumeric()) { + if (!candidateType.isSubtypeOf(BuiltinTypesCatalogue.dateTimeItem)) { throw new InvalidArgumentTypeException( "Cannot compare " + this.returnType + " with " + candidateType, getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMin = candidateItem; + if (candidateItem.getDateTimeValue().compareTo(this.currentMinDateTime) < 0) { + this.currentMinDateTime = candidateItem.getDateTimeValue(); + } + break; + case 10: + if (!candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + now = new Instant(); + if (candidateItem.getDurationValue().toDurationFrom(now).compareTo(this.currentMinDayTimeDuration.toDurationFrom(now)) < 0) { + this.currentMinDayTimeDuration = candidateItem.getDurationValue(); + } + break; + case 11: + if (!candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + now = new Instant(); + if (candidateItem.getDurationValue().toDurationFrom(now).compareTo(this.currentMinYearMonthDuration.toDurationFrom(now)) < 0) { + this.currentMinYearMonthDuration = candidateItem.getDurationValue(); + } + break; + case 12: + if (!candidateType.equals(BuiltinTypesCatalogue.timeItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateItem.getDateTimeValue().compareTo(this.currentMinTime) < 0) { + this.currentMinTime = candidateItem.getDateTimeValue(); } break; default: @@ -332,10 +397,28 @@ public Item materializeFirstItemOrNull(DynamicContext context) { itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMinDouble); break; case 5: + itemResult = this.currentMinURI; + break; case 6: + itemResult = ItemFactory.getInstance().createStringItem(this.currentMinString); + break; case 7: + itemResult = ItemFactory.getInstance().createBooleanItem(this.currentMinBoolean); + break; + case 8: + itemResult = ItemFactory.getInstance().createDateItem(this.currentMinDate.toString()); + break; case 9: - itemResult = this.currentMin; + itemResult = ItemFactory.getInstance().createDateTimeItem(this.currentMinDateTime.toString()); + break; + case 10: + itemResult = ItemFactory.getInstance().createDayTimeDurationItem(this.currentMinDayTimeDuration); + break; + case 11: + itemResult = ItemFactory.getInstance().createYearMonthDurationItem(this.currentMinYearMonthDuration); + break; + case 12: + itemResult = ItemFactory.getInstance().createTimeItem(this.currentMinTime.toString()); break; default: throw new OurBadException("Inconsistent state in state iteration"); From 26b79afcdf2b0592fec15f2e1f34d7b9102d25c3 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Thu, 29 Jul 2021 23:26:48 +0200 Subject: [PATCH 131/142] Cleaner min and max. --- .../aggregate/MaxFunctionIterator.java | 184 ++++++++++++++---- .../aggregate/MinFunctionIterator.java | 74 ++++--- 2 files changed, 190 insertions(+), 68 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index b6b633a202..8a2c6953d2 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -21,6 +21,9 @@ package org.rumbledb.runtime.functions.sequences.aggregate; import org.apache.spark.api.java.JavaRDD; +import org.joda.time.DateTime; +import org.joda.time.Instant; +import org.joda.time.Period; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; @@ -51,13 +54,21 @@ public class MaxFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private float currentMaxFloat; private BigDecimal currentMaxDecimal; private long currentMaxLong; - private Item currentMax; - private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long, 5 = anyURI, 6 = - // String, 7 = other types (date types) + private String currentMaxURI; + private String currentMaxString; + private boolean currentMaxBoolean; + private boolean hasTimeZone = false; + private DateTime currentMaxDate; // TODO: Change to Date type but had issues with Java compiler + private DateTime currentMaxDateTime; + private Period currentMaxDayTimeDuration; + private Period currentMaxYearMonthDuration; + private DateTime currentMaxTime; + private byte activeType = 0; private ItemType returnType; private Item result; private ItemComparator comparator; + public MaxFunctionIterator( List arguments, ExecutionMode executionMode, @@ -66,7 +77,7 @@ public MaxFunctionIterator( super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); this.comparator = new ItemComparator( - false, + true, new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types", getMetadata() @@ -85,16 +96,17 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (!this.iterator.isRDDOrDataFrame()) { this.iterator.open(context); + Item candidateItem = null; + ItemType candidateType = null; + Instant now = null; while (this.iterator.hasNext()) { - Item candidateItem = this.iterator.next(); + candidateItem = this.iterator.next(); if (candidateItem.isNull()) { - continue; + return ItemFactory.getInstance().createNullItem(); } - ItemType candidateType = candidateItem.getDynamicType(); - // Manage all types and make sure comparison are correct + candidateType = candidateItem.getDynamicType(); switch (this.activeType) { case 0: - // initialization, take whatever first type if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { this.activeType = 1; this.currentMaxLong = candidateItem.castToDecimalValue().longValue(); @@ -109,28 +121,39 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.currentMaxDouble = candidateItem.castToDoubleValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.anyURIItem)) { this.activeType = 5; - this.currentMax = candidateItem; + this.currentMaxURI = candidateItem.getStringValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.stringItem)) { this.activeType = 6; - this.currentMax = candidateItem; - } else if ( - candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem) - || candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem) - || candidateType.equals(BuiltinTypesCatalogue.dateTimeItem) - || candidateType.equals(BuiltinTypesCatalogue.dateItem) - ) { + this.currentMaxString = candidateItem.getStringValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.booleanItem)) { this.activeType = 7; - this.currentMax = candidateItem; - } else { - if (candidateType.equals(BuiltinTypesCatalogue.durationItem)) { - throw new InvalidArgumentTypeException( - "Cannot compare " + this.returnType + " with " + candidateType, - getMetadata() - ); + this.currentMaxBoolean = candidateItem.getBooleanValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { + this.activeType = 8; + this.currentMaxDate = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; } + } else if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.dateTimeItem)) { this.activeType = 9; - this.currentMax = candidateItem; - // throw new OurBadException("Inconsistent state in state iteration"); + this.currentMaxDateTime = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; + } + } else if (candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem)) { + this.activeType = 10; + this.currentMaxDayTimeDuration = candidateItem.getDurationValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { + this.activeType = 11; + this.currentMaxYearMonthDuration = candidateItem.getDurationValue(); + } else if (candidateType.equals(BuiltinTypesCatalogue.timeItem)) { + this.activeType = 12; + this.currentMaxTime = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; + } + } else { + throw new OurBadException("Inconsistent state in state iteration"); } this.returnType = candidateType; break; @@ -256,7 +279,7 @@ public Item materializeFirstItemOrNull(DynamicContext context) { } break; case 5: - if (candidateItem.isNumeric()) { + if (!candidateItem.isString() && !candidateItem.isAnyURI()) { throw new InvalidArgumentTypeException( "Cannot compare anyURI with " + candidateType, getMetadata() @@ -265,43 +288,104 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (candidateItem.isString()) { this.activeType = 6; this.returnType = BuiltinTypesCatalogue.stringItem; - } - if (this.comparator.compare(candidateItem, this.currentMax) > 0) { - this.currentMax = candidateItem; + this.currentMaxString = this.currentMaxURI; + if (candidateItem.getStringValue().compareTo(this.currentMaxURI) > 0) { + this.currentMaxString = candidateItem.getStringValue(); + } + } else if (candidateItem.getStringValue().compareTo(this.currentMaxURI) > 0) { + this.currentMaxURI = candidateItem.getStringValue(); + } break; case 6: - if (candidateItem.isNumeric()) { + if (!candidateItem.isString() && !candidateItem.isAnyURI()) { throw new InvalidArgumentTypeException( "Cannot compare string with " + candidateType, getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMax) > 0) { - this.currentMax = candidateItem; + if (candidateItem.getStringValue().compareTo(this.currentMaxString) > 0) { + this.currentMaxString = candidateItem.getStringValue(); this.returnType = candidateType; } break; case 7: - if (!candidateType.equals(this.returnType)) { + if (!candidateType.equals(BuiltinTypesCatalogue.booleanItem)) { throw new InvalidArgumentTypeException( "Cannot compare " + this.returnType + " with " + candidateType, getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMax) > 0) { - this.currentMax = candidateItem; + if (Boolean.compare(candidateItem.getBooleanValue(), this.currentMaxBoolean) > 0) { + this.currentMaxBoolean = candidateItem.getBooleanValue(); + } + break; + case 8: + if (!candidateType.equals(BuiltinTypesCatalogue.dateItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateItem.getDateTimeValue().toDate().compareTo(this.currentMaxDate.toDate()) > 0) { + this.currentMaxDate = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); } break; case 9: - if (candidateItem.isNumeric()) { + if (!candidateType.isSubtypeOf(BuiltinTypesCatalogue.dateTimeItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateItem.getDateTimeValue().compareTo(this.currentMaxDateTime) > 0) { + this.currentMaxDateTime = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); + } + break; + case 10: + if (!candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem)) { throw new InvalidArgumentTypeException( "Cannot compare " + this.returnType + " with " + candidateType, getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMax) > 0) { - this.currentMax = candidateItem; + now = new Instant(); + if ( + candidateItem.getDurationValue() + .toDurationFrom(now) + .compareTo(this.currentMaxDayTimeDuration.toDurationFrom(now)) > 0 + ) { + this.currentMaxDayTimeDuration = candidateItem.getDurationValue(); + } + break; + case 11: + if (!candidateType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + now = new Instant(); + if ( + candidateItem.getDurationValue() + .toDurationFrom(now) + .compareTo(this.currentMaxYearMonthDuration.toDurationFrom(now)) > 0 + ) { + this.currentMaxYearMonthDuration = candidateItem.getDurationValue(); + } + break; + case 12: + if (!candidateType.equals(BuiltinTypesCatalogue.timeItem)) { + throw new InvalidArgumentTypeException( + "Cannot compare " + this.returnType + " with " + candidateType, + getMetadata() + ); + } + if (candidateItem.getDateTimeValue().compareTo(this.currentMaxTime) > 0) { + this.currentMaxTime = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); } break; default: @@ -329,10 +413,30 @@ public Item materializeFirstItemOrNull(DynamicContext context) { itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMaxDouble); break; case 5: + itemResult = ItemFactory.getInstance().createAnyURIItem(this.currentMaxURI); + break; case 6: + itemResult = ItemFactory.getInstance().createStringItem(this.currentMaxString); + break; case 7: + itemResult = ItemFactory.getInstance().createBooleanItem(this.currentMaxBoolean); + break; + case 8: + itemResult = ItemFactory.getInstance().createDateItem(this.currentMaxDate, this.hasTimeZone); + break; case 9: - itemResult = this.currentMax; + itemResult = ItemFactory.getInstance() + .createDateTimeItem(this.currentMaxDateTime, this.hasTimeZone); + break; + case 10: + itemResult = ItemFactory.getInstance().createDayTimeDurationItem(this.currentMaxDayTimeDuration); + break; + case 11: + itemResult = ItemFactory.getInstance() + .createYearMonthDurationItem(this.currentMaxYearMonthDuration); + break; + case 12: + itemResult = ItemFactory.getInstance().createTimeItem(this.currentMaxTime, this.hasTimeZone); break; default: throw new OurBadException("Inconsistent state in state iteration"); diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java index a89388eda5..72b9394c54 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MinFunctionIterator.java @@ -41,8 +41,6 @@ import sparksoniq.spark.SparkSessionManager; import java.math.BigDecimal; -import java.net.URI; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -56,17 +54,16 @@ public class MinFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private float currentMinFloat; private BigDecimal currentMinDecimal; private long currentMinLong; - private Item currentMinURI; + private String currentMinURI; private String currentMinString; private boolean currentMinBoolean; - private Date currentMinDate; + private boolean hasTimeZone = false; + private DateTime currentMinDate; // TODO: Change to Date type but had issues with Java compiler private DateTime currentMinDateTime; private Period currentMinDayTimeDuration; private Period currentMinYearMonthDuration; private DateTime currentMinTime; - private Item currentMin; - private byte activeType = 0; // 0 = unknown/init 1 = long, 2 = BigDecimal, 3 = float, 4 = long, 5 = anyURI, 6 = - // String, 7 = other types (date types) + private byte activeType = 0; private ItemType returnType; private Item result; private ItemComparator comparator; @@ -108,10 +105,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { return ItemFactory.getInstance().createNullItem(); } candidateType = candidateItem.getDynamicType(); - // Manage all types and make sure comparison are correct switch (this.activeType) { case 0: - // initialization, take whatever first type if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.longItem)) { this.activeType = 1; this.currentMinLong = candidateItem.castToDecimalValue().longValue(); @@ -126,20 +121,25 @@ public Item materializeFirstItemOrNull(DynamicContext context) { this.currentMinDouble = candidateItem.castToDoubleValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.anyURIItem)) { this.activeType = 5; - this.currentMinURI = candidateItem; + this.currentMinURI = candidateItem.getStringValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.stringItem)) { this.activeType = 6; this.currentMinString = candidateItem.getStringValue(); } else if (candidateType.equals(BuiltinTypesCatalogue.booleanItem)) { this.activeType = 7; this.currentMinBoolean = candidateItem.getBooleanValue(); - } - else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { + } else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { this.activeType = 8; - this.currentMinDate = candidateItem.getDateTimeValue().toDate(); + this.currentMinDate = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; + } } else if (candidateType.isSubtypeOf(BuiltinTypesCatalogue.dateTimeItem)) { this.activeType = 9; this.currentMinDateTime = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; + } } else if (candidateType.equals(BuiltinTypesCatalogue.dayTimeDurationItem)) { this.activeType = 10; this.currentMinDayTimeDuration = candidateItem.getDurationValue(); @@ -149,6 +149,9 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { } else if (candidateType.equals(BuiltinTypesCatalogue.timeItem)) { this.activeType = 12; this.currentMinTime = candidateItem.getDateTimeValue(); + if (candidateItem.hasTimeZone()) { + this.hasTimeZone = true; + } } else { throw new OurBadException("Inconsistent state in state iteration"); } @@ -276,7 +279,7 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { } break; case 5: - if (!candidateItem.isString() || !candidateItem.isAnyURI()) { + if (!candidateItem.isString() && !candidateItem.isAnyURI()) { throw new InvalidArgumentTypeException( "Cannot compare anyURI with " + candidateType, getMetadata() @@ -285,11 +288,13 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { if (candidateItem.isString()) { this.activeType = 6; this.returnType = BuiltinTypesCatalogue.stringItem; - if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMinString = this.currentMinURI.getStringValue(); + this.currentMinString = this.currentMinURI; + if (candidateItem.getStringValue().compareTo(this.currentMinURI) < 0) { + this.currentMinString = candidateItem.getStringValue(); } - } else if (this.comparator.compare(candidateItem, this.currentMin) < 0) { - this.currentMinURI = candidateItem; + } else if (candidateItem.getStringValue().compareTo(this.currentMinURI) < 0) { + this.currentMinURI = candidateItem.getStringValue(); + } break; case 6: @@ -299,7 +304,7 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { getMetadata() ); } - if (this.comparator.compare(candidateItem, this.currentMin) < 0) { + if (candidateItem.getStringValue().compareTo(this.currentMinString) < 0) { this.currentMinString = candidateItem.getStringValue(); this.returnType = candidateType; } @@ -322,8 +327,9 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { getMetadata() ); } - if (candidateItem.getDateTimeValue().toDate().compareTo(this.currentMinDate) < 0) { - this.currentMinDate = candidateItem.getDateTimeValue().toDate(); + if (candidateItem.getDateTimeValue().toDate().compareTo(this.currentMinDate.toDate()) < 0) { + this.currentMinDate = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); } break; case 9: @@ -335,6 +341,7 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { } if (candidateItem.getDateTimeValue().compareTo(this.currentMinDateTime) < 0) { this.currentMinDateTime = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); } break; case 10: @@ -345,7 +352,11 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { ); } now = new Instant(); - if (candidateItem.getDurationValue().toDurationFrom(now).compareTo(this.currentMinDayTimeDuration.toDurationFrom(now)) < 0) { + if ( + candidateItem.getDurationValue() + .toDurationFrom(now) + .compareTo(this.currentMinDayTimeDuration.toDurationFrom(now)) < 0 + ) { this.currentMinDayTimeDuration = candidateItem.getDurationValue(); } break; @@ -357,7 +368,11 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { ); } now = new Instant(); - if (candidateItem.getDurationValue().toDurationFrom(now).compareTo(this.currentMinYearMonthDuration.toDurationFrom(now)) < 0) { + if ( + candidateItem.getDurationValue() + .toDurationFrom(now) + .compareTo(this.currentMinYearMonthDuration.toDurationFrom(now)) < 0 + ) { this.currentMinYearMonthDuration = candidateItem.getDurationValue(); } break; @@ -370,6 +385,7 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { } if (candidateItem.getDateTimeValue().compareTo(this.currentMinTime) < 0) { this.currentMinTime = candidateItem.getDateTimeValue(); + this.hasTimeZone = candidateItem.hasTimeZone(); } break; default: @@ -397,7 +413,7 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { itemResult = ItemFactory.getInstance().createDoubleItem(this.currentMinDouble); break; case 5: - itemResult = this.currentMinURI; + itemResult = ItemFactory.getInstance().createAnyURIItem(this.currentMinURI); break; case 6: itemResult = ItemFactory.getInstance().createStringItem(this.currentMinString); @@ -406,19 +422,21 @@ else if (candidateType.equals(BuiltinTypesCatalogue.dateItem)) { itemResult = ItemFactory.getInstance().createBooleanItem(this.currentMinBoolean); break; case 8: - itemResult = ItemFactory.getInstance().createDateItem(this.currentMinDate.toString()); + itemResult = ItemFactory.getInstance().createDateItem(this.currentMinDate, this.hasTimeZone); break; case 9: - itemResult = ItemFactory.getInstance().createDateTimeItem(this.currentMinDateTime.toString()); + itemResult = ItemFactory.getInstance() + .createDateTimeItem(this.currentMinDateTime, this.hasTimeZone); break; case 10: itemResult = ItemFactory.getInstance().createDayTimeDurationItem(this.currentMinDayTimeDuration); break; case 11: - itemResult = ItemFactory.getInstance().createYearMonthDurationItem(this.currentMinYearMonthDuration); + itemResult = ItemFactory.getInstance() + .createYearMonthDurationItem(this.currentMinYearMonthDuration); break; case 12: - itemResult = ItemFactory.getInstance().createTimeItem(this.currentMinTime.toString()); + itemResult = ItemFactory.getInstance().createTimeItem(this.currentMinTime, this.hasTimeZone); break; default: throw new OurBadException("Inconsistent state in state iteration"); From 4fb38febac2f07ce05f1f1b1978ee7052b641236 Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 30 Jul 2021 18:00:25 +0200 Subject: [PATCH 132/142] fix max with null. --- .../sequences/aggregate/MaxFunctionIterator.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java index 8a2c6953d2..2075208927 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/aggregate/MaxFunctionIterator.java @@ -50,6 +50,7 @@ public class MaxFunctionIterator extends AtMostOneItemLocalRuntimeIterator { private static final long serialVersionUID = 1L; private RuntimeIterator iterator; + private boolean currentMinIsNullItem = false; // Only happens if all elements are null private double currentMaxDouble; private float currentMaxFloat; private BigDecimal currentMaxDecimal; @@ -77,7 +78,7 @@ public MaxFunctionIterator( super(arguments, executionMode, iteratorMetadata); this.iterator = this.children.get(0); this.comparator = new ItemComparator( - true, + false, new InvalidArgumentTypeException( "Max expression input error. Input has to be non-null atomics of matching types", getMetadata() @@ -102,7 +103,8 @@ public Item materializeFirstItemOrNull(DynamicContext context) { while (this.iterator.hasNext()) { candidateItem = this.iterator.next(); if (candidateItem.isNull()) { - return ItemFactory.getInstance().createNullItem(); + this.currentMinIsNullItem = true; + continue; } candidateType = candidateItem.getDynamicType(); switch (this.activeType) { @@ -399,6 +401,9 @@ public Item materializeFirstItemOrNull(DynamicContext context) { Item itemResult; switch (this.activeType) { case 0: + if (this.currentMinIsNullItem) { + return ItemFactory.getInstance().createNullItem(); + } return null; case 1: itemResult = ItemFactory.getInstance().createLongItem(this.currentMaxLong); From 6b597cd92f325a51a152585d68f03fba236984db Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 30 Jul 2021 18:43:03 +0200 Subject: [PATCH 133/142] add fn:dateTime. --- .../context/BuiltinFunctionCatalogue.java | 23 ++++++-- .../datetime/DateTimeFunctionIterator.java | 59 +++++++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java diff --git a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java index 55a660728b..6022df48af 100644 --- a/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java +++ b/src/main/java/org/rumbledb/context/BuiltinFunctionCatalogue.java @@ -16,12 +16,7 @@ import org.rumbledb.runtime.functions.booleans.TrueFunctionIterator; import org.rumbledb.runtime.functions.context.LastFunctionIterator; import org.rumbledb.runtime.functions.context.PositionFunctionIterator; -import org.rumbledb.runtime.functions.datetime.CurrentDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.CurrentDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.CurrentTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.FormatDateFunctionIterator; -import org.rumbledb.runtime.functions.datetime.FormatDateTimeFunctionIterator; -import org.rumbledb.runtime.functions.datetime.FormatTimeFunctionIterator; +import org.rumbledb.runtime.functions.datetime.*; import org.rumbledb.runtime.functions.datetime.components.AdjustDateTimeToTimezone; import org.rumbledb.runtime.functions.datetime.components.AdjustDateToTimezone; import org.rumbledb.runtime.functions.datetime.components.AdjustTimeToTimezone; @@ -1859,6 +1854,21 @@ private static BuiltinFunction createBuiltinFunction( FormatDateTimeFunctionIterator.class, BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL ); + /** + * function that returns a xs:dateTime value created by combining an xs:date and an xs:time + */ + static final BuiltinFunction dateTime = createBuiltinFunction( + new Name( + Name.FN_NS, + "fn", + "dateTime" + ), + "date?", + "time?", + "dateTime?", + DateTimeFunctionIterator.class, + BuiltinFunction.BuiltinFunctionExecutionMode.LOCAL + ); /** * function that returns the year from a dateTime */ @@ -2643,6 +2653,7 @@ private static BuiltinFunction createBuiltinFunction( builtinFunctions.put(current_dateTime.getIdentifier(), current_dateTime); builtinFunctions.put(format_dateTime.getIdentifier(), format_dateTime); + builtinFunctions.put(dateTime.getIdentifier(), dateTime); builtinFunctions.put(year_from_dateTime.getIdentifier(), year_from_dateTime); builtinFunctions.put(month_from_dateTime.getIdentifier(), month_from_dateTime); builtinFunctions.put(day_from_dateTime.getIdentifier(), day_from_dateTime); diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java new file mode 100644 index 0000000000..000b7597a4 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java @@ -0,0 +1,59 @@ +package org.rumbledb.runtime.functions.datetime; + +import org.joda.time.DateTime; +import org.rumbledb.api.Item; +import org.rumbledb.context.DynamicContext; +import org.rumbledb.exceptions.*; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; +import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class DateTimeFunctionIterator extends AtMostOneItemLocalRuntimeIterator { + + private static final long serialVersionUID = 1L; + private Item dateItem = null; + private Item timeItem = null; + + public DateTimeFunctionIterator( + List arguments, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + super(arguments, executionMode, iteratorMetadata); + } + + @Override + public Item materializeFirstItemOrNull(DynamicContext context) { + this.dateItem = this.children.get(0) + .materializeFirstItemOrNull(context); + this.timeItem = this.children.get(1) + .materializeFirstItemOrNull(context); + if (this.dateItem == null || this.timeItem == null) { + return null; + } + DateTime dt = new DateTime(this.dateItem.getDateTimeValue()).withTime( + this.timeItem.getDateTimeValue().toLocalTime() + ); + if (this.dateItem.hasTimeZone() && this.timeItem.hasTimeZone()) { + if (this.dateItem.getDateTimeValue().getZone() == this.timeItem.getDateTimeValue().getZone()) { + return ItemFactory.getInstance().createDateTimeItem(dt, true); + } else { + throw new InvalidTimezoneException("The two arguments have inconsistent timezones", getMetadata()); + } + } else if (this.dateItem.hasTimeZone() && !this.timeItem.hasTimeZone()) { + dt = dt.withZone(this.dateItem.getDateTimeValue().getZone()); + return ItemFactory.getInstance().createDateTimeItem(dt, true); + } else if (!this.dateItem.hasTimeZone() && this.timeItem.hasTimeZone()) { + dt = dt.withZone(this.dateItem.getDateTimeValue().getZone()); + return ItemFactory.getInstance().createDateTimeItem(dt, true); + } + + return ItemFactory.getInstance().createDateTimeItem(dt, false); + + } + + +} From cc48f1dfdf1f188690875b4398aafa8f2184c1ea Mon Sep 17 00:00:00 2001 From: Pierre Motard Date: Fri, 30 Jul 2021 19:14:25 +0200 Subject: [PATCH 134/142] fix fn:dateTime, add inconsistent timezone exception. --- .../org/rumbledb/errorcodes/ErrorCode.java | 1 + .../InconsistentTimezonesException.java | 32 +++++++++++++++++++ .../datetime/DateTimeFunctionIterator.java | 29 +++++++++++------ 3 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/rumbledb/exceptions/InconsistentTimezonesException.java diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 138d505273..33521ffe5d 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -37,6 +37,7 @@ public enum ErrorCode { OneOrMoreErrorCode("FORG0004"), ExactlyOneErrorCode("FORG0005"), InvalidArgumentType("FORG0006"), + InconsistentTimezones("FORG0008"), InvalidRegexPatternErrorCode("FORX0002"), MatchesEmptyStringErrorCode("FORX0003"), InvalidReplacementStringErrorCode("FORX0004"), diff --git a/src/main/java/org/rumbledb/exceptions/InconsistentTimezonesException.java b/src/main/java/org/rumbledb/exceptions/InconsistentTimezonesException.java new file mode 100644 index 0000000000..9d552ae6a0 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/InconsistentTimezonesException.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Stefan Irimescu, Can Berker Cikis + * + */ + +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class InconsistentTimezonesException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public InconsistentTimezonesException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.InconsistentTimezones, metadata); + } +} diff --git a/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java b/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java index 000b7597a4..066b719ca8 100644 --- a/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/datetime/DateTimeFunctionIterator.java @@ -34,23 +34,34 @@ public Item materializeFirstItemOrNull(DynamicContext context) { if (this.dateItem == null || this.timeItem == null) { return null; } - DateTime dt = new DateTime(this.dateItem.getDateTimeValue()).withTime( - this.timeItem.getDateTimeValue().toLocalTime() - ); + DateTime dt = null; + DateTime dateDt = this.dateItem.getDateTimeValue(); + DateTime timeDt = this.timeItem.getDateTimeValue(); + if (this.dateItem.hasTimeZone() && this.timeItem.hasTimeZone()) { - if (this.dateItem.getDateTimeValue().getZone() == this.timeItem.getDateTimeValue().getZone()) { + if (dateDt.getZone() == timeDt.getZone()) { + dt = new DateTime().withZone(dateDt.getZone()) + .withDate(dateDt.toLocalDate()) + .withTime(timeDt.toLocalTime()); return ItemFactory.getInstance().createDateTimeItem(dt, true); } else { - throw new InvalidTimezoneException("The two arguments have inconsistent timezones", getMetadata()); + throw new InconsistentTimezonesException( + "The two arguments have inconsistent timezones", + getMetadata() + ); } } else if (this.dateItem.hasTimeZone() && !this.timeItem.hasTimeZone()) { - dt = dt.withZone(this.dateItem.getDateTimeValue().getZone()); + dt = new DateTime().withZone(dateDt.getZone()) + .withDate(dateDt.toLocalDate()) + .withTime(timeDt.toLocalTime()); return ItemFactory.getInstance().createDateTimeItem(dt, true); } else if (!this.dateItem.hasTimeZone() && this.timeItem.hasTimeZone()) { - dt = dt.withZone(this.dateItem.getDateTimeValue().getZone()); - return ItemFactory.getInstance().createDateTimeItem(dt, true); + dt = new DateTime().withZone(timeDt.getZone()) + .withDate(dateDt.toLocalDate()) + .withTime(timeDt.toLocalTime()); + return ItemFactory.getInstance().createDateTimeItem(dt.withTime(timeDt.toLocalTime()), true); } - + dt = new DateTime(dateDt).withTime(timeDt.toLocalTime()); return ItemFactory.getInstance().createDateTimeItem(dt, false); } From fcaede154e5b6ae9737d1b259452d38caa5dcee8 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 25 Aug 2021 12:46:34 +0200 Subject: [PATCH 135/142] Fix. --- .../cardinality/ExactlyOneIterator.java | 1 - .../rumbledb/types/BuiltinTypesCatalogue.java | 1 - .../java/org/rumbledb/types/SequenceType.java | 20 +------------------ 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java index 0536c7665a..180130f114 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ExactlyOneIterator.java @@ -63,7 +63,6 @@ public Item materializeFirstItemOrNull(DynamicContext dynamicContext) { getMetadata() ); } - } @Override diff --git a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java index e0279a9691..b14aed8283 100644 --- a/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java +++ b/src/main/java/org/rumbledb/types/BuiltinTypesCatalogue.java @@ -247,7 +247,6 @@ public class BuiltinTypesCatalogue { ) ) ); - public static final ItemType hexBinaryItem = new AtomicItemType( new Name(Name.XS_NS, "xs", "hexBinary"), new HashSet<>( diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index db7de85d0f..209c3be71f 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -21,7 +21,6 @@ package org.rumbledb.types; import org.rumbledb.context.DynamicContext; -import org.rumbledb.context.Name; import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; @@ -313,8 +312,7 @@ public String toString() { return "()"; } StringBuilder result = new StringBuilder(); - Name name = this.getItemType().getName(); - result.append(name != null ? name : ""); + result.append(this.getItemType().toString()); result.append(this.arity.getSymbol()); return result.toString(); } @@ -421,22 +419,6 @@ public String toString() { sequenceTypes.put("time?", new SequenceType(BuiltinTypesCatalogue.timeItem, SequenceType.Arity.OneOrZero)); - sequenceTypes.put("gDay?", new SequenceType(BuiltinTypesCatalogue.gDayItem, SequenceType.Arity.OneOrZero)); - - sequenceTypes.put("gMonth?", new SequenceType(BuiltinTypesCatalogue.gMonthItem, SequenceType.Arity.OneOrZero)); - - sequenceTypes.put("gYear?", new SequenceType(BuiltinTypesCatalogue.gYearItem, SequenceType.Arity.OneOrZero)); - - sequenceTypes.put( - "gMonthDay?", - new SequenceType(BuiltinTypesCatalogue.gMonthDayItem, SequenceType.Arity.OneOrZero) - ); - - sequenceTypes.put( - "gYearMonth?", - new SequenceType(BuiltinTypesCatalogue.gYearMonthItem, SequenceType.Arity.OneOrZero) - ); - sequenceTypes.put("anyURI", new SequenceType(BuiltinTypesCatalogue.anyURIItem)); sequenceTypes.put("anyURI?", new SequenceType(BuiltinTypesCatalogue.anyURIItem, SequenceType.Arity.OneOrZero)); From f559f4776f4acc3c4dc0bbd360b51e1d01ce46d2 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 31 Aug 2021 13:58:07 +0200 Subject: [PATCH 136/142] Remove import. --- .../functions/sequences/cardinality/ZeroOrOneIterator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java index 195a7c9f36..1101974b3c 100644 --- a/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java +++ b/src/main/java/org/rumbledb/runtime/functions/sequences/cardinality/ZeroOrOneIterator.java @@ -26,7 +26,6 @@ import org.rumbledb.exceptions.MoreThanOneItemException; import org.rumbledb.exceptions.SequenceExceptionZeroOrOne; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.AtMostOneItemLocalRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; From 49fd5361d624719f22c88dad4749bfd90cb1561b Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 8 Sep 2021 17:11:20 +0200 Subject: [PATCH 137/142] Remove change. --- .../java/org/rumbledb/types/SequenceType.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/types/SequenceType.java b/src/main/java/org/rumbledb/types/SequenceType.java index 209c3be71f..d958db60c7 100644 --- a/src/main/java/org/rumbledb/types/SequenceType.java +++ b/src/main/java/org/rumbledb/types/SequenceType.java @@ -21,6 +21,7 @@ package org.rumbledb.types; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; @@ -312,7 +313,8 @@ public String toString() { return "()"; } StringBuilder result = new StringBuilder(); - result.append(this.getItemType().toString()); + Name name = this.getItemType().getName(); + result.append(name != null ? name : ""); result.append(this.arity.getSymbol()); return result.toString(); } @@ -419,6 +421,18 @@ public String toString() { sequenceTypes.put("time?", new SequenceType(BuiltinTypesCatalogue.timeItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put("gDay?", new SequenceType(BuiltinTypesCatalogue.gDayItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put("gMonth?", new SequenceType(BuiltinTypesCatalogue.gMonthItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put("gYear?", new SequenceType(BuiltinTypesCatalogue.gYearItem, SequenceType.Arity.OneOrZero)); + sequenceTypes.put( + "gMonthDay?", + new SequenceType(BuiltinTypesCatalogue.gMonthDayItem, SequenceType.Arity.OneOrZero) + ); + sequenceTypes.put( + "gYearMonth?", + new SequenceType(BuiltinTypesCatalogue.gYearMonthItem, SequenceType.Arity.OneOrZero) + ); + sequenceTypes.put("anyURI", new SequenceType(BuiltinTypesCatalogue.anyURIItem)); sequenceTypes.put("anyURI?", new SequenceType(BuiltinTypesCatalogue.anyURIItem, SequenceType.Arity.OneOrZero)); From d290d10ce9d4541a9a00ebdece264fa7b44e2274 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 8 Sep 2021 17:12:18 +0200 Subject: [PATCH 138/142] Remove changes. --- .../rumbledb/runtime/typing/CastIterator.java | 74 +------------------ 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java index 662dbc9ede..d1b05e4729 100644 --- a/src/main/java/org/rumbledb/runtime/typing/CastIterator.java +++ b/src/main/java/org/rumbledb/runtime/typing/CastIterator.java @@ -265,6 +265,7 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return new AnnotatedItem(result, targetType); } + if (targetType.isSubtypeOf(BuiltinTypesCatalogue.decimalItem)) { if (item.isString()) { result = ItemFactory.getInstance().createDecimalItem(item.castToDecimalValue()); @@ -335,36 +336,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return new AnnotatedItem(result, targetType); } - if (targetType.isSubtypeOf(BuiltinTypesCatalogue.intItem)) { - if (!item.isString() && !item.isNumeric()) { - return null; - } - if (item.isInt()) { - return checkFacetsInt(item, targetType, true); - } - - Item intItem = castItemToType(item, BuiltinTypesCatalogue.intItem, metadata); - if (intItem == null) { - return null; - } - return checkFacetsInt(intItem, targetType, true); - } - - if (targetType.isSubtypeOf(BuiltinTypesCatalogue.integerItem)) { - if (!item.isString() && !item.isNumeric()) { - return null; - } - if (item.isInteger()) { - return checkFacetsInteger(item, targetType, true); - } - - Item integerItem = castItemToType(item, BuiltinTypesCatalogue.integerItem, metadata); - if (integerItem == null) { - return null; - } - return checkFacetsInteger(integerItem, targetType, true); - } - if (targetType.equals(BuiltinTypesCatalogue.dateItem)) { if (item.isString()) { result = ItemFactory.getInstance().createDateItem(item.getStringValue().trim()); @@ -437,18 +408,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad } return new AnnotatedItem(result, targetType); } - if (targetType.equals(BuiltinTypesCatalogue.dateTimeStampItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getStringValue().trim()); - } - if (item.isDate()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), false); - } - if (item.isDateTime()) { - return ItemFactory.getInstance().createDateTimeStampItem(item.getDateTimeValue(), true); - } - return null; - } if (targetType.equals(BuiltinTypesCatalogue.yearMonthDurationItem)) { if (item.isString()) { return ItemFactory.getInstance() @@ -575,37 +534,6 @@ public static Item castItemToType(Item item, ItemType targetType, ExceptionMetad return new AnnotatedItem(result, targetType); } - if (targetType.equals(BuiltinTypesCatalogue.gDayItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createGDayItem(item.getStringValue().trim()); - } - return null; - } - if (targetType.equals(BuiltinTypesCatalogue.gMonthItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createGMonthItem(item.getStringValue().trim()); - } - return null; - } - if (targetType.equals(BuiltinTypesCatalogue.gYearItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createGYearItem(item.getStringValue().trim()); - } - return null; - } - if (targetType.equals(BuiltinTypesCatalogue.gMonthDayItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createGMonthDayItem(item.getStringValue().trim()); - } - return null; - } - if (targetType.equals(BuiltinTypesCatalogue.gYearMonthItem)) { - if (item.isString()) { - return ItemFactory.getInstance().createGYearMonthItem(item.getStringValue().trim()); - } - return null; - } - return null; } catch (InvalidLexicalValueException i) { throw new InvalidLexicalValueException( From 698fd70ade298ffa67702a1bf9c5eb59e442b824 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 8 Sep 2021 17:15:28 +0200 Subject: [PATCH 139/142] Revert tests. --- .../RumbleML/MLPipeline1.jq.deactivated | 29 --------------- .../RumbleML/MLPipeline2.jq.deactivated | 29 --------------- .../RumbleML/MLPipeline3.jq.deactivated | 36 ------------------- .../RumbleML/MLPipeline4.jq.deactivated | 29 --------------- .../RumbleML/MLPipeline5.jq.deactivated | 23 ------------ .../RumbleML/MLPipeline6.jq.deactivated | 24 ------------- 6 files changed, 170 deletions(-) delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated delete mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated deleted file mode 100644 index 62d29dfd5d..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq.deactivated +++ /dev/null @@ -1,29 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) -let $vector-assembler := get-transformer("VectorAssembler") -let $training-data := ( - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -) -let $test-data := ( - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -) -let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) -let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) -let $est := get-estimator("PCA") -let $my-training-data := $vector-assembler($my-training-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) -let $trained_est := $est($my-training-data, - {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) -let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) -let $est2 := get-estimator("LogisticRegression") -let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) -let $my-test-data := $vector-assembler($my-test-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) -let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) -for $i in $trained_est2( - $my-new-test-data, - {"featuresCol": "features2", "predictionCol": "ocol1"} -) -return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated deleted file mode 100644 index 4466476be8..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq.deactivated +++ /dev/null @@ -1,29 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) -let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) -let $training-data := ( - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -) -let $test-data := ( - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -) -let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) -let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) -let $est := get-estimator("PCA") -let $my-training-data := $vector-assembler($my-training-data) -let $trained_est := $est($my-training-data, - {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) -let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) -let $est2 := get-estimator("LogisticRegression") -let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) -let $my-test-data := $vector-assembler($my-test-data) -let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) -for $i in $trained_est2( - $my-new-test-data, - {"featuresCol": "features2", "predictionCol": "ocol1"} -) -return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated deleted file mode 100644 index 3204b05df9..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq.deactivated +++ /dev/null @@ -1,36 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) - -declare type local:mytype as { - "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" -}; - -let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) -let $training-data := ( - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -) -let $test-data := ( - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -) -let $my-training-data := validate type local:mytype* { $training-data } -let $my-training-data := $vector-assembler($my-training-data) -let $my-test-data := validate type local:mytype* {$test-data } -let $my-test-data := $vector-assembler($my-test-data) - -let $est := get-estimator("PCA") -let $trained_est := $est($my-training-data, - {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) -let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) - -let $est2 := get-estimator("LogisticRegression") -let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) -let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) -for $i in $trained_est2( - $my-new-test-data, - {"featuresCol": "features2", "predictionCol": "ocol1"} -) -return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated deleted file mode 100644 index 520c307381..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq.deactivated +++ /dev/null @@ -1,29 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) - -declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; - - -declare function local:pipeline($trainingset as object*, $testset as object*) as object* -{ - let $logisticregression := get-estimator("LogisticRegression") - let $model := $logisticregression($trainingset, {"featuresCol": "features"}) - return $model($testset, {"featuresCol": "features"}) -}; - -let $vector-assembler := get-transformer("VectorAssembler")(?, {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) - - -let $training-data := $vector-assembler(validate type local:mytype* { - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -}) -let $test-data := $vector-assembler(validate type local:mytype* { - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -}) - -let $pip := local:pipeline($training-data, ?) -return $pip($test-data) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated deleted file mode 100644 index 297bb024ea..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq.deactivated +++ /dev/null @@ -1,23 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) -declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; - -let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) -let $logisticregression := get-estimator("LogisticRegression", { "featuresCol" : "features" }) - -let $pipeline := get-estimator("Pipeline", { "stages" : [ $vector-assembler, $logisticregression ] }) - - -let $training-data := validate type local:mytype* { - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -} -let $test-data := validate type local:mytype* { - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -} - -let $pip := $pipeline($training-data, {}) -return $pip($test-data, {}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated deleted file mode 100644 index f2bbe8ed97..0000000000 --- a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq.deactivated +++ /dev/null @@ -1,24 +0,0 @@ -(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) -declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; - -let $pipeline := get-estimator("Pipeline", { - "stages" : [ - get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}), - get-estimator("LogisticRegression", { "featuresCol" : "features" }) - ] -}) - -let $training-data := validate type local:mytype* { - {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, - {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, - {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, - {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} -} -let $test-data := validate type local:mytype* { - {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, - {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, - {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} -} - -let $pip := $pipeline($training-data, {}) -return $pip($test-data, {}) From 1958bf66530c150072a7f15bd602b1e94b06ba61 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Wed, 8 Sep 2021 17:16:25 +0200 Subject: [PATCH 140/142] Add back. --- .../runtime-spark/RumbleML/MLPipeline1.jq | 29 +++++++++++++++ .../runtime-spark/RumbleML/MLPipeline2.jq | 29 +++++++++++++++ .../runtime-spark/RumbleML/MLPipeline3.jq | 36 +++++++++++++++++++ .../runtime-spark/RumbleML/MLPipeline4.jq | 29 +++++++++++++++ .../runtime-spark/RumbleML/MLPipeline5.jq | 23 ++++++++++++ .../runtime-spark/RumbleML/MLPipeline6.jq | 24 +++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq create mode 100644 src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq new file mode 100644 index 0000000000..62d29dfd5d --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline1.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +let $vector-assembler := get-transformer("VectorAssembler") +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $est := get-estimator("PCA") +let $my-training-data := $vector-assembler($my-training-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-test-data := $vector-assembler($my-test-data, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq new file mode 100644 index 0000000000..4466476be8 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline2.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) +let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := annotate($training-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $my-test-data := annotate($test-data, {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}) +let $est := get-estimator("PCA") +let $my-training-data := $vector-assembler($my-training-data) +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-test-data := $vector-assembler($my-test-data) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq new file mode 100644 index 0000000000..3204b05df9 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline3.jq @@ -0,0 +1,36 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "features2" : [ 0.6811443247067492, -1.6574062675838126 ], "rawPrediction" : [ -37.01954042109449, 37.01954042109449 ], "probability" : [ 8.367926801087183E-17, 1 ], "ocol1" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "features2" : [ -2.93898570550277, 0.48441694826197534 ], "rawPrediction" : [ 37.84452856407813, -37.84452856407813 ], "probability" : [ 1, 3.667161819961595E-17 ], "ocol1" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "features2" : [ 0.28609394877170796, 1.1822492465709793 ], "rawPrediction" : [ -18.536609873254328, 18.536609873254328 ], "probability" : [ 8.905383262038758E-9, 0.9999999910946168 ], "ocol1" : 1 })" :) + +declare type local:mytype as { + "id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal" +}; + +let $vector-assembler := get-transformer("VectorAssembler")(?, { "inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features" }) +let $training-data := ( + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +) +let $test-data := ( + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +) +let $my-training-data := validate type local:mytype* { $training-data } +let $my-training-data := $vector-assembler($my-training-data) +let $my-test-data := validate type local:mytype* {$test-data } +let $my-test-data := $vector-assembler($my-test-data) + +let $est := get-estimator("PCA") +let $trained_est := $est($my-training-data, + {"inputCol": "features", "outputCol": ["ocol1", "ocol2", "ocol2"], "k":2}) +let $my-new-training-data := $trained_est($my-training-data, {"inputCol": "features", "outputCol": "features2"}) + +let $est2 := get-estimator("LogisticRegression") +let $trained_est2 := $est2($my-new-training-data, {"featuresCol": "features2"}) +let $my-new-test-data := $trained_est($my-test-data, {"inputCol": "features", "outputCol": "features2"}) +for $i in $trained_est2( + $my-new-test-data, + {"featuresCol": "features2", "predictionCol": "ocol1"} +) +return $i \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq new file mode 100644 index 0000000000..520c307381 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline4.jq @@ -0,0 +1,29 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) + +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + + +declare function local:pipeline($trainingset as object*, $testset as object*) as object* +{ + let $logisticregression := get-estimator("LogisticRegression") + let $model := $logisticregression($trainingset, {"featuresCol": "features"}) + return $model($testset, {"featuresCol": "features"}) +}; + +let $vector-assembler := get-transformer("VectorAssembler")(?, {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) + + +let $training-data := $vector-assembler(validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +}) +let $test-data := $vector-assembler(validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +}) + +let $pip := local:pipeline($training-data, ?) +return $pip($test-data) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq new file mode 100644 index 0000000000..297bb024ea --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline5.jq @@ -0,0 +1,23 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + +let $vector-assembler := get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}) +let $logisticregression := get-estimator("LogisticRegression", { "featuresCol" : "features" }) + +let $pipeline := get-estimator("Pipeline", { "stages" : [ $vector-assembler, $logisticregression ] }) + + +let $training-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +} +let $test-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +} + +let $pip := $pipeline($training-data, {}) +return $pip($test-data, {}) diff --git a/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq new file mode 100644 index 0000000000..f2bbe8ed97 --- /dev/null +++ b/src/test/resources/test_files/runtime-spark/RumbleML/MLPipeline6.jq @@ -0,0 +1,24 @@ +(:JIQS: ShouldRun; Output="({ "id" : 0, "label" : 1, "col1" : -1, "col2" : 1.5, "col3" : 1.3, "features" : [ -1, 1.5, 1.3 ], "rawPrediction" : [ -43.28021983334889, 43.28021983334889 ], "probability" : [ 1.5982302663265492E-19, 1 ], "prediction" : 1 }, { "id" : 1, "label" : 0, "col1" : 3, "col2" : 2, "col3" : -0.1, "features" : [ 3, 2, -0.1 ], "rawPrediction" : [ 27.129563756689066, -27.129563756689066 ], "probability" : [ 0.9999999999983489, 1.6511258015816568E-12 ], "prediction" : 0 }, { "id" : 2, "label" : 1, "col1" : 0, "col2" : 2.2, "col3" : -1.5, "features" : [ 0, 2.2, -1.5 ], "rawPrediction" : [ -41.54445354973831, 41.54445354973831 ], "probability" : [ 9.067197376998538E-19, 1 ], "prediction" : 1 })" :) +declare type local:mytype as {"id": "integer", "label": "integer", "col1": "decimal", "col2": "decimal", "col3": "decimal"}; + +let $pipeline := get-estimator("Pipeline", { + "stages" : [ + get-transformer("VectorAssembler", {"inputCols" : [ "col1", "col2", "col3" ], "outputCol" : "features"}), + get-estimator("LogisticRegression", { "featuresCol" : "features" }) + ] +}) + +let $training-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": 0.0, "col2": 1.1, "col3": 0.1}, + {"id": 1, "label": 0, "col1": 2.0, "col2": 1.0, "col3": -1.0}, + {"id": 2, "label": 0, "col1": 2.0, "col2": 1.3, "col3": 1.0}, + {"id": 3, "label": 1, "col1": 0.0, "col2": 1.2, "col3": -0.5} +} +let $test-data := validate type local:mytype* { + {"id": 0, "label": 1, "col1": -1.0, "col2": 1.5, "col3": 1.3}, + {"id": 1, "label": 0, "col1": 3.0, "col2": 2.0, "col3": -0.1}, + {"id": 2, "label": 1, "col1": 0.0, "col2": 2.2, "col3": -1.5} +} + +let $pip := $pipeline($training-data, {}) +return $pip($test-data, {}) From cb9bdf3ebfb89cff2051953ef524673c866f1194 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Thu, 9 Sep 2021 15:19:36 +0200 Subject: [PATCH 141/142] Update ComparisonIterator.java --- .../runtime/misc/ComparisonIterator.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java index 62a9a75437..a9e7ac3ea6 100644 --- a/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java +++ b/src/main/java/org/rumbledb/runtime/misc/ComparisonIterator.java @@ -208,16 +208,6 @@ private Item valueComparison(Item left, Item right) { .getInstance() .createBooleanItem(false); } - if (left.isFloat() && Float.isNaN(left.getFloatValue())) { - return ItemFactory - .getInstance() - .createBooleanItem(false); - } - if (right.isFloat() && Float.isNaN(right.getFloatValue())) { - return ItemFactory - .getInstance() - .createBooleanItem(false); - } return comparisonResultToBooleanItem( (int) comparison, this.comparisonOperator, @@ -240,22 +230,6 @@ public static long compareItems( if (!left.isNull() && right.isNull()) { return 1; } - if ( - right.isNumeric() - && - ((left.isDouble() && Double.isNaN(left.getDoubleValue())) - || (left.isFloat() && Float.isNaN(left.getFloatValue()))) - ) { - return 1; - } - if ( - left.isNumeric() - && - ((right.isDouble() && Double.isNaN(right.getDoubleValue())) - || (right.isFloat() && Float.isNaN(right.getFloatValue()))) - ) { - return -1; - } if ( left.isInt() && right.isInt() From efdccc8d2e55e7d46d85e20a3faeaa2ecaecb713 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Thu, 9 Sep 2021 15:32:45 +0200 Subject: [PATCH 142/142] Fix test. --- .../test_files/runtime-spark/DataFrames/TreatAs1.jq | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/resources/test_files/runtime-spark/DataFrames/TreatAs1.jq b/src/test/resources/test_files/runtime-spark/DataFrames/TreatAs1.jq index aa72b21601..125bec37bc 100644 --- a/src/test/resources/test_files/runtime-spark/DataFrames/TreatAs1.jq +++ b/src/test/resources/test_files/runtime-spark/DataFrames/TreatAs1.jq @@ -16,7 +16,7 @@ try { let $a := annotate({"foo" : 1e0},{"foo":"integer"}) let $b := $a.foo treat as double return $b -} catch XQDY0027 +} catch XPDY0050 { "good" }, @@ -24,7 +24,7 @@ try { let $a := annotate({"foo" : 1e0},{"foo":"integer"}) let $b := $a.foo treat as double? return $b -} catch XQDY0027 +} catch XPDY0050 { "good" }, @@ -32,7 +32,7 @@ try { let $a := annotate({"foo" : 1e0},{"foo":"integer"}) let $b := $a.foo treat as double* return $b -} catch XQDY0027 +} catch XPDY0050 { "good" }, @@ -40,7 +40,7 @@ try { let $a := annotate({"foo" : 1e0},{"foo":"integer"}) let $b := $a.foo treat as double+ return $b -} catch XQDY0027 +} catch XPDY0050 { "good" },